文章目录
-
- PlayerController.cs
- EnemyController.cs
- Enemy01.cs
- BulletController.cs
- SceneController.cs
- Videoontroller.cs
- BulletBag.cs
- Collectible.cs
- Inventory.cs
- InventoryManager.cs
- Item.cs
- ItemOnWorld.cs
- Slot.cs
- AudioManager.cs
- AuManager.cs
- ChangeScene.cs
- ChangeScene1.cs
- GameManger.cs
- NPCmanager.cs
- Passform.cs
- SceneLoadPanel.cs
- UIEntry.cs
- UImanager.cs
- ViewBase.cs
- DamageArea.cs
- ImageShift.cs
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// 控制角色移动、生命、动画等
/// </summary>
public class PlayerController : MonoBehaviour
{
public float speed = 5f;//移动速度
private int maxHealth = 5;//最大生命值
private int currentHealth;//当前的生命值
//========玩家死亡结束游戏==============================
//游戏结束提示
//public GameObject GameOver;
//指定为主角并销毁
public GameObject GameOverPlayer;
public int MyMaxHealth {
get {
return maxHealth; } }//在这里定义一个公共属性以便Collectible.cs可以访问生命属性
public int MyCurrentHealth {
get {
return currentHealth; } }//在这里定义一个公共属性以便Collectible.cs可以访问生命属性
//给个无敌时间
private float invincibleTime = 2f;//无敌时间2秒
private float invincibleTimer;//无敌计时器
private bool isInvincible;//给个状态-是否处于无敌状态
public GameObject bulletPrefab;//子弹
//==============玩家的音效===============================
public AudioClip hitClip;//受伤音效
public AudioClip launchClip;//发射齿轮音效
//==============玩家的方向的朝向=========================
private Vector2 lookDirection = new Vector2(1, 0);//(动画)默认朝向右方
//==============玩家的子弹数量============================
[SerializeField ]//序列化一下 也能在属性面板直接调整
private int curBulletCount;//当前子弹数量
private int maxBulletCount = 10;//最大子弹数量
public int MyCurBulletCount {
get {
return curBulletCount; } }
public int MyMaxBulletCount {
get {
return maxBulletCount; } }//这样就能在齿轮子弹包BulletBag.cs那边进行访问了
public static object pc {
get; internal set; }
Passform currentPassform; //当前玩家处在的位置
Rigidbody2D rbody;//先获取它的刚体组件
Animator anim;//(动画)获取动画组件
/// <summary>
/// 背包系统
/// </summary>
public GameObject myBag;
bool isOpen;//反复按同一个按键 实现打开和关闭效果
/// <summary>
/// 智能提示
/// </summary>
//无法实现在其他脚本中销毁提示,故在此脚本中限时销毁
public float showTime = 3;
private float showTimer;
//智能提示框计时器
public float tiptime = 6;
private float tiptimer;
//智能提示文本
public Text tips;
public GameObject tipsframe;
void Start()
{
curBulletCount = 2;//一开始子弹数量为0
currentHealth = 5;
invincibleTimer = 0;//一开始是可以受到伤害的
rbody = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();//(动画)获取动画组件
UImanager.instance.UpdateHealthBar(currentHealth, maxHealth);//更新以下血条状态
UImanager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
}
void Update()
{
//智能提示文本
showTimer -= Time.deltaTime;//任务完成显示 计时器
tiptimer -= Time.deltaTime;//提示框显示 计时器
if (tiptimer<0)//超过时间就取消显示提示文本
{
tipsframe.SetActive(false);
}
if (showTimer + 5 < 0)//取消显示提示文本
{
tipsframe.SetActive(false);
}
if (currentHealth <= 2)//如果生命<=2了,则进行提示
{
tip();
}
if (curBulletCount == 0 && currentHealth !=0)//如果没有子弹了,则进行提示
{
tip();
}
OPenMyBag();//在Update里进行调用
/**
* 测试左朝向有误 故暂改代码
* float horizontal = Input.GetAxis("Horizontal");//控制水平移动方向A: -1 D: 1 0
float vertical = Input.GetAxis("Vertical"); //控制垂直移动方向 W: 1 S:-1 0
Vector2 moveVector = new Vector2(horizontal, vertical);//(动画)
if (moveVector.x != 0 || moveVector.y != 0) {
lookDirection = moveVector;
}//按键不按的时候是为0的
anim.SetFloat("Look X", lookDirection.x);
anim.SetFloat("Look Y", lookDirection.y);
anim.SetFloat("Speed", moveVector.magnitude);
**/
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 moveVector = new Vector2(horizontal, vertical);//将输入值存储在名为 moveVector 的 Vector2 变量中,而不是独立设置用于移动的 x 和 y
/*检查 move.x 或 move.y 是否不等于 0
* 使用 Mathf.Approximately 而不是 ==,这是因为计算机存储浮点数的方式意味着精度会有很小的损失
* 所以,不应测试完美的相等性,因为最终结果应该是 0.0f 的运算可能会得出类似 0.0000000001f 的结果。Approximately 会考虑这种不精确性,如果除去这种不精确性可以认为数值相等,将返回 true
* 本可以设置 lookDirection = moveVector,但这是另一种分配向量的 x 和 y 的方式
*/
if (!Mathf.Approximately(moveVector.x, 0.0f) || !Mathf.Approximately(moveVector.y, 0.0f))
{
lookDirection.Set(moveVector.x, moveVector.y);
lookDirection.Normalize();//在 lookDirection 上调用 Normalize,从而使长度等于 1。Vector2 类型存储位置,但也可以存储方向
}
anim.SetFloat("Look X", lookDirection.x);
anim.SetFloat("Look Y", lookDirection.y);
anim.SetFloat("Speed", moveVector.magnitude);
//=========移动=================================================================
Vector2 position = rbody .position;
//position.x = position.x + 1f * moveX * speed* Time.fixedDeltaTime; //消除抖动把Time.deltaTime改成Time.fixedDeltaTime
//position.y = position.y + 1f * moveY * speed* Time.fixedDeltaTime;
//因为上面定义了moveVector 所以把上面的注释掉 换另一种写法
position += moveVector * speed * Time.fixedDeltaTime;
rbody .MovePosition ( position);//把transform.position = position;修改成刚体移动
//=============无敌计时==========================================================
if (isInvincible) {
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
{
isInvincible = false; //倒计时结束以后(2秒),取消无敌状态
}
}
//=============按下J键 并且子弹数量>0 进行攻击===================================================
if (Input.GetKeyDown(KeyCode.J)&&curBulletCount >0)
{
Launch();
}
//=============按下 E 键 进行NPC交互
if (Input.GetKeyDown(KeyCode.E)) {
RaycastHit2D hit = Physics2D.Raycast(rbody.position, lookDirection, 2f,LayerMask .GetMask ("NPC"));//根据层级来进行索引 把NPC设为NPC层级 这样玩家发射的射线就只会和NPC触碰
if (hit.collider != null) {
NPCmanager npc = hit.collider.GetComponent<NPCmanager>();
if (npc != null) {
npc.ShowDialog();//显示对话框
}
}
}
//==================玩家死亡结束游戏===================================
//如果生命值为0,显示游戏结束字样,并销毁主角
if (currentHealth == 0)
{
//GameOver.SetActive(true);
//tip();
//GameObject.Find("Ruby").GetComponent<PlayerController >().enabled = false;
//gameObject.SetActive(false);
Destroy(GameOverPlayer,2f);
SceneManager.LoadScene(1);
}
//穿越
if (currentPassform != null)
{
currentPassform.Pass(gameObject);
}
}
/// <summary>
/// 改变玩家的生命值
/// </summary>
/// <param name="amount"></param>
public void ChangeHealth(int amount) {
//如果玩家受到伤害
if (amount < 0) {
if (isInvincible == true) {
return; //如果处于无敌状态就不让它进行下一步的伤害检测了
}
isInvincible = true;//如果不是无敌状态 改为true 让它受到这次伤害后就是无敌状态了 只让它受到一次伤害
anim.SetTrigger("Hit");//添加受伤动画
AudioManager.instance.AudioPlay(hitClip);//播放受伤音效
invincibleTimer = invincibleTime;//把时间进行重置 这样update里就能进行检测 它就开始减 如果小于0后它就解除无敌状态
}
//把玩家的生命值约束在0和最大值之间
Debug.Log(currentHealth + "/" + maxHealth);
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UImanager.instance.UpdateHealthBar(currentHealth, maxHealth);//更新血条
Debug.Log(currentHealth + "/" + maxHealth);
}
public void ChangeBulletCount(int amount) {
curBulletCount = Mathf.Clamp(curBulletCount + amount, 0, maxBulletCount);//限制子弹数量在0-最大值之间
UImanager.instance.UpdateBulletCount(curBulletCount, maxBulletCount);
}
public void Launch()
{
if (!UImanager.instance.hasTask) //当没有任务的时候
{
return;
}
ChangeBulletCount(-1);//每次攻击减1个齿轮
anim.SetTrigger("Launch");//播放攻击动画
AudioManager.instance.AudioPlay(launchClip);//播放攻击音效
GameObject bullet = Instantiate(bulletPrefab, rbody.position + Vector2.up * 0.5f