using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class RedGhost : MonoBehaviour { // ========== 状态枚举 ========== public enum GhostState { Idle, //开局的待机 Start, //离开重生点出发 Chase, // 追击模式 Frightened, // 恐惧模式,逃跑 Die // 死亡重生 } public GhostState curstate;//当前枚举 [Header("基础配置")] public Rigidbody2D rb; public Animator anim; public GameObject pacMan;//吃豆人主角 public LayerMask obstadeLayer;//墙的层级 [Header("追击逃跑逻辑相关")] private Vector2 currentDirection; public float speed;//基础速度 public float frightenedSpeed;//逃跑速度 private void Awake() { rb = GetComponent(); // anim = GetComponent(); pacMan = GameObject.Find("PacManPlayer");//找到主角 } private void Update() { switch (curstate) { case GhostState.Idle: Idle(); break; case GhostState.Start: GhostStart(); break; case GhostState.Chase: Chase(); break; case GhostState.Frightened: Frightened(); break; case GhostState.Die: Die(); break; } } private void Idle() { curstate = GhostState.Chase; } private void GhostStart() { throw new NotImplementedException(); } private void Chase() { UpdateMovement(pacMan.transform.position, true); //anim.SetBool("Frightened", false); } private void Frightened() { throw new NotImplementedException(); } private void Die() { throw new NotImplementedException(); } // 核心移动逻辑(追击/逃跑共用) private void UpdateMovement(Vector2 targetPos, bool isChasing) { Vector2[] directions = { Vector2.up, Vector2.down, Vector2.left, Vector2.right }; Vector2 bestDir = Vector2.zero; float bestValue = isChasing ? Mathf.Infinity : -Mathf.Infinity;//正无穷大,负无穷大 foreach (Vector2 dir in directions) { if (dir == -currentDirection) continue; // 循环到的方向等于当前的负方向,继续执行,禁止直接回头 RaycastHit2D hit = Physics2D.Raycast(transform.position, dir, 1f, obstadeLayer);//起始点,方向,长度,过滤器 if (hit.collider != null) continue; // 计算方向价值 float distance = Vector2.Distance(rb.position + dir, targetPos);//当前坐标加方向向量和目标主角坐标的差值 float currentValue = isChasing ? distance : -distance;//是追击还是逃跑 if ((isChasing && currentValue < bestValue) || (!isChasing && currentValue > bestValue)) { bestValue = currentValue; bestDir = dir; } } if (bestDir != Vector2.zero) { currentDirection = bestDir; rb.velocity = currentDirection * (curstate == GhostState.Frightened ? frightenedSpeed : speed); //anim.SetFloat("DirX", currentDirection.x); //anim.SetFloat("DirY", currentDirection.y); } } }