PacMan/Assets/Scripts/RedGhost.cs

124 lines
3.3 KiB
C#

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<Rigidbody2D>();
// anim = GetComponent<Animator>();
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);
}
}
}