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

2024-09-14
86看过
编写AI巡逻的具体逻辑,AI需要先获取当前场景中是否存在巡逻点,如果有巡逻路径,就前往,检测是否到达当前巡逻点,就切换到下一个巡逻点


PatrolPath:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Control
  5. {
  6.     public class PatrolPath : MonoBehaviour
  7.     {
  8.         // 在绘制 Gizmos,用于可视化巡逻路径
  9.         private void OnDrawGizmos()
  10.         {
  11.             for (int i = 0;i< transform.childCount; i++)  // 遍历所有子对象(每个子对象是一个路径点)
  12.             {
  13.                 int j = GetNextIndex(i);// 获取当前点的下一个点的索引
  14.                 Gizmos.color = Color.red; // 设置 Gizmos 的颜色为红色
  15.                 Gizmos.DrawSphere(GetWaypoint(i), 1f);   // 绘制当前路径点的位置
  16.                 Gizmos.DrawLine(GetWaypoint(i),GetWaypoint(j)); // 绘制从当前路径点到下一个路径点的连线
  17.             }
  18.         }
  19.         public int GetNextIndex(int i)// 获取当前索引点的下一个索引
  20.         {
  21.             if(i +1 == transform.childCount) // 如果当前点是最后一个点,则返回第一个点的索引
  22.             {
  23.                 return 0;
  24.             }
  25.             return i + 1; // 否则返回下一个点的索引
  26.         }
  27.         public Vector3 GetWaypoint(int i)  // 获取指定索引的路径点位置
  28.         {
  29.             return transform.GetChild(i).position;
  30.         }
  31.     }
  32. }
复制代码
AIController:

  1. using RPG.Combat;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using RPG.Movement;
  6. using RPG.Core;
  7. using System;
  8. namespace RPG.Control
  9. {
  10.     //AI的控制
  11.     public class AIController : MonoBehaviour
  12.     {
  13.         [SerializeField] float chaseDistance = 5f;// 设定追逐范围的距离
  14.         [SerializeField] float suspicionTime = 4f;//丢失目标后原地等待时间
  15.         [SerializeField] PatrolPath patrolPath;
  16.         [SerializeField] float waypointTolerance = 1f;
  17.         float timeSinceLastSawPlayer = Mathf.Infinity;//最后一次看见玩家的时间
  18.         int currentWaypointIndex = 0;
  19.         Vector3 guardPosition;//默认位置
  20.         //组件
  21.         Fighter fighter;
  22.         Health health;
  23.         Mover mover;
  24.         GameObject player;
  25.         
  26.         
  27.         private void Start()
  28.         {
  29.             fighter = GetComponent<Fighter>();
  30.             health = GetComponent<Health>();
  31.             player = GameObject.FindWithTag("Player");// 找到标签为“Player”的游戏对象
  32.             mover = GetComponent<Mover>();
  33.             guardPosition = transform.position;
  34.         }
  35.         private void Update()
  36.         {
  37.             if (health.IsDead()) return;//如果角色已经死亡,则跳出
  38.             // 如果和玩家的距离小于设定的追逐范围 并且可以攻击玩家
  39.             if (InAttackRangeOfPlayer()&& fighter.CanAttack(player))
  40.             {
  41.                 timeSinceLastSawPlayer = 0;//设置为0
  42.                 AttackBehaviour();
  43.             }
  44.             else if(timeSinceLastSawPlayer < suspicionTime)//失去对玩家的视线后,怀疑时间
  45.             {
  46.                 SuspicionBehaviour();
  47.             }
  48.             else//不在范围内
  49.             {
  50.                 PatrolBehaviour();
  51.             }
  52.             timeSinceLastSawPlayer += Time.deltaTime;
  53.         }
  54.         private void PatrolBehaviour()//巡逻行为
  55.         {
  56.             Vector3 nectPoition = guardPosition; // 默认巡逻点设为守卫的起始位置
  57.             if (patrolPath != null)// 如果存在巡逻路径
  58.             {
  59.                 if(AtWaypoint())// 如果到达当前巡逻点
  60.                 {
  61.                     CycleWaypoint();// 切换到下一个巡逻点
  62.                 }
  63.             }
  64.             nectPoition = GetCurrentWaypoint();// 获取当前巡逻点的位置
  65.             mover.StartMoveAction(nectPoition);// 开始移动到当前巡逻点
  66.         }
  67.       
  68.         private bool AtWaypoint()// 检查是否到达巡逻点
  69.         {
  70.             // 计算当前位置与当前巡逻点之间的距离
  71.             float distanceToWaypoint = Vector3.Distance(transform.position,GetCurrentWaypoint());
  72.             return distanceToWaypoint <waypointTolerance; // 判断是否小于允许的误差范围
  73.         }
  74.         private void CycleWaypoint()// 切换到下一个巡逻点
  75.         {
  76.             // 更新当前巡逻点的索引
  77.             currentWaypointIndex = patrolPath.GetNextIndex(currentWaypointIndex);
  78.         }
  79.         private Vector3 GetCurrentWaypoint()// 获取当前巡逻点的位置
  80.         {
  81.             // 从巡逻路径中获取当前巡逻点的位置
  82.             return patrolPath.GetWaypoint(currentWaypointIndex);
  83.         }
  84.         private void SuspicionBehaviour()//丢失目标行为
  85.         {
  86.             GetComponent<ActionScheduler>().CancelCurrentAction();
  87.         }
  88.         private void AttackBehaviour()//攻击行为
  89.         {
  90.             fighter.Attack(player);//对玩家进行攻击
  91.         }
  92.         private bool InAttackRangeOfPlayer() // 检测是否在攻击范围内
  93.         {
  94.             float distanceToPlayer = Vector3.Distance(player.transform.position,transform.position); // 计算并返回玩家和当前对象之间的距离
  95.             return distanceToPlayer < chaseDistance;//返回两者之间距离是否小于追逐距离
  96.         }
  97.         private void OnDrawGizmosSelected()//绘制线框球体
  98.         {
  99.             Gizmos.color = Color.yellow;
  100.             Gizmos.DrawWireSphere(transform.position, chaseDistance);
  101.         }
  102.     }
  103. }
复制代码


回复

举报

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

本版积分规则

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