Udemy-Unity制作类暗黑破坏神游戏记录-P46

2024-09-12
89看过
修复角色死亡后,依然可以移动的问题,修复角色死亡,敌人将不在追逐,一旦角色死亡后,将关闭角色的碰撞体和寻路

逻辑也比较简单,在角色控制器和AI控制器的更新中加上一个死亡判断就行, if (health.IsDead()) return;
具体代码如下
Health:
  1. using RPG.Core;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.AI;
  6. // 处理生命值系统的脚本
  7. namespace RPG.Combat
  8. {
  9.     public class Health : MonoBehaviour
  10.     {
  11.         [SerializeField] float healthPoints = 100f;// 当前生命值,初始值为 100
  12.         bool isDead = false;//是否死亡
  13.         //死亡方法,这个方法用于给角色判断,是否继续进行攻击
  14.         public bool IsDead()
  15.         {
  16.             return isDead;
  17.         }
  18.         // 处理受伤逻辑的方法
  19.         public void TakeDamage(float damage)
  20.         {
  21.             healthPoints = Mathf.Max(healthPoints - damage, 0);// 减少生命值,确保生命值不会低于 0
  22.             print(healthPoints);
  23.             if (healthPoints == 0)//如果生命值等于0,
  24.             {
  25.                 Die();
  26.             }
  27.         }
  28.         /// <summary>
  29.         /// 死亡逻辑
  30.         /// </summary>
  31.         private void Die()
  32.         {
  33.             if (isDead) return;//如果玩家已死亡,直接跳出该方法
  34.             isDead = true;
  35.             GetComponent<Animator>().SetTrigger("death");//播放死亡动画
  36.             GetComponent<ActionScheduler>().CancelCurrentAction();//设置当前行为为空
  37.         }
  38.     }
  39. }
复制代码
PlayerController:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using RPG.Movement;
  5. using RPG.Combat;
  6. //角色的控制
  7. namespace RPG.Control
  8. {
  9.    
  10.     public class PlayerController : MonoBehaviour
  11.     {
  12.         private Mover mover;
  13.         Health health;
  14.         private void Start()
  15.         {
  16.             mover = GetComponent<Mover>();
  17.             health = GetComponent<Health>();
  18.         }
  19.         private void Update()
  20.         {
  21.             if (health.IsDead()) return;//如果角色已经死亡,则退出
  22.             if (InteractWithCombat()) return;// 如果处理了战斗交互,则退出方法
  23.             if (InteractWithMovement()) return; // 如果处理了移动交互,则退出方法
  24.         }
  25.         
  26.         
  27.         private bool InteractWithCombat()// 战斗交互
  28.         {
  29.             RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
  30.             foreach (RaycastHit hit in hits)
  31.             {
  32.                 CombatTarget target = hit.transform.GetComponent<CombatTarget>();//被射线击中的物体获取战斗目标组件
  33.                 if(target == null) continue;//如果目标为空,继续执行
  34.                
  35.                 if (!GetComponent<Fighter>().CanAttack(target.gameObject))//如果可以攻击该目标,继续执行
  36.                 {
  37.                     continue;
  38.                 }
  39.                 if(Input.GetMouseButtonDown(0))//按下左键
  40.                 {
  41.                     GetComponent<Fighter>().Attack(target.gameObject);//攻击目标
  42.                 }
  43.                 return true;//射线找到目标
  44.             }
  45.             return false;//射线没有找到目标  ActionScheduler
  46.         }
  47.         // 移动和交互
  48.         private bool InteractWithMovement()
  49.         {
  50.             RaycastHit hit;//存储射线碰撞的信息
  51.             bool hasHit = Physics.Raycast(GetMouseRay(), out hit); //通过射线检测是否有接触到碰撞物体
  52.             if (hasHit)//如果有检测到
  53.             {
  54.                 if (Input.GetMouseButton(0))//如果按下鼠标左键
  55.                 {
  56.                     mover.StartMoveAction(hit.point);
  57.                     
  58.                 }
  59.                 return true;
  60.             }
  61.             return false;
  62.         }
  63.         
  64.         //创建射线
  65.         private static Ray GetMouseRay()
  66.         {
  67.             return Camera.main.ScreenPointToRay(Input.mousePosition);
  68.         }
  69.     }
  70. }
复制代码
AIController
  1. using RPG.Combat;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace RPG.Control
  6. {
  7.     //AI的控制
  8.     public class AIController : MonoBehaviour
  9.     {
  10.         [SerializeField] float chaseDistance = 5f;// 设定追逐范围的距离
  11.         Fighter fighter;
  12.         Health health;
  13.         GameObject player;
  14.         private void Start()
  15.         {
  16.             fighter = GetComponent<Fighter>();
  17.             health = GetComponent<Health>();
  18.             player = GameObject.FindWithTag("Player");// 找到标签为“Player”的游戏对象
  19.         }
  20.         private void Update()
  21.         {
  22.             if (health.IsDead()) return;//如果角色已经死亡,则跳出
  23.             // 如果和玩家的距离小于设定的追逐范围 并且可以攻击玩家
  24.             if (InAttackRangeOfPlayer()&& fighter.CanAttack(player))   
  25.             {
  26.                 fighter.Attack(player);//对玩家进行攻击
  27.                 print("可以攻击");
  28.             }
  29.             else
  30.             {
  31.                 fighter.Cancel();//取消攻击
  32.             }
  33.            
  34.         }
  35.         private bool InAttackRangeOfPlayer() // 检测是否在攻击范围内
  36.         {
  37.             float distanceToPlayer = Vector3.Distance(player.transform.position,transform.position); // 计算并返回玩家和当前对象之间的距离
  38.             return distanceToPlayer < chaseDistance;//返回两者之间距离是否小于追逐距离
  39.         }
  40.     }
  41. }
复制代码
Mover
  1. using RPG.Combat;
  2. using RPG.Core;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using UnityEngine.AI;
  7. using UnityEngine.UI;
  8. //角色的移动
  9. namespace RPG.Movement
  10. {
  11.     public class Mover : MonoBehaviour,IAction
  12.     {
  13.         private NavMeshAgent navMeshAgent;
  14.         
  15.         Animator animator;
  16.         Health health;
  17.         CapsuleCollider capsuleCollider;
  18.         private void Start()
  19.         {
  20.             animator = GetComponent<Animator>();
  21.             navMeshAgent = GetComponent<NavMeshAgent>();
  22.             health = GetComponent<Health>();
  23.             capsuleCollider = GetComponent<CapsuleCollider>();
  24.         }
  25.         private void Update()
  26.         {
  27.             if (health.IsDead())
  28.             {
  29.                 capsuleCollider.enabled = false;//关闭碰撞
  30.                 navMeshAgent.enabled = false;//关闭寻路
  31.             }
  32.             
  33.             UpdateAnimator();
  34.         }
  35.         /// <summary>
  36.         /// 开始移动行为
  37.         /// </summary>
  38.         /// <param name="destination">移动的位置</param>
  39.         public void StartMoveAction(Vector3 destination)
  40.         {
  41.             GetComponent<ActionScheduler>().StartAction(this);
  42.             
  43.             MoveTo(destination);
  44.         }
  45.         /// <summary>
  46.         /// 寻路移动到射线检测点
  47.         /// </summary>
  48.         /// <param name="hit"></param>
  49.         public void MoveTo(Vector3 destination)
  50.         {
  51.             navMeshAgent.destination = destination;//获取寻路目的地 = 射线碰撞的点
  52.             navMeshAgent.isStopped = false;
  53.         }
  54.         /// <summary>
  55.         /// 停止寻路
  56.         /// </summary>
  57.         public void Cancel()
  58.         {
  59.             navMeshAgent.isStopped = true;
  60.         }
  61.         
  62.         /// <summary>
  63.         /// 动画更新
  64.         /// </summary>
  65.         private void UpdateAnimator()
  66.         {
  67.             Vector3 velocity = navMeshAgent.velocity;//创建寻路速度
  68.             Vector3 localVelocity = transform.InverseTransformDirection(velocity);// 将世界向前变换到本地空间:
  69.             float speed = localVelocity.z;
  70.             
  71.             animator.SetFloat("forwardSpeed", speed);
  72.         }
  73.     }
  74. }
复制代码


回复

举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表