第六章 游戏AI决策系统的核心——有限状态机(FSM)设计与实现

6.1 有限状态机的基本概念与设计模式

有限状态机(Finite State Machine,简称FSM)是游戏人工智能中最经典、最常用的决策模型之一。它是一种抽象的数学模型,用于描述对象在其生命周期内可能处于的有限状态集合,以及在这些状态之间转换的条件和规则。在游戏开发中,FSM特别适合模拟具有明确行为模式的角色,如敌人、NPC或游戏中的各种实体。

6.1.1 经典游戏《Pac-Man》中红幽灵的FSM设计解析

在经典游戏《吃豆人》中,红幽灵(Blinky)的AI行为是通过一个精心设计的有限状态机实现的。这个FSM包含了几个关键状态,每个状态都有特定的行为模式和转换条件。

红幽灵的主要状态包括:

  1. 追逐状态:直接朝向吃豆人当前位置移动
  2. 散射状态:移动到地图的特定角落
  3. 恐惧状态:当吃豆人吃掉能量豆时,幽灵变得脆弱并试图逃离
  4. 被吃状态:当幽灵被吃豆人吃掉时,返回重生点

下面是红幽灵状态机的完整实现,展示了商业游戏中的FSM设计思路:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PacManGhostFSM : MonoBehaviour
{
    [System.Serializable]
    public class GhostBehaviorSettings
    {
        public float normalSpeed = 3.5f;
        public float frightenedSpeed = 2.5f;
        public float eatenSpeed = 6.0f;
        public float scatterDuration = 7.0f;
        public float chaseDuration = 20.0f;
        public float frightenedDuration = 10.0f;
        public Vector2 scatterTargetCorner = new Vector2(25, 34);
        public Color normalColor = Color.red;
        public Color frightenedColor = Color.blue;
        public Color eatenColor = Color.white;
    }

    [System.Serializable]
    public class GhostStateTimers
    {
        public float scatterTimer;
        public float chaseTimer;
        public float frightenedTimer;
        public float stateChangeCooldown;
    }

    public enum GhostState
    {
        Scatter,        // 散射状态
        Chase,          // 追逐状态
        Frightened,     // 恐惧状态
        Eaten,          // 被吃状态
        LeavingHouse,   // 离开鬼屋状态
        EnteringHouse   // 进入鬼屋状态
    }

    public enum GhostMode
    {
        Normal,
        Frightened,
        Eaten
    }

    [Header("行为设置")]
    [SerializeField]
    private GhostBehaviorSettings behaviorSettings = new GhostBehaviorSettings();

    [Header("状态管理")]
    [SerializeField]
    private GhostState currentState = GhostState.Scatter;

    [SerializeField]
    private GhostMode currentMode = GhostMode.Normal;

    [SerializeField]
    private GhostStateTimers stateTimers = new GhostStateTimers();

    [Header("目标追踪")]
    [SerializeField]
    private Transform pacManTransform;

    [SerializeField]
    private Vector2 currentTargetPosition;

    [SerializeField]
    private Vector2 scatterTargetPosition;

    [Header("组件引用")]
    [SerializeField]
    private SpriteRenderer ghostSpriteRenderer;

    [SerializeField]
    private Animator ghostAnimator;

    [SerializeField]
    private GhostMovementController movementController;

    [Header("路径计算")]
    [SerializeField]
    private PacManGridNavigation gridNavigation;

    [SerializeField]
    private List<Vector2> currentPath = new List<Vector2>();

    [SerializeField]
    private int currentPathIndex;

    private Vector2 ghostHousePosition = new Vector2(13.5f, 17);
    private bool isInGhostHouse = true;
    private bool isVulnerable = false;
    private int dotsEatenForRelease = 0;
    private int dotsEatenCounter = 0;

    private void Awake()
    {
        InitializeComponents();
        InitializeStateMachine();
    }

    private void InitializeComponents()
    {
        if (ghostSpriteRenderer == null)
        {
            ghostSpriteRenderer = GetComponent<SpriteRenderer>();
        }

        if (ghostAnimator == null)
        {
            ghostAnimator = GetComponent<Animator>();
        }

        if (movementController == null)
        {
            movementController = GetComponent<GhostMovementController>();
        }

        if (gridNavigation == null)
        {
            gridNavigation = FindObjectOfType<PacManGridNavigation>();
        }

        if (pacManTransform == null)
        {
            GameObject pacMan = GameObject.FindGameObjectWithTag("Player");
            if (pacMan != null)
            {
                pacManTransform = pacMan.transform;
            }
        }
    }

    private void InitializeStateMachine()
    {
        // 初始化状态
        currentState = GhostState.LeavingHouse;
        currentMode = GhostMode.Normal;
        isInGhostHouse = true;
        
        // 设置初始目标位置
        scatterTargetPosition = behaviorSettings.scatterTargetCorner;
        
        // 初始化计时器
        stateTimers.scatterTimer = behaviorSettings.scatterDuration;
        stateTimers.chaseTimer = behaviorSettings.chaseDuration;
        stateTimers.frightenedTimer = behaviorSettings.frightenedDuration;
        stateTimers.stateChangeCooldown = 0f;
        
        // 设置初始外观
        UpdateGhostAppearance();
        
        Debug.Log("红幽灵FSM初始化完成,初始状态: " + currentState);
    }

    private void Update()
    {
        UpdateStateTimers();
        UpdateStateMachine();
        UpdateMovement();
        UpdateAnimations();
    }

    private void UpdateStateTimers()
    {
        // 更新所有状态计时器
        switch (currentState)
        {
            case GhostState.Scatter:
                stateTimers.scatterTimer -= Time.deltaTime;
                if (stateTimers.scatterTimer <= 0)
                {
                    ChangeState(GhostState.Chase);
                }
                break;
                
            case GhostState.Chase:
                stateTimers.chaseTimer -= Time.deltaTime;
                if (stateTimers.chaseTimer <= 0)
                {
                    ChangeState(GhostState.Scatter);
                }
                break;
                
            case GhostState.Frightened:
                stateTimers.frightenedTimer -= Time.deltaTime;
                if (stateTimers.frightenedTimer <= 0)
                {
                    ChangeToNormalMode();
                }
                
                // 闪烁警告(最后几秒)
                if (stateTimers.frightenedTimer < 3.0f)
                {
                    float blinkRate = Mathf.PingPong(Time.time * 10, 1);
                    ghostSpriteRenderer.color = blinkRate > 0.5f ? 
                        behaviorSettings.frightenedColor : behaviorSettings.normalColor;
                }
                break;
        }
        
        // 更新状态转换冷却
        if (stateTimers.stateChangeCooldown > 0)
        {
            stateTimers.stateChangeCooldown -= Time.deltaTime;
        }
    }

    private void UpdateStateMachine()
    {
        // 处理状态特定的逻辑
        switch (currentState)
        {
            case GhostState.LeavingHouse:
                HandleLeavingHouseState();
                break;
                
            case GhostState.Scatter:
                HandleScatterState();
                break;
                
            case GhostState.Chase:
                HandleChaseState();
                break;
                
            case GhostState.Frightened:
                HandleFrightenedState();
                break;
                
            case GhostState.Eaten:
                HandleEatenState();
                break;
                
            case GhostState.EnteringHouse:
                HandleEnteringHouseState();
                break;
        }
    }

    private void HandleLeavingHouseState()
    {
        // 离开鬼屋的逻辑
        Vector2 currentPos = transform.position;
        Vector2 houseExit = new Vector2(13.5f, 20);
        
        if (Vector2.Distance(currentPos, houseExit) < 0.1f)
        {
            // 到达出口,切换到散射状态
            ChangeState(GhostState.Scatter);
            isInGhostHouse = false;
        }
        else
        {
            // 向出口移动
            currentTargetPosition = houseExit;
            CalculatePathToTarget(houseExit);
        }
    }

    private void HandleScatterState()
    {
        // 散射状态:移动到地图角落
        currentTargetPosition = scatterTargetPosition;
        
        // 定期重新计算路径
        if (ShouldRecalculatePath())
        {
            CalculatePathToTarget(scatterTargetPosition);
        }
        
        // 检查是否接近目标(允许一定误差)
        if (Vector2.Distance(transform.position, scatterTargetPosition) < 1.0f)
        {
            // 到达角落,可以稍微徘徊
            WanderAroundCorner();
        }
    }

    private void HandleChaseState()
    {
        if (pacManTransform == null)
        {
            return;
        }
        
        // 追逐状态:根据红幽灵的策略直接追向吃豆人
        Vector2 pacManPosition = pacManTransform.position;
        currentTargetPosition = pacManPosition;
        
        // 定期重新计算路径
        if (ShouldRecalculatePath())
        {
            CalculatePathToTarget(pacManPosition);
        }
        
        // 红幽灵的特殊行为:当距离吃豆人很近时,会尝试预测移动方向
        float distanceToPacMan = Vector2.Distance(transform.position, pacManPosition);
        if (distanceToPacMan < 5.0f)
        {
            // 尝试预测吃豆人移动方向
            Rigidbody2D pacManRb = pacManTransform.GetComponent<Rigidbody2D>();
            if (pacManRb != null)
            {
                Vector2 predictedPosition = pacManPosition + pacManRb.velocity.normalized * 3.0f;
                currentTargetPosition = predictedPosition;
            }
        }
    }

    private void HandleFrightenedState()
    {
        // 恐惧状态:随机移动以躲避吃豆人
        if (pacManTransform == null)
        {
            return;
        }
        
        // 计算吃豆人位置
        Vector2 pacManPosition = pacManTransform.position;
        Vector2 awayFromPacMan = ((Vector2)transform.position - pacManPosition).normalized;
        
        // 选择远离吃豆人的方向
        Vector2[] possibleDirections = GetPossibleDirections();
        Vector2 bestDirection = Vector2.zero;
        float bestScore = -Mathf.Infinity;
        
        foreach (Vector2 direction in possibleDirections)
        {
            // 避免回头(除非必须)
            if (movementController.CurrentDirection == -direction)
            {
                continue;
            }
            
            // 计算分数:远离吃豆人 + 随机因素
            float distanceScore = Vector2.Dot(direction, awayFromPacMan);
            float randomScore = Random.Range(0f, 0.3f);
            float totalScore = distanceScore + randomScore;
            
            if (totalScore > bestScore)
            {
                bestScore = totalScore;
                bestDirection = direction;
            }
        }
        
        // 应用移动方向
        if (bestDirection != Vector2.zero)
        {
            movementController.SetDirection(bestDirection);
        }
        
        // 恐惧状态下的目标位置(随机点)
        if (ShouldRecalculatePath() || currentPath.Count == 0)
        {
            Vector2 randomTarget = GetRandomAccessiblePosition();
            CalculatePathToTarget(randomTarget);
        }
    }

    private void HandleEatenState()
    {
        // 被吃状态:返回鬼屋
        currentTargetPosition = ghostHousePosition;
        
        if (Vector2.Distance(transform.position, ghostHousePosition) < 0.5f)
        {
            // 到达鬼屋,切换到进入鬼屋状态
            ChangeState(GhostState.EnteringHouse);
        }
        else
        {
            // 计算返回鬼屋的路径
            if (ShouldRecalculatePath())
            {
                CalculatePathToTarget(ghostHousePosition);
            }
        }
    }

    private void HandleEnteringHouseState()
    {
        // 进入鬼屋状态:在鬼屋内重置
        transform.position = ghostHousePosition;
        isInGhostHouse = true;
        
        // 短暂延迟后恢复正常
        StartCoroutine(ResetFromEatenState());
    }

    private IEnumerator ResetFromEatenState()
    {
        yield return new WaitForSeconds(2.0f);
        
        // 重置为正常模式
        ChangeToNormalMode();
        ChangeState(GhostState.LeavingHouse);
        
        Debug.Log("红幽灵已重生");
    }

    private void ChangeState(GhostState newState)
    {
        if (currentState == newState || stateTimers.stateChangeCooldown > 0)
        {
            return;
        }
        
        GhostState previousState = currentState;
        currentState = newState;
        
        // 重置相关计时器
        switch (newState)
        {
            case GhostState.Scatter:
                stateTimers.scatterTimer = behaviorSettings.scatterDuration;
                break;
                
            case GhostState.Chase:
                stateTimers.chaseTimer = behaviorSettings.chaseDuration;
                break;
                
            case GhostState.Frightened:
                stateTimers.frightenedTimer = behaviorSettings.frightenedDuration;
                break;
        }
        
        // 设置状态转换冷却
        stateTimers.stateChangeCooldown = 0.5f;
        
        // 清除当前路径
        currentPath.Clear();
        currentPathIndex = 0;
        
        // 反转方向(经典吃豆人行为)
        if (movementController != null && 
            (previousState == GhostState.Scatter || previousState == GhostState.Chase) &&
            (newState == GhostState.Scatter || newState == GhostState.Chase))
        {
            movementController.ReverseDirection();
        }
        
        Debug.Log($"红幽灵状态变化: {previousState} -> {newState}");
        
        // 触发状态变化事件
        OnGhostStateChanged(previousState, newState);
    }

    public void SetFrightenedMode()
    {
        if (currentMode == GhostMode.Eaten)
        {
            return; // 被吃状态下不进入恐惧模式
        }
        
        currentMode = GhostMode.Frightened;
        isVulnerable = true;
        
        // 如果当前不是被吃状态,切换到恐惧状态
        if (currentState != GhostState.Eaten && currentState != GhostState.EnteringHouse)
        {
            ChangeState(GhostState.Frightened);
        }
        
        UpdateGhostAppearance();
        Debug.Log("红幽灵进入恐惧模式");
    }

    public void SetEatenMode()
    {
        if (currentMode != GhostMode.Frightened)
        {
            return; // 只有恐惧模式下才能被吃
        }
        
        currentMode = GhostMode.Eaten;
        ChangeState(GhostState.Eaten);
        UpdateGhostAppearance();
        
        // 增加分数
        GameScoreManager.Instance.AddGhostScore(200);
        
        Debug.Log("红幽灵被吃");
    }

    private void ChangeToNormalMode()
    {
        currentMode = GhostMode.Normal;
        isVulnerable = false;
        
        // 如果不是被吃或进入鬼屋状态,切换到散射状态
        if (currentState != GhostState.Eaten && currentState != GhostState.EnteringHouse)
        {
            ChangeState(GhostState.Scatter);
        }
        
        UpdateGhostAppearance();
        Debug.Log("红幽灵恢复正常模式");
    }

    private void UpdateGhostAppearance()
    {
        if (ghostSpriteRenderer == null)
        {
            return;
        }
        
        switch (currentMode)
        {
            case GhostMode.Normal:
                ghostSpriteRenderer.color = behaviorSettings.normalColor;
                break;
                
            case GhostMode.Frightened:
                ghostSpriteRenderer.color = behaviorSettings.frightenedColor;
                break;
                
            case GhostMode.Eaten:
                ghostSpriteRenderer.color = behaviorSettings.eatenColor;
                break;
        }
        
        // 更新动画参数
        if (ghostAnimator != null)
        {
            ghostAnimator.SetBool("IsFrightened", currentMode == GhostMode.Frightened);
            ghostAnimator.SetBool("IsEaten", currentMode == GhostMode.Eaten);
        }
    }

    private void UpdateMovement()
    {
        if (movementController == null)
        {
            return;
        }
        
        // 根据当前模式设置速度
        float currentSpeed = behaviorSettings.normalSpeed;
        
        switch (currentMode)
        {
            case GhostMode.Frightened:
                currentSpeed = behaviorSettings.frightenedSpeed;
                break;
                
            case GhostMode.Eaten:
                currentSpeed = behaviorSettings.eatenSpeed;
                break;
        }
        
        movementController.SetSpeed(currentSpeed);
        
        // 如果有路径,沿路径移动
        if (currentPath.Count > 0 && currentPathIndex < currentPath.Count)
        {
            Vector2 targetPosition = currentPath[currentPathIndex];
            Vector2 currentPosition = transform.position;
            
            if (Vector2.Distance(currentPosition, targetPosition) < 0.1f)
            {
                currentPathIndex++;
                
                if (currentPathIndex >= currentPath.Count)
                {
                    // 到达路径终点
                    currentPath.Clear();
                    currentPathIndex = 0;
                }
            }
            else
            {
                // 向路径点移动
                Vector2 direction = (targetPosition - currentPosition).normalized;
                movementController.SetDirection(direction);
            }
        }
    }

    private void UpdateAnimations()
    {
        if (ghostAnimator == null || movementController == null)
        {
            return;
        }
        
        // 更新移动方向动画
        Vector2 currentDirection = movementController.CurrentDirection;
        
        if (Mathf.Abs(currentDirection.x) > Mathf.Abs(currentDirection.y))
        {
            // 水平移动
            ghostAnimator.SetFloat("MoveX", Mathf.Sign(currentDirection.x));
            ghostAnimator.SetFloat("MoveY", 0);
        }
        else
        {
            // 垂直移动
            ghostAnimator.SetFloat("MoveX", 0);
            ghostAnimator.SetFloat("MoveY", Mathf.Sign(currentDirection.y));
        }
    }

    private void CalculatePathToTarget(Vector2 targetPosition)
    {
        if (gridNavigation == null)
        {
            return;
        }
        
        Vector2 startPosition = transform.position;
        currentPath = gridNavigation.FindPath(startPosition, targetPosition);
        currentPathIndex = 0;
        
        if (currentPath.Count == 0)
        {
            Debug.LogWarning("无法找到路径到目标位置: " + targetPosition);
        }
    }

    private bool ShouldRecalculatePath()
    {
        // 定期重新计算路径
        return Time.frameCount % 30 == 0; // 每30帧重新计算一次
    }

    private Vector2[] GetPossibleDirections()
    {
        // 获取当前可移动的方向
        // 在实际实现中,这会检查网格导航数据
        return new Vector2[]
        {
            Vector2.up,
            Vector2.down,
            Vector2.left,
            Vector2.right
        };
    }

    private Vector2 GetRandomAccessiblePosition()
    {
        // 获取随机可到达的位置
        // 简化实现:返回当前区域内的随机位置
        Vector2 currentPos = transform.position;
        float randomX = currentPos.x + Random.Range(-5f, 5f);
        float randomY = currentPos.y + Random.Range(-5f, 5f);
        
        return new Vector2(randomX, randomY);
    }

    private void WanderAroundCorner()
    {
        // 在角落附近徘徊
        float wanderRadius = 2.0f;
        float angle = Time.time * 0.5f; // 缓慢旋转
        
        Vector2 wanderOffset = new Vector2(
            Mathf.Cos(angle) * wanderRadius,
            Mathf.Sin(angle) * wanderRadius
        );
        
        currentTargetPosition = scatterTargetPosition + wanderOffset;
    }

    public void OnPacManAtePowerPellet()
    {
        // 当吃豆人吃掉能量豆时的反应
        SetFrightenedMode();
    }

    public void OnPacManAteDot()
    {
        // 当吃豆人吃掉豆子时的计数
        dotsEatenCounter++;
        
        // 检查是否达到释放条件(如果有)
        if (isInGhostHouse && dotsEatenCounter >= dotsEatenForRelease)
        {
            dotsEatenCounter = 0;
            // 可以触发释放逻辑
        }
    }

    public bool IsVulnerable
    {
        get { return isVulnerable; }
    }

    public GhostState CurrentState
    {
        get { return currentState; }
    }

    public GhostMode CurrentMode
    {
        get { return currentMode; }
    }

    public event System.Action<GhostState, GhostState> OnGhostStateChanged = delegate { };

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }
        
        // 绘制当前目标位置
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(currentTargetPosition, 0.3f);
        Gizmos.DrawLine(transform.position, currentTargetPosition);
        
        // 绘制路径
        Gizmos.color = Color.yellow;
        for (int i = 0; i < currentPath.Count - 1; i++)
        {
            Gizmos.DrawLine(currentPath[i], currentPath[i + 1]);
            Gizmos.DrawWireSphere(currentPath[i], 0.2f);
        }
        
        // 绘制当前状态信息
        #if UNITY_EDITOR
        string stateInfo = $"状态: {currentState}\n模式: {currentMode}";
        if (isVulnerable) stateInfo += "\n(脆弱)";
        
        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 0.5f,
            stateInfo
        );
        #endif
    }
}

public class GhostMovementController : MonoBehaviour
{
    [SerializeField]
    private Vector2 currentDirection = Vector2.right;

    [SerializeField]
    private float currentSpeed = 3.5f;

    private Rigidbody2D rb2D;

    private void Awake()
    {
        rb2D = GetComponent<Rigidbody2D>();
        if (rb2D == null)
        {
            rb2D = gameObject.AddComponent<Rigidbody2D>();
            rb2D.gravityScale = 0;
            rb2D.constraints = RigidbodyConstraints2D.FreezeRotation;
        }
    }

    private void FixedUpdate()
    {
        UpdateMovement();
    }

    private void UpdateMovement()
    {
        if (rb2D == null)
        {
            return;
        }
        
        Vector2 velocity = currentDirection * currentSpeed;
        rb2D.velocity = velocity;
    }

    public void SetDirection(Vector2 newDirection)
    {
        if (newDirection.magnitude > 0.1f)
        {
            currentDirection = newDirection.normalized;
        }
    }

    public void SetSpeed(float newSpeed)
    {
        currentSpeed = Mathf.Max(0, newSpeed);
    }

    public void ReverseDirection()
    {
        currentDirection = -currentDirection;
    }

    public Vector2 CurrentDirection
    {
        get { return currentDirection; }
    }
}

public class PacManGridNavigation : MonoBehaviour
{
    // 简化的网格导航系统
    public List<Vector2> FindPath(Vector2 start, Vector2 end)
    {
        // 简化实现:返回直接路径
        // 在实际吃豆人游戏中,这会使用更复杂的网格导航算法
        
        List<Vector2> path = new List<Vector2>();
        
        // 添加起点
        path.Add(start);
        
        // 添加几个中间点(简化)
        Vector2 midPoint = (start + end) / 2;
        path.Add(midPoint);
        
        // 添加终点
        path.Add(end);
        
        return path;
    }
}

public class GameScoreManager : MonoBehaviour
{
    private static GameScoreManager instance;
    
    private int currentScore = 0;
    
    public static GameScoreManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<GameScoreManager>();
                if (instance == null)
                {
                    GameObject go = new GameObject("GameScoreManager");
                    instance = go.AddComponent<GameScoreManager>();
                    DontDestroyOnLoad(go);
                }
            }
            return instance;
        }
    }
    
    public void AddGhostScore(int points)
    {
        currentScore += points;
        Debug.Log($"得分: {points},总分: {currentScore}");
        
        // 更新UI等
    }
}

6.1.2 《Quake II》中怪物AI的有限状态机案例分析

在经典第一人称射击游戏《雷神之锤II》中,怪物AI使用了相对复杂但高效的有限状态机系统。每个怪物类型都有自己独特的状态机,但共享相似的基本结构。

《Quake II》怪物状态机的核心特点:

  1. 感知状态:怪物检测玩家存在
  2. 追逐状态:怪物追踪玩家位置
  3. 攻击状态:怪物执行攻击行为
  4. 受伤状态:怪物受到伤害时的反应
  5. 死亡状态:怪物死亡后的处理

下面是一个基于《Quake II》怪物AI的现代实现,展示了如何在3D射击游戏中应用FSM:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class QuakeMonsterFSM : MonoBehaviour
{
    [System.Serializable]
    public class MonsterStats
    {
        public int maxHealth = 100;
        public float moveSpeed = 5.0f;
        public float chaseSpeed = 7.0f;
        public float attackRange = 10.0f;
        public float detectionRange = 20.0f;
        public float attackDamage = 10.0f;
        public float attackCooldown = 1.0f;
        public float painChance = 0.3f; // 受伤时进入疼痛状态的概率
    }

    [System.Serializable]
    public class MonsterSounds
    {
        public AudioClip idleSound;
        public AudioClip chaseSound;
        public AudioClip attackSound;
        public AudioClip painSound;
        public AudioClip deathSound;
        public float soundVolume = 0.7f;
    }

    public enum MonsterState
    {
        Idle,           // 空闲状态
        Patrol,         // 巡逻状态
        Chase,          // 追逐状态
        Attack,         // 攻击状态
        Pain,           // 受伤疼痛状态
        Dead,           // 死亡状态
        Ambush          // 伏击状态
    }

    public enum MonsterType
    {
        Grunt,          // 普通士兵
        Enforcer,       // 强化士兵
        Berserker,      // 狂战士
        Flyer,          // 飞行单位
        Tank            // 重型单位
    }

    [Header("怪物属性")]
    [SerializeField]
    private MonsterType monsterType = MonsterType.Grunt;

    [SerializeField]
    private MonsterStats stats = new MonsterStats();

    [Header("状态管理")]
    [SerializeField]
    private MonsterState currentState = MonsterState.Idle;

    [SerializeField]
    private MonsterState previousState = MonsterState.Idle;

    [SerializeField]
    private int currentHealth;

    [Header("目标追踪")]
    [SerializeField]
    private Transform playerTarget;

    [SerializeField]
    private Vector3 lastKnownPlayerPosition;

    [SerializeField]
    private float playerLastSeenTime;

    [Header("攻击系统")]
    [SerializeField]
    private float attackTimer;

    [SerializeField]
    private bool canAttack = true;

    [SerializeField]
    private GameObject projectilePrefab;

    [SerializeField]
    private Transform projectileSpawnPoint;

    [Header("组件引用")]
    [SerializeField]
    private CharacterController characterController;

    [SerializeField]
    private Animator monsterAnimator;

    [SerializeField]
    private AudioSource audioSource;

    [SerializeField]
    private AudioSource footstepAudioSource;

    [SerializeField]
    private MonsterSounds monsterSounds = new MonsterSounds();

    [Header("巡逻系统")]
    [SerializeField]
    private List<Vector3> patrolPoints = new List<Vector3>();

    [SerializeField]
    private int currentPatrolIndex;

    [SerializeField]
    private float patrolWaitTime = 2.0f;

    [SerializeField]
    private float patrolTimer;

    [Header("感知系统")]
    [SerializeField]
    private float sightCheckInterval = 0.2f;

    [SerializeField]
    private float lastSightCheckTime;

    [SerializeField]
    private bool playerInSight;

    [SerializeField]
    private float hearingRange = 15.0f;

    private Vector3 spawnPosition;
    private Quaternion spawnRotation;
    private bool isActive = true;
    private float stateEnterTime;
    private float painDuration = 0.5f;
    private float painTimer;

    private void Awake()
    {
        InitializeMonster();
    }

    private void InitializeMonster()
    {
        // 保存初始位置和旋转
        spawnPosition = transform.position;
        spawnRotation = transform.rotation;
        
        // 初始化生命值
        currentHealth = stats.maxHealth;
        
        // 获取组件引用
        if (characterController == null)
        {
            characterController = GetComponent<CharacterController>();
        }
        
        if (monsterAnimator == null)
        {
            monsterAnimator = GetComponent<Animator>();
        }
        
        if (audioSource == null)
        {
            audioSource = GetComponent<AudioSource>();
        }
        
        if (footstepAudioSource == null)
        {
            footstepAudioSource = gameObject.AddComponent<AudioSource>();
            footstepAudioSource.spatialBlend = 1.0f;
            footstepAudioSource.volume = 0.3f;
        }
        
        // 查找玩家
        if (playerTarget == null)
        {
            GameObject player = GameObject.FindGameObjectWithTag("Player");
            if (player != null)
            {
                playerTarget = player.transform;
            }
        }
        
        // 初始化巡逻点
        InitializePatrolPoints();
        
        // 设置初始状态
        ChangeState(MonsterState.Idle);
        
        Debug.Log($"{monsterType} 怪物初始化完成,生命值: {currentHealth}/{stats.maxHealth}");
    }

    private void InitializePatrolPoints()
    {
        // 根据怪物类型生成巡逻点
        int patrolPointCount = 0;
        
        switch (monsterType)
        {
            case MonsterType.Grunt:
                patrolPointCount = 3;
                break;
                
            case MonsterType.Enforcer:
                patrolPointCount = 4;
                break;
                
            case MonsterType.Berserker:
                patrolPointCount = 2; // 狂战士更倾向于待命
                break;
                
            case MonsterType.Flyer:
                patrolPointCount = 5; // 飞行单位有更大的巡逻范围
                break;
                
            case MonsterType.Tank:
                patrolPointCount = 2; // 重型单位移动缓慢
                break;
        }
        
        patrolPoints.Clear();
        
        // 生成围绕生成点的巡逻点
        for (int i = 0; i < patrolPointCount; i++)
        {
            float angle = (i * 360f / patrolPointCount) * Mathf.Deg2Rad;
            float radius = Random.Range(3f, 8f);
            
            Vector3 patrolPoint = spawnPosition + new Vector3(
                Mathf.Cos(angle) * radius,
                0,
                Mathf.Sin(angle) * radius
            );
            
            patrolPoints.Add(patrolPoint);
        }
        
        currentPatrolIndex = 0;
        patrolTimer = 0f;
    }

    private void Update()
    {
        if (!isActive || currentState == MonsterState.Dead)
        {
            return;
        }
        
        UpdatePerception();
        UpdateStateMachine();
        UpdateTimers();
        UpdateAnimations();
    }

    private void UpdatePerception()
    {
        if (playerTarget == null || Time.time - lastSightCheckTime < sightCheckInterval)
        {
            return;
        }
        
        lastSightCheckTime = Time.time;
        
        // 检查玩家是否在视野内
        Vector3 directionToPlayer = playerTarget.position - transform.position;
        float distanceToPlayer = directionToPlayer.magnitude;
        
        // 检查是否在检测范围内
        if (distanceToPlayer > stats.detectionRange)
        {
            playerInSight = false;
            return;
        }
        
        // 检查视线是否被阻挡
        RaycastHit hit;
        bool hasLineOfSight = false;
        
        if (Physics.Raycast(
            transform.position + Vector3.up * 1.5f,
            directionToPlayer.normalized,
            out hit,
            stats.detectionRange,
            ~LayerMask.GetMask("Monster", "Trigger"),
            QueryTriggerInteraction.Ignore
        ))
        {
            if (hit.collider.CompareTag("Player"))
            {
                hasLineOfSight = true;
            }
        }
        
        playerInSight = hasLineOfSight;
        
        if (playerInSight)
        {
            lastKnownPlayerPosition = playerTarget.position;
            playerLastSeenTime = Time.time;
            
            // 如果玩家在听觉范围内,即使看不到也能听到
            if (distanceToPlayer <= hearingRange)
            {
                OnPlayerDetected();
            }
        }
        
        // 检查是否应该听到玩家声音
        CheckHearing();
    }

    private void CheckHearing()
    {
        if (playerTarget == null)
        {
            return;
        }
        
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        // 如果玩家在听觉范围内且最近发出过声音
        PlayerNoiseEmitter noiseEmitter = playerTarget.GetComponent<PlayerNoiseEmitter>();
        if (noiseEmitter != null && distanceToPlayer <= hearingRange)
        {
            float lastNoiseTime = noiseEmitter.GetLastNoiseTime();
            float noiseLevel = noiseEmitter.GetCurrentNoiseLevel();
            
            // 根据噪音级别调整检测
            float effectiveHearingRange = hearingRange * noiseLevel;
            
            if (Time.time - lastNoiseTime < 2.0f && distanceToPlayer <= effectiveHearingRange)
            {
                // 听到玩家声音,前往调查
                lastKnownPlayerPosition = playerTarget.position;
                playerLastSeenTime = Time.time;
                
                if (currentState == MonsterState.Idle || currentState == MonsterState.Patrol)
                {
                    ChangeState(MonsterState.Chase);
                }
            }
        }
    }

    private void UpdateStateMachine()
    {
        // 处理当前状态
        switch (currentState)
        {
            case MonsterState.Idle:
                HandleIdleState();
                break;
                
            case MonsterState.Patrol:
                HandlePatrolState();
                break;
                
            case MonsterState.Chase:
                HandleChaseState();
                break;
                
            case MonsterState.Attack:
                HandleAttackState();
                break;
                
            case MonsterState.Pain:
                HandlePainState();
                break;
                
            case MonsterState.Ambush:
                HandleAmbushState();
                break;
        }
        
        // 全局状态转换检查
        CheckGlobalTransitions();
    }

    private void HandleIdleState()
    {
        // 空闲状态:播放空闲动画,偶尔环顾四周
        
        // 一段时间后开始巡逻
        float timeInState = Time.time - stateEnterTime;
        if (timeInState > 5.0f)
        {
            ChangeState(MonsterState.Patrol);
        }
        
        // 随机播放空闲声音
        if (Random.value < 0.01f && monsterSounds.idleSound != null)
        {
            PlaySound(monsterSounds.idleSound);
        }
    }

    private void HandlePatrolState()
    {
        if (patrolPoints.Count == 0)
        {
            ChangeState(MonsterState.Idle);
            return;
        }
        
        Vector3 targetPosition = patrolPoints[currentPatrolIndex];
        Vector3 directionToTarget = (targetPosition - transform.position).normalized;
        
        // 移动到巡逻点
        MoveTowards(directionToTarget, stats.moveSpeed);
        
        // 检查是否到达巡逻点
        if (Vector3.Distance(transform.position, targetPosition) < 1.0f)
        {
            patrolTimer += Time.deltaTime;
            
            if (patrolTimer >= patrolWaitTime)
            {
                // 前往下一个巡逻点
                currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Count;
                patrolTimer = 0f;
                
                // 随机决定是否停留更久
                if (Random.value < 0.3f)
                {
                    patrolWaitTime = Random.Range(2.0f, 5.0f);
                }
            }
        }
        
        // 播放脚步声
        PlayFootstepSound();
    }

    private void HandleChaseState()
    {
        if (playerTarget == null)
        {
            ChangeState(MonsterState.Patrol);
            return;
        }
        
        // 检查玩家是否在攻击范围内
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        if (distanceToPlayer <= stats.attackRange && playerInSight)
        {
            ChangeState(MonsterState.Attack);
            return;
        }
        
        // 追逐玩家
        Vector3 chaseDirection;
        
        if (playerInSight)
        {
            // 直接追逐可见玩家
            chaseDirection = (playerTarget.position - transform.position).normalized;
            lastKnownPlayerPosition = playerTarget.position;
        }
        else
        {
            // 前往最后已知位置
            chaseDirection = (lastKnownPlayerPosition - transform.position).normalized;
            
            // 检查是否到达最后已知位置
            if (Vector3.Distance(transform.position, lastKnownPlayerPosition) < 2.0f)
            {
                // 玩家已丢失,返回巡逻
                ChangeState(MonsterState.Patrol);
                return;
            }
            
            // 检查玩家丢失时间
            if (Time.time - playerLastSeenTime > 10.0f)
            {
                ChangeState(MonsterState.Patrol);
                return;
            }
        }
        
        // 移动追逐
        MoveTowards(chaseDirection, stats.chaseSpeed);
        
        // 播放追逐声音
        if (Random.value < 0.02f && monsterSounds.chaseSound != null)
        {
            PlaySound(monsterSounds.chaseSound);
        }
        
        // 播放脚步声
        PlayFootstepSound(1.5f); // 追逐时脚步声更快
    }

    private void HandleAttackState()
    {
        if (playerTarget == null)
        {
            ChangeState(MonsterState.Patrol);
            return;
        }
        
        // 面向玩家
        Vector3 directionToPlayer = (playerTarget.position - transform.position).normalized;
        directionToPlayer.y = 0;
        
        if (directionToPlayer.magnitude > 0.1f)
        {
            Quaternion targetRotation = Quaternion.LookRotation(directionToPlayer);
            transform.rotation = Quaternion.Slerp(
                transform.rotation,
                targetRotation,
                10.0f * Time.deltaTime
            );
        }
        
        // 检查玩家是否仍在攻击范围内
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        if (distanceToPlayer > stats.attackRange || !playerInSight)
        {
            ChangeState(MonsterState.Chase);
            return;
        }
        
        // 执行攻击
        if (canAttack)
        {
            AttackPlayer();
            canAttack = false;
            attackTimer = stats.attackCooldown;
        }
        
        // 根据怪物类型决定攻击时的移动
        switch (monsterType)
        {
            case MonsterType.Berserker:
                // 狂战士在攻击时会继续靠近玩家
                if (distanceToPlayer > 3.0f)
                {
                    MoveTowards(directionToPlayer, stats.moveSpeed * 0.5f);
                }
                break;
                
            case MonsterType.Flyer:
                // 飞行单位会在攻击时保持距离
                if (distanceToPlayer < stats.attackRange * 0.7f)
                {
                    MoveTowards(-directionToPlayer, stats.moveSpeed * 0.3f);
                }
                break;
        }
    }

    private void HandlePainState()
    {
        // 疼痛状态:短暂停顿,播放受伤动画
        
        painTimer += Time.deltaTime;
        
        if (painTimer >= painDuration)
        {
            // 返回之前的状态
            ChangeState(previousState);
        }
    }

    private void HandleAmbushState()
    {
        // 伏击状态:隐藏并等待玩家靠近
        
        if (playerTarget == null)
        {
            ChangeState(MonsterState.Patrol);
            return;
        }
        
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        // 当玩家足够近时发动攻击
        if (distanceToPlayer < stats.attackRange * 0.7f && playerInSight)
        {
            ChangeState(MonsterState.Attack);
        }
        // 如果玩家离开或等待时间过长,放弃伏击
        else if (Time.time - stateEnterTime > 15.0f)
        {
            ChangeState(MonsterState.Patrol);
        }
    }

    private void CheckGlobalTransitions()
    {
        // 全局状态转换规则
        
        // 死亡检查
        if (currentHealth <= 0 && currentState != MonsterState.Dead)
        {
            ChangeState(MonsterState.Dead);
            return;
        }
        
        // 玩家检测
        if (playerInSight && 
            (currentState == MonsterState.Idle || currentState == MonsterState.Patrol))
        {
            // 根据怪物类型决定反应
            switch (monsterType)
            {
                case MonsterType.Grunt:
                case MonsterType.Enforcer:
                    ChangeState(MonsterState.Chase);
                    break;
                    
                case MonsterType.Berserker:
                    ChangeState(MonsterState.Chase);
                    // 狂战士立即发出战吼
                    PlaySound(monsterSounds.chaseSound);
                    break;
                    
                case MonsterType.Flyer:
                    // 飞行单位可能选择伏击
                    if (Random.value < 0.5f)
                    {
                        ChangeState(MonsterState.Ambush);
                    }
                    else
                    {
                        ChangeState(MonsterState.Chase);
                    }
                    break;
                    
                case MonsterType.Tank:
                    // 重型单位反应较慢
                    if (Random.value < 0.3f)
                    {
                        ChangeState(MonsterState.Chase);
                    }
                    break;
            }
        }
    }

    private void MoveTowards(Vector3 direction, float speed)
    {
        if (characterController == null || !characterController.enabled)
        {
            return;
        }
        
        direction.y = 0;
        
        // 应用移动
        Vector3 moveVector = direction * speed * Time.deltaTime;
        characterController.Move(moveVector);
        
        // 旋转面向移动方向
        if (direction.magnitude > 0.1f)
        {
            Quaternion targetRotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.Slerp(
                transform.rotation,
                targetRotation,
                5.0f * Time.deltaTime
            );
        }
    }

    private void AttackPlayer()
    {
        // 执行攻击
        switch (monsterType)
        {
            case MonsterType.Grunt:
            case MonsterType.Enforcer:
                RangedAttack();
                break;
                
            case MonsterType.Berserker:
                MeleeAttack();
                break;
                
            case MonsterType.Flyer:
                FlyerAttack();
                break;
                
            case MonsterType.Tank:
                TankAttack();
                break;
        }
        
        // 播放攻击声音
        if (monsterSounds.attackSound != null)
        {
            PlaySound(monsterSounds.attackSound);
        }
        
        // 触发攻击动画
        if (monsterAnimator != null)
        {
            monsterAnimator.SetTrigger("Attack");
        }
        
        Debug.Log($"{monsterType} 发动攻击");
    }

    private void RangedAttack()
    {
        // 远程攻击:发射抛射物
        if (projectilePrefab != null && projectileSpawnPoint != null)
        {
            GameObject projectile = Instantiate(
                projectilePrefab,
                projectileSpawnPoint.position,
                projectileSpawnPoint.rotation
            );
            
            MonsterProjectile projScript = projectile.GetComponent<MonsterProjectile>();
            if (projScript != null)
            {
                projScript.SetDamage(stats.attackDamage);
                projScript.SetTarget(playerTarget);
            }
        }
        else
        {
            // 如果没有抛射物,进行直接伤害
            if (playerTarget != null)
            {
                PlayerHealth playerHealth = playerTarget.GetComponent<PlayerHealth>();
                if (playerHealth != null)
                {
                    playerHealth.TakeDamage(stats.attackDamage);
                }
            }
        }
    }

    private void MeleeAttack()
    {
        // 近战攻击:检查范围内玩家
        if (playerTarget != null)
        {
            float distance = Vector3.Distance(transform.position, playerTarget.position);
            if (distance <= 3.0f)
            {
                PlayerHealth playerHealth = playerTarget.GetComponent<PlayerHealth>();
                if (playerHealth != null)
                {
                    playerHealth.TakeDamage(stats.attackDamage * 1.5f); // 近战伤害更高
                }
            }
        }
    }

    private void FlyerAttack()
    {
        // 飞行单位攻击:快速俯冲或发射多个抛射物
        if (projectilePrefab != null && projectileSpawnPoint != null)
        {
            // 发射3个散射抛射物
            for (int i = 0; i < 3; i++)
            {
                Vector3 spread = new Vector3(
                    Random.Range(-0.2f, 0.2f),
                    Random.Range(-0.1f, 0.1f),
                    Random.Range(-0.2f, 0.2f)
                );
                
                Quaternion spreadRotation = projectileSpawnPoint.rotation * Quaternion.Euler(spread * 30);
                
                GameObject projectile = Instantiate(
                    projectilePrefab,
                    projectileSpawnPoint.position,
                    spreadRotation
                );
                
                MonsterProjectile projScript = projectile.GetComponent<MonsterProjectile>();
                if (projScript != null)
                {
                    projScript.SetDamage(stats.attackDamage * 0.7f);
                }
            }
        }
    }

    private void TankAttack()
    {
        // 重型单位攻击:高伤害但慢速
        if (projectilePrefab != null && projectileSpawnPoint != null)
        {
            GameObject projectile = Instantiate(
                projectilePrefab,
                projectileSpawnPoint.position,
                projectileSpawnPoint.rotation
            );
            
            MonsterProjectile projScript = projectile.GetComponent<MonsterProjectile>();
            if (projScript != null)
            {
                projScript.SetDamage(stats.attackDamage * 2.0f);
                projScript.SetSpeed(15.0f); // 较慢但伤害高
            }
        }
    }

    private void UpdateTimers()
    {
        // 更新攻击冷却
        if (!canAttack)
        {
            attackTimer -= Time.deltaTime;
            if (attackTimer <= 0)
            {
                canAttack = true;
            }
        }
    }

    private void UpdateAnimations()
    {
        if (monsterAnimator == null)
        {
            return;
        }
        
        // 设置状态参数
        monsterAnimator.SetInteger("State", (int)currentState);
        
        // 设置移动速度参数
        float speed = 0f;
        if (characterController != null)
        {
            speed = characterController.velocity.magnitude;
        }
        monsterAnimator.SetFloat("Speed", speed);
        
        // 设置生命值参数
        float healthRatio = (float)currentHealth / stats.maxHealth;
        monsterAnimator.SetFloat("Health", healthRatio);
    }

    private void PlaySound(AudioClip clip)
    {
        if (audioSource != null && clip != null)
        {
            audioSource.PlayOneShot(clip, monsterSounds.soundVolume);
        }
    }

    private void PlayFootstepSound(float pitchMultiplier = 1.0f)
    {
        if (footstepAudioSource != null && !footstepAudioSource.isPlaying)
        {
            // 根据移动速度调整脚步频率
            float speed = characterController != null ? characterController.velocity.magnitude : 0f;
            
            if (speed > 0.5f)
            {
                footstepAudioSource.pitch = Random.Range(0.8f, 1.2f) * pitchMultiplier;
                footstepAudioSource.Play();
            }
        }
    }

    public void TakeDamage(float damage, Vector3 hitPoint, GameObject damageSource)
    {
        if (currentState == MonsterState.Dead || !isActive)
        {
            return;
        }
        
        // 减少生命值
        currentHealth -= Mathf.RoundToInt(damage);
        
        // 检查是否死亡
        if (currentHealth <= 0)
        {
            ChangeState(MonsterState.Dead);
            return;
        }
        
        // 根据概率进入疼痛状态
        if (Random.value < stats.painChance && currentState != MonsterState.Pain)
        {
            previousState = currentState;
            ChangeState(MonsterState.Pain);
            painTimer = 0f;
            
            // 播放疼痛声音
            if (monsterSounds.painSound != null)
            {
                PlaySound(monsterSounds.painSound);
            }
        }
        
        // 如果受到玩家攻击且不在追逐/攻击状态,开始追逐
        if (damageSource != null && damageSource.CompareTag("Player") &&
            (currentState == MonsterState.Idle || currentState == MonsterState.Patrol))
        {
            lastKnownPlayerPosition = damageSource.transform.position;
            playerLastSeenTime = Time.time;
            ChangeState(MonsterState.Chase);
        }
        
        Debug.Log($"{monsterType} 受到伤害: {damage},剩余生命: {currentHealth}");
    }

    private void ChangeState(MonsterState newState)
    {
        if (currentState == newState)
        {
            return;
        }
        
        previousState = currentState;
        currentState = newState;
        stateEnterTime = Time.time;
        
        // 状态进入时的特殊处理
        switch (newState)
        {
            case MonsterState.Chase:
                OnEnterChaseState();
                break;
                
            case MonsterState.Attack:
                OnEnterAttackState();
                break;
                
            case MonsterState.Dead:
                OnEnterDeadState();
                break;
                
            case MonsterState.Ambush:
                OnEnterAmbushState();
                break;
        }
        
        Debug.Log($"{monsterType} 状态变化: {previousState} -> {newState}");
    }

    private void OnEnterChaseState()
    {
        // 追逐状态进入时的处理
        if (monsterSounds.chaseSound != null)
        {
            PlaySound(monsterSounds.chaseSound);
        }
    }

    private void OnEnterAttackState()
    {
        // 攻击状态进入时的处理
        // 重置攻击计时器,可以立即攻击
        canAttack = true;
        attackTimer = 0f;
    }

    private void OnEnterDeadState()
    {
        // 死亡状态进入时的处理
        isActive = false;
        
        if (characterController != null)
        {
            characterController.enabled = false;
        }
        
        // 播放死亡声音
        if (monsterSounds.deathSound != null)
        {
            PlaySound(monsterSounds.deathSound);
        }
        
        // 触发死亡动画
        if (monsterAnimator != null)
        {
            monsterAnimator.SetTrigger("Die");
        }
        
        // 禁用碰撞器
        Collider collider = GetComponent<Collider>();
        if (collider != null)
        {
            collider.enabled = false;
        }
        
        // 开始消失过程
        StartCoroutine(DeathSequence());
        
        Debug.Log($"{monsterType} 已死亡");
    }

    private void OnEnterAmbushState()
    {
        // 伏击状态进入时的处理
        // 尝试隐藏(如改变材质、缩小碰撞器等)
        Renderer renderer = GetComponent<Renderer>();
        if (renderer != null)
        {
            // 变暗材质以模拟隐藏
            foreach (Material material in renderer.materials)
            {
                Color color = material.color;
                color *= 0.5f;
                material.color = color;
            }
        }
    }

    private IEnumerator DeathSequence()
    {
        // 等待死亡动画完成
        yield return new WaitForSeconds(2.0f);
        
        // 下沉效果
        float sinkSpeed = 0.5f;
        float sinkTime = 2.0f;
        float timer = 0f;
        
        while (timer < sinkTime)
        {
            transform.position += Vector3.down * sinkSpeed * Time.deltaTime;
            timer += Time.deltaTime;
            yield return null;
        }
        
        // 销毁对象
        Destroy(gameObject);
    }

    private void OnPlayerDetected()
    {
        // 玩家被检测到时的处理
        // 可以在这里触发警报、通知其他怪物等
        
        // 通知附近的同类
        float notificationRange = 15.0f;
        Collider[] nearbyMonsters = Physics.OverlapSphere(
            transform.position,
            notificationRange,
            LayerMask.GetMask("Monster")
        );
        
        foreach (Collider collider in nearbyMonsters)
        {
            if (collider.gameObject != gameObject)
            {
                QuakeMonsterFSM otherMonster = collider.GetComponent<QuakeMonsterFSM>();
                if (otherMonster != null)
                {
                    otherMonster.OnAlarmTriggered(lastKnownPlayerPosition);
                }
            }
        }
    }

    public void OnAlarmTriggered(Vector3 alarmPosition)
    {
        // 被其他怪物警报触发
        if (currentState == MonsterState.Idle || currentState == MonsterState.Patrol)
        {
            lastKnownPlayerPosition = alarmPosition;
            playerLastSeenTime = Time.time;
            ChangeState(MonsterState.Chase);
        }
    }

    public MonsterState CurrentState
    {
        get { return currentState; }
    }

    public int CurrentHealth
    {
        get { return currentHealth; }
    }

    public bool IsActive
    {
        get { return isActive; }
    }

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }
        
        // 绘制检测范围
        Gizmos.color = playerInSight ? Color.red : Color.yellow;
        Gizmos.DrawWireSphere(transform.position, stats.detectionRange);
        
        // 绘制攻击范围
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, stats.attackRange);
        
        // 绘制听觉范围
        Gizmos.color = new Color(0, 1, 1, 0.3f);
        Gizmos.DrawWireSphere(transform.position, hearingRange);
        
        // 绘制巡逻点
        Gizmos.color = Color.green;
        foreach (Vector3 point in patrolPoints)
        {
            Gizmos.DrawWireSphere(point, 0.3f);
        }
        
        // 绘制当前目标
        if (playerTarget != null && playerInSight)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawLine(transform.position, playerTarget.position);
        }
        else if (lastKnownPlayerPosition != Vector3.zero)
        {
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(transform.position, lastKnownPlayerPosition);
            Gizmos.DrawWireSphere(lastKnownPlayerPosition, 0.5f);
        }
        
        // 绘制状态信息
        #if UNITY_EDITOR
        string stateInfo = $"{monsterType}\n";
        stateInfo += $"状态: {currentState}\n";
        stateInfo += $"生命: {currentHealth}/{stats.maxHealth}\n";
        stateInfo += $"玩家视野: {playerInSight}";
        
        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 2.5f,
            stateInfo
        );
        #endif
    }
}

public class MonsterProjectile : MonoBehaviour
{
    [SerializeField]
    private float speed = 20.0f;
    
    [SerializeField]
    private float damage = 10.0f;
    
    [SerializeField]
    private float lifetime = 5.0f;
    
    [SerializeField]
    private GameObject impactEffect;
    
    private Transform target;
    private Vector3 targetDirection;
    private float spawnTime;
    
    private void Start()
    {
        spawnTime = Time.time;
        Destroy(gameObject, lifetime);
    }
    
    private void Update()
    {
        // 移动逻辑
        if (target != null)
        {
            // 追踪目标
            targetDirection = (target.position - transform.position).normalized;
        }
        
        // 应用移动
        transform.position += targetDirection * speed * Time.deltaTime;
        
        // 旋转面向移动方向
        if (targetDirection.magnitude > 0.1f)
        {
            transform.rotation = Quaternion.LookRotation(targetDirection);
        }
        
        // 检查生命周期
        if (Time.time - spawnTime > lifetime)
        {
            Destroy(gameObject);
        }
    }
    
    public void SetDamage(float newDamage)
    {
        damage = newDamage;
    }
    
    public void SetSpeed(float newSpeed)
    {
        speed = newSpeed;
    }
    
    public void SetTarget(Transform newTarget)
    {
        target = newTarget;
        if (target != null)
        {
            targetDirection = (target.position - transform.position).normalized;
        }
    }
    
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Monster") || other.CompareTag("Projectile"))
        {
            return; // 忽略友军和别的抛射物
        }
        
        // 对玩家造成伤害
        if (other.CompareTag("Player"))
        {
            PlayerHealth playerHealth = other.GetComponent<PlayerHealth>();
            if (playerHealth != null)
            {
                playerHealth.TakeDamage(damage);
            }
        }
        
        // 创建击中效果
        if (impactEffect != null)
        {
            Instantiate(impactEffect, transform.position, Quaternion.identity);
        }
        
        // 销毁抛射物
        Destroy(gameObject);
    }
}

public class PlayerNoiseEmitter : MonoBehaviour
{
    [SerializeField]
    private float baseNoiseLevel = 1.0f;
    
    [SerializeField]
    private float runningNoiseMultiplier = 2.0f;
    
    [SerializeField]
    private float shootingNoiseLevel = 5.0f;
    
    [SerializeField]
    private float noiseDecayRate = 0.5f;
    
    private float currentNoiseLevel = 0f;
    private float lastNoiseTime = 0f;
    private CharacterController characterController;
    
    private void Awake()
    {
        characterController = GetComponent<CharacterController>();
    }
    
    private void Update()
    {
        UpdateNoise();
    }
    
    private void UpdateNoise()
    {
        // 基础噪音(移动产生)
        float movementNoise = 0f;
        
        if (characterController != null)
        {
            float speed = characterController.velocity.magnitude;
            
            if (speed > 0.1f)
            {
                movementNoise = baseNoiseLevel;
                
                // 跑步产生更多噪音
                if (speed > 5.0f)
                {
                    movementNoise *= runningNoiseMultiplier;
                }
            }
        }
        
        // 噪音衰减
        currentNoiseLevel = Mathf.Max(movementNoise, currentNoiseLevel - noiseDecayRate * Time.deltaTime);
        
        // 更新最后噪音时间
        if (currentNoiseLevel > 0.1f)
        {
            lastNoiseTime = Time.time;
        }
    }
    
    public void EmitNoise(float noiseAmount)
    {
        currentNoiseLevel = Mathf.Max(currentNoiseLevel, noiseAmount);
        lastNoiseTime = Time.time;
    }
    
    public float GetCurrentNoiseLevel()
    {
        return currentNoiseLevel;
    }
    
    public float GetLastNoiseTime()
    {
        return lastNoiseTime;
    }
}

public class PlayerHealth : MonoBehaviour
{
    [SerializeField]
    private float maxHealth = 100f;
    
    [SerializeField]
    private float currentHealth;
    
    private void Awake()
    {
        currentHealth = maxHealth;
    }
    
    public void TakeDamage(float damage)
    {
        currentHealth -= damage;
        currentHealth = Mathf.Max(0, currentHealth);
        
        Debug.Log($"玩家受到伤害: {damage},剩余生命: {currentHealth}");
        
        if (currentHealth <= 0)
        {
            Die();
        }
    }
    
    private void Die()
    {
        Debug.Log("玩家死亡");
        // 处理玩家死亡逻辑
    }
}

6.2 有限状态机的基础实现方法

6.2.1 使用Switch语句实现简单状态机

最简单的有限状态机实现方式是使用switch语句。这种方法直观易懂,适合状态数量较少、逻辑简单的AI系统。尽管在大型项目中可能不够灵活,但对于小型游戏或原型开发来说,switch语句状态机是一个很好的起点。

下面是一个完整的switch语句状态机实现,展示了如何创建一个基础的敌人AI:

using UnityEngine;
using System.Collections;

public class SwitchStatementFSM : MonoBehaviour
{
    public enum EnemyState
    {
        Idle,
        Patrol,
        Chase,
        Attack,
        Retreat,
        Dead
    }

    [Header("敌人属性")]
    [SerializeField]
    private float moveSpeed = 3.5f;
    
    [SerializeField]
    private float chaseSpeed = 5.0f;
    
    [SerializeField]
    private float attackRange = 2.0f;
    
    [SerializeField]
    private float detectionRange = 10.0f;
    
    [SerializeField]
    private float health = 100f;
    
    [SerializeField]
    private float attackDamage = 10f;
    
    [SerializeField]
    private float attackCooldown = 1.0f;

    [Header("状态管理")]
    [SerializeField]
    private EnemyState currentState = EnemyState.Idle;
    
    [SerializeField]
    private float stateTimer = 0f;
    
    [SerializeField]
    private float attackTimer = 0f;

    [Header("目标与导航")]
    [SerializeField]
    private Transform playerTarget;
    
    [SerializeField]
    private Vector3 patrolTarget;
    
    [SerializeField]
    private Vector3 retreatPosition;
    
    [SerializeField]
    private float patrolRadius = 5f;

    [Header("组件引用")]
    [SerializeField]
    private CharacterController characterController;
    
    [SerializeField]
    private Animator enemyAnimator;
    
    [SerializeField]
    private GameObject projectilePrefab;
    
    [SerializeField]
    private Transform weaponMuzzle;

    private Vector3 spawnPosition;
    private bool canAttack = true;
    private float idleDuration = 3f;
    private float patrolPointWaitTime = 2f;

    private void Awake()
    {
        InitializeEnemy();
    }

    private void InitializeEnemy()
    {
        spawnPosition = transform.position;
        
        if (characterController == null)
        {
            characterController = GetComponent<CharacterController>();
        }
        
        if (enemyAnimator == null)
        {
            enemyAnimator = GetComponent<Animator>();
        }
        
        if (playerTarget == null)
        {
            GameObject player = GameObject.FindGameObjectWithTag("Player");
            if (player != null)
            {
                playerTarget = player.transform;
            }
        }
        
        // 设置初始巡逻目标
        SetNewPatrolTarget();
        
        // 设置初始状态
        ChangeState(EnemyState.Idle);
        
        Debug.Log("敌人初始化完成,初始状态: " + currentState);
    }

    private void Update()
    {
        // 更新状态计时器
        stateTimer += Time.deltaTime;
        
        // 更新攻击冷却
        if (!canAttack)
        {
            attackTimer -= Time.deltaTime;
            if (attackTimer <= 0)
            {
                canAttack = true;
            }
        }
        
        // 执行当前状态
        ExecuteCurrentState();
        
        // 更新动画
        UpdateAnimations();
        
        // 全局状态检查
        CheckGlobalConditions();
    }

    private void ExecuteCurrentState()
    {
        // 使用switch语句处理不同状态
        switch (currentState)
        {
            case EnemyState.Idle:
                ExecuteIdleState();
                break;
                
            case EnemyState.Patrol:
                ExecutePatrolState();
                break;
                
            case EnemyState.Chase:
                ExecuteChaseState();
                break;
                
            case EnemyState.Attack:
                ExecuteAttackState();
                break;
                
            case EnemyState.Retreat:
                ExecuteRetreatState();
                break;
                
            case EnemyState.Dead:
                ExecuteDeadState();
                break;
        }
    }

    private void ExecuteIdleState()
    {
        // 空闲状态:站立不动,偶尔环顾四周
        
        // 一段时间后开始巡逻
        if (stateTimer >= idleDuration)
        {
            ChangeState(EnemyState.Patrol);
            return;
        }
        
        // 随机旋转以模拟环顾四周
        if (Random.value < 0.01f)
        {
            float randomRotation = Random.Range(-45f, 45f);
            transform.Rotate(0, randomRotation * Time.deltaTime * 10f, 0);
        }
        
        // 播放空闲动画
        enemyAnimator.SetBool("IsMoving", false);
    }

    private void ExecutePatrolState()
    {
        // 巡逻状态:在区域内移动
        
        // 计算到巡逻目标的距离
        float distanceToTarget = Vector3.Distance(transform.position, patrolTarget);
        
        if (distanceToTarget < 0.5f)
        {
            // 到达巡逻点,等待一段时间
            if (stateTimer >= patrolPointWaitTime)
            {
                SetNewPatrolTarget();
                stateTimer = 0f;
            }
            
            enemyAnimator.SetBool("IsMoving", false);
        }
        else
        {
            // 向巡逻目标移动
            Vector3 direction = (patrolTarget - transform.position).normalized;
            MoveInDirection(direction, moveSpeed);
            
            enemyAnimator.SetBool("IsMoving", true);
        }
        
        // 检查是否发现玩家
        if (PlayerInSight())
        {
            ChangeState(EnemyState.Chase);
        }
    }

    private void ExecuteChaseState()
    {
        if (playerTarget == null)
        {
            ChangeState(EnemyState.Patrol);
            return;
        }
        
        // 计算到玩家的距离
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        // 检查是否进入攻击范围
        if (distanceToPlayer <= attackRange)
        {
            ChangeState(EnemyState.Attack);
            return;
        }
        
        // 检查是否丢失玩家
        if (distanceToPlayer > detectionRange * 1.5f)
        {
            ChangeState(EnemyState.Patrol);
            return;
        }
        
        // 追逐玩家
        Vector3 directionToPlayer = (playerTarget.position - transform.position).normalized;
        MoveInDirection(directionToPlayer, chaseSpeed);
        
        enemyAnimator.SetBool("IsMoving", true);
        
        // 播放追逐声音(如果有)
        if (Random.value < 0.02f)
        {
            // PlayChaseSound();
        }
    }

    private void ExecuteAttackState()
    {
        if (playerTarget == null)
        {
            ChangeState(EnemyState.Patrol);
            return;
        }
        
        // 面向玩家
        Vector3 directionToPlayer = (playerTarget.position - transform.position).normalized;
        directionToPlayer.y = 0;
        
        if (directionToPlayer.magnitude > 0.1f)
        {
            Quaternion targetRotation = Quaternion.LookRotation(directionToPlayer);
            transform.rotation = Quaternion.Slerp(
                transform.rotation,
                targetRotation,
                10f * Time.deltaTime
            );
        }
        
        // 检查玩家是否仍在攻击范围内
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        
        if (distanceToPlayer > attackRange * 1.2f)
        {
            ChangeState(EnemyState.Chase);
            return;
        }
        
        // 执行攻击
        if (canAttack)
        {
            PerformAttack();
            canAttack = false;
            attackTimer = attackCooldown;
        }
        
        enemyAnimator.SetBool("IsMoving", false);
        enemyAnimator.SetBool("IsAttacking", !canAttack);
    }

    private void ExecuteRetreatState()
    {
        // 撤退状态:低生命值时返回安全位置
        
        float distanceToRetreatPoint = Vector3.Distance(transform.position, retreatPosition);
        
        if (distanceToRetreatPoint < 1f)
        {
            // 到达撤退点,进入空闲状态
            ChangeState(EnemyState.Idle);
            return;
        }
        
        // 向撤退点移动
        Vector3 direction = (retreatPosition - transform.position).normalized;
        MoveInDirection(direction, moveSpeed);
        
        enemyAnimator.SetBool("IsMoving", true);
        
        // 检查生命值是否恢复
        if (health > 50f)
        {
            ChangeState(EnemyState.Patrol);
        }
    }

    private void ExecuteDeadState()
    {
        // 死亡状态:播放死亡动画,然后销毁
        
        enemyAnimator.SetBool("IsDead", true);
        
        // 禁用控制器
        if (characterController != null)
        {
            characterController.enabled = false;
        }
        
        // 禁用碰撞器
        Collider collider = GetComponent<Collider>();
        if (collider != null)
        {
            collider.enabled = false;
        }
        
        // 一段时间后销毁
        if (stateTimer > 3f)
        {
            Destroy(gameObject);
        }
    }

    private void ChangeState(EnemyState newState)
    {
        if (currentState == newState)
        {
            return;
        }
        
        // 退出当前状态
        OnStateExit(currentState);
        
        // 更新状态
        EnemyState previousState = currentState;
        currentState = newState;
        stateTimer = 0f;
        
        // 进入新状态
        OnStateEnter(newState, previousState);
        
        Debug.Log($"状态变化: {previousState} -> {newState}");
    }

    private void OnStateEnter(EnemyState newState, EnemyState previousState)
    {
        // 状态进入时的处理
        switch (newState)
        {
            case EnemyState.Patrol:
                SetNewPatrolTarget();
                break;
                
            case EnemyState.Retreat:
                SetRetreatPosition();
                break;
                
            case EnemyState.Attack:
                canAttack = true; // 进入攻击状态时可以立即攻击
                break;
                
            case EnemyState.Dead:
                // 播放死亡声音
                // PlayDeathSound();
                
                // 掉落物品
                SpawnLoot();
                break;
        }
    }

    private void OnStateExit(EnemyState oldState)
    {
        // 状态退出时的处理
        switch (oldState)
        {
            case EnemyState.Attack:
                enemyAnimator.SetBool("IsAttacking", false);
                break;
        }
    }

    private void MoveInDirection(Vector3 direction, float speed)
    {
        if (characterController == null || !characterController.enabled)
        {
            return;
        }
        
        direction.y = 0;
        
        // 应用移动
        Vector3 moveVector = direction * speed * Time.deltaTime;
        characterController.Move(moveVector);
        
        // 旋转面向移动方向
        if (direction.magnitude > 0.1f)
        {
            Quaternion targetRotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.Slerp(
                transform.rotation,
                targetRotation,
                5f * Time.deltaTime
            );
        }
    }

    private void SetNewPatrolTarget()
    {
        // 在巡逻半径内随机选择新目标
        Vector2 randomCircle = Random.insideUnitCircle * patrolRadius;
        patrolTarget = spawnPosition + new Vector3(randomCircle.x, 0, randomCircle.y);
        
        // 确保目标在地面上
        RaycastHit hit;
        if (Physics.Raycast(patrolTarget + Vector3.up * 10f, Vector3.down, out hit, 20f))
        {
            patrolTarget = hit.point;
        }
    }

    private void SetRetreatPosition()
    {
        // 设置撤退位置(返回生成点)
        retreatPosition = spawnPosition;
    }

    private bool PlayerInSight()
    {
        if (playerTarget == null)
        {
            return false;
        }
        
        float distance = Vector3.Distance(transform.position, playerTarget.position);
        
        if (distance > detectionRange)
        {
            return false;
        }
        
        // 检查视线
        RaycastHit hit;
        Vector3 direction = playerTarget.position - transform.position;
        
        if (Physics.Raycast(
            transform.position + Vector3.up,
            direction.normalized,
            out hit,
            detectionRange
        ))
        {
            return hit.collider.CompareTag("Player");
        }
        
        return false;
    }

    private void PerformAttack()
    {
        // 执行攻击
        if (projectilePrefab != null && weaponMuzzle != null)
        {
            // 远程攻击:发射抛射物
            GameObject projectile = Instantiate(
                projectilePrefab,
                weaponMuzzle.position,
                weaponMuzzle.rotation
            );
            
            EnemyProjectile projectileScript = projectile.GetComponent<EnemyProjectile>();
            if (projectileScript != null)
            {
                projectileScript.damage = attackDamage;
            }
        }
        else
        {
            // 近战攻击:直接伤害
            if (playerTarget != null)
            {
                PlayerHealth playerHealth = playerTarget.GetComponent<PlayerHealth>();
                if (playerHealth != null)
                {
                    playerHealth.TakeDamage(attackDamage);
                }
            }
        }
        
        // 播放攻击动画
        enemyAnimator.SetTrigger("Attack");
        
        Debug.Log("敌人发动攻击,伤害: " + attackDamage);
    }

    private void UpdateAnimations()
    {
        if (enemyAnimator == null)
        {
            return;
        }
        
        // 设置状态参数
        enemyAnimator.SetInteger("State", (int)currentState);
        
        // 设置移动速度
        float speed = 0f;
        if (characterController != null)
        {
            speed = characterController.velocity.magnitude;
        }
        enemyAnimator.SetFloat("Speed", speed);
    }

    private void CheckGlobalConditions()
    {
        // 全局状态转换检查
        
        // 死亡检查
        if (health <= 0 && currentState != EnemyState.Dead)
        {
            ChangeState(EnemyState.Dead);
            return;
        }
        
        // 低生命值撤退
        if (health < 30f && currentState != EnemyState.Retreat && currentState != EnemyState.Dead)
        {
            ChangeState(EnemyState.Retreat);
            return;
        }
        
        // 玩家检测(除了撤退和死亡状态)
        if (currentState != EnemyState.Retreat && 
            currentState != EnemyState.Dead && 
            currentState != EnemyState.Chase && 
            currentState != EnemyState.Attack)
        {
            if (PlayerInSight())
            {
                ChangeState(EnemyState.Chase);
            }
        }
    }

    public void TakeDamage(float damage)
    {
        if (currentState == EnemyState.Dead)
        {
            return;
        }
        
        health -= damage;
        
        Debug.Log($"敌人受到伤害: {damage},剩余生命: {health}");
        
        // 如果受到伤害且不在战斗状态,开始追逐玩家
        if (currentState != EnemyState.Chase && 
            currentState != EnemyState.Attack && 
            currentState != EnemyState.Retreat)
        {
            ChangeState(EnemyState.Chase);
        }
    }

    private void SpawnLoot()
    {
        // 生成掉落物品
        // 在实际游戏中,这里会实例化掉落物预制体
        
        Debug.Log("敌人死亡,生成掉落物");
        
        // 示例:30%概率掉落生命值
        if (Random.value < 0.3f)
        {
            // Instantiate(healthPickupPrefab, transform.position, Quaternion.identity);
        }
    }

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }
        
        // 绘制检测范围
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, detectionRange);
        
        // 绘制攻击范围
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, attackRange);
        
        // 绘制巡逻半径
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(spawnPosition, patrolRadius);
        
        // 绘制当前目标
        switch (currentState)
        {
            case EnemyState.Patrol:
                Gizmos.color = Color.green;
                Gizmos.DrawLine(transform.position, patrolTarget);
                Gizmos.DrawWireSphere(patrolTarget, 0.3f);
                break;
                
            case EnemyState.Chase:
            case EnemyState.Attack:
                if (playerTarget != null)
                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawLine(transform.position, playerTarget.position);
                }
                break;
                
            case EnemyState.Retreat:
                Gizmos.color = Color.blue;
                Gizmos.DrawLine(transform.position, retreatPosition);
                Gizmos.DrawWireSphere(retreatPosition, 0.3f);
                break;
        }
        
        // 绘制状态信息
        #if UNITY_EDITOR
        string info = $"状态: {currentState}\n";
        info += $"生命: {health:F0}\n";
        info += $"计时: {stateTimer:F1}s";
        
        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 2f,
            info
        );
        #endif
    }
}

public class EnemyProjectile : MonoBehaviour
{
    public float damage = 10f;
    public float speed = 15f;
    public float lifetime = 3f;
    
    private void Start()
    {
        Destroy(gameObject, lifetime);
    }
    
    private void Update()
    {
        transform.position += transform.forward * speed * Time.deltaTime;
    }
    
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            PlayerHealth playerHealth = other.GetComponent<PlayerHealth>();
            if (playerHealth != null)
            {
                playerHealth.TakeDamage(damage);
            }
            
            Destroy(gameObject);
        }
        else if (!other.CompareTag("Enemy") && !other.CompareTag("Projectile"))
        {
            Destroy(gameObject);
        }
    }
}

6.2.2 Switch语句状态机的优化与扩展

虽然switch语句状态机简单直观,但随着状态数量的增加,代码会变得难以维护。下面介绍一些优化技巧和扩展方法,使switch语句状态机更适合中型项目:

using UnityEngine;
using System;
using System.Collections.Generic;

public class EnhancedSwitchFSM : MonoBehaviour
{
    public enum AIState
    {
        Idle,
        Patrol,
        Investigate,
        Chase,
        Attack,
        TakeCover,
        Reload,
        Heal,
        Dead
    }

    [System.Serializable]
    public class StateConfiguration
    {
        public AIState state;
        public float minDuration = 0f;
        public float maxDuration = Mathf.Infinity;
        public bool canBeInterrupted = true;
        public Color debugColor = Color.white;
    }

    [System.Serializable]
    public class TransitionCondition
    {
        public AIState fromState;
        public AIState toState;
        public Func<bool> condition;
        public int priority = 0;
    }

    [Header("状态配置")]
    [SerializeField]
    private List<StateConfiguration> stateConfigurations = new List<StateConfiguration>();

    [Header("当前状态")]
    [SerializeField]
    private AIState currentState = AIState.Idle;

    [SerializeField]
    private float timeInCurrentState = 0f;

    [Header("目标系统")]
    [SerializeField]
    private Transform primaryTarget;

    [SerializeField]
    private Vector3 lastKnownTargetPosition;

    [SerializeField]
    private float targetLastSeenTime;

    [Header("属性")]
    [SerializeField]
    private float health = 100f;

    [SerializeField]
    private float ammo = 30f;

    [SerializeField]
    private float stamina = 100f;

    [Header("感知")]
    [SerializeField]
    private float detectionRange = 15f;

    [SerializeField]
    private float hearingRange = 10f;

    [SerializeField]
    private float fieldOfView = 90f;

    private Dictionary<AIState, Action> stateEnterActions = new Dictionary<AIState, Action>();
    private Dictionary<AIState, Action> stateUpdateActions = new Dictionary<AIState, Action>();
    private Dictionary<AIState, Action> stateExitActions = new Dictionary<AIState, Action>();
    
    private List<TransitionCondition> transitionConditions = new List<TransitionCondition>();
    
    private CharacterController characterController;
    private Animator animator;
    private StateConfiguration currentStateConfig;

    private void Awake()
    {
        InitializeEnhancedFSM();
    }

    private void InitializeEnhancedFSM()
    {
        characterController = GetComponent<CharacterController>();
        animator = GetComponent<Animator>();
        
        if (primaryTarget == null)
        {
            GameObject player = GameObject.FindGameObjectWithTag("Player");
            if (player != null)
            {
                primaryTarget = player.transform;
            }
        }
        
        // 初始化状态配置
        InitializeStateConfigurations();
        
        // 注册状态行为
        RegisterStateBehaviors();
        
        // 注册转换条件
        RegisterTransitionConditions();
        
        // 设置初始状态
        ChangeState(AIState.Idle);
        
        Debug.Log("增强型FSM初始化完成");
    }

    private void InitializeStateConfigurations()
    {
        // 清除现有配置
        stateConfigurations.Clear();
        
        // 添加默认状态配置
        AddStateConfiguration(AIState.Idle, 2f, 5f, true, Color.gray);
        AddStateConfiguration(AIState.Patrol, 3f, 10f, true, Color.green);
        AddStateConfiguration(AIState.Investigate, 2f, 8f, true, Color.yellow);
        AddStateConfiguration(AIState.Chase, 1f, 15f, true, Color.red);
        AddStateConfiguration(AIState.Attack, 0.5f, 3f, false, Color.magenta);
        AddStateConfiguration(AIState.TakeCover, 1f, 5f, false, Color.blue);
        AddStateConfiguration(AIState.Reload, 1f, 2f, false, Color.cyan);
        AddStateConfiguration(AIState.Heal, 2f, 4f, false, new Color(0, 1, 0, 1));
        AddStateConfiguration(AIState.Dead, Mathf.Infinity, Mathf.Infinity, false, Color.black);
    }

    private void AddStateConfiguration(AIState state, float minDur, float maxDur, bool interruptible, Color color)
    {
        StateConfiguration config = new StateConfiguration
        {
            state = state,
            minDuration = minDur,
            maxDuration = maxDur,
            canBeInterrupted = interruptible,
            debugColor = color
        };
        
        stateConfigurations.Add(config);
    }

    private void RegisterStateBehaviors()
    {
        // 注册状态进入行为
        stateEnterActions[AIState.Idle] = OnEnterIdle;
        stateEnterActions[AIState.Patrol] = OnEnterPatrol;
        stateEnterActions[AIState.Investigate] = OnEnterInvestigate;
        stateEnterActions[AIState.Chase] = OnEnterChase;
        stateEnterActions[AIState.Attack] = OnEnterAttack;
        stateEnterActions[AIState.TakeCover] = OnEnterTakeCover;
        stateEnterActions[AIState.Reload] = OnEnterReload;
        stateEnterActions[AIState.Heal] = OnEnterHeal;
        stateEnterActions[AIState.Dead] = OnEnterDead;
        
        // 注册状态更新行为
        stateUpdateActions[AIState.Idle] = OnUpdateIdle;
        stateUpdateActions[AIState.Patrol] = OnUpdatePatrol;
        stateUpdateActions[AIState.Investigate] = OnUpdateInvestigate;
        stateUpdateActions[AIState.Chase] = OnUpdateChase;
        stateUpdateActions[AIState.Attack] = OnUpdateAttack;
        stateUpdateActions[AIState.TakeCover] = OnUpdateTakeCover;
        stateUpdateActions[AIState.Reload] = OnUpdateReload;
        stateUpdateActions[AIState.Heal] = OnUpdateHeal;
        stateUpdateActions[AIState.Dead] = OnUpdateDead;
        
        // 注册状态退出行为
        stateExitActions[AIState.Idle] = OnExitIdle;
        stateExitActions[AIState.Patrol] = OnExitPatrol;
        stateExitActions[AIState.Investigate] = OnExitInvestigate;
        stateExitActions[AIState.Chase] = OnExitChase;
        stateExitActions[AIState.Attack] = OnExitAttack;
        stateExitActions[AIState.TakeCover] = OnExitTakeCover;
        stateExitActions[AIState.Reload] = OnExitReload;
        stateExitActions[AIState.Heal] = OnExitHeal;
        stateExitActions[AIState.Dead] = OnExitDead;
    }

    private void RegisterTransitionConditions()
    {
        // 注册状态转换条件
        
        // 空闲 -> 巡逻
        AddTransitionCondition(AIState.Idle, AIState.Patrol, 
            () => timeInCurrentState > currentStateConfig.minDuration, 1);
        
        // 巡逻 -> 调查(听到声音)
        AddTransitionCondition(AIState.Patrol, AIState.Investigate,
            () => HeardSuspiciousSound(), 2);
        
        // 巡逻/空闲 -> 追逐(看到目标)
        AddTransitionCondition(AIState.Patrol, AIState.Chase,
            () => TargetInSight(), 3);
        AddTransitionCondition(AIState.Idle, AIState.Chase,
            () => TargetInSight(), 3);
        
        // 调查 -> 追逐(看到目标)
        AddTransitionCondition(AIState.Investigate, AIState.Chase,
            () => TargetInSight(), 3);
        
        // 追逐 -> 攻击(在攻击范围内)
        AddTransitionCondition(AIState.Chase, AIState.Attack,
            () => TargetInAttackRange() && TargetInSight(), 4);
        
        // 攻击 -> 寻找掩护(生命值低)
        AddTransitionCondition(AIState.Attack, AIState.TakeCover,
            () => health < 30f, 5);
        
        // 攻击 -> 重新装弹(弹药不足)
        AddTransitionCondition(AIState.Attack, AIState.Reload,
            () => ammo < 5f, 5);
        
        // 任何状态 -> 治疗(生命值很低且有治疗包)
        AddTransitionCondition(AIState.Attack, AIState.Heal,
            () => health < 20f && HasHealthPack(), 6);
        AddTransitionCondition(AIState.Chase, AIState.Heal,
            () => health < 20f && HasHealthPack(), 6);
        
        // 任何状态 -> 死亡(生命值<=0)
        foreach (AIState state in Enum.GetValues(typeof(AIState)))
        {
            if (state != AIState.Dead)
            {
                AddTransitionCondition(state, AIState.Dead,
                    () => health <= 0f, 10);
            }
        }
    }

    private void AddTransitionCondition(AIState fromState, AIState toState, Func<bool> condition, int priority)
    {
        TransitionCondition transition = new TransitionCondition
        {
            fromState = fromState,
            toState = toState,
            condition = condition,
            priority = priority
        };
        
        transitionConditions.Add(transition);
    }

    private void Update()
    {
        // 更新状态计时器
        timeInCurrentState += Time.deltaTime;
        
        // 检查状态转换
        CheckStateTransitions();
        
        // 执行当前状态更新
        ExecuteCurrentState();
        
        // 更新动画
        UpdateAnimations();
    }

    private void CheckStateTransitions()
    {
        if (currentStateConfig == null || !currentStateConfig.canBeInterrupted)
        {
            return;
        }
        
        // 检查最小持续时间
        if (timeInCurrentState < currentStateConfig.minDuration)
        {
            return;
        }
        
        // 检查最大持续时间
        if (timeInCurrentState > currentStateConfig.maxDuration)
        {
            // 强制转换到适当的状态
            switch (currentState)
            {
                case AIState.Idle:
                case AIState.Patrol:
                    ChangeState(AIState.Idle);
                    break;
                    
                case AIState.Investigate:
                    ChangeState(AIState.Patrol);
                    break;
                    
                case AIState.Chase:
                    ChangeState(AIState.Investigate);
                    break;
                    
                case AIState.Attack:
                    ChangeState(AIState.TakeCover);
                    break;
            }
            return;
        }
        
        // 查找符合条件的转换(按优先级排序)
        List<TransitionCondition> validTransitions = new List<TransitionCondition>();
        
        foreach (TransitionCondition transition in transitionConditions)
        {
            if (transition.fromState == currentState && transition.condition())
            {
                validTransitions.Add(transition);
            }
        }
        
        // 选择优先级最高的转换
        if (validTransitions.Count > 0)
        {
            validTransitions.Sort((a, b) => b.priority.CompareTo(a.priority));
            ChangeState(validTransitions[0].toState);
        }
    }

    private void ExecuteCurrentState()
    {
        // 执行当前状态的更新逻辑
        if (stateUpdateActions.ContainsKey(currentState))
        {
            stateUpdateActions[currentState]();
        }
    }

    private void ChangeState(AIState newState)
    {
        if (currentState == newState)
        {
            return;
        }
        
        // 执行退出当前状态的行为
        if (stateExitActions.ContainsKey(currentState))
        {
            stateExitActions[currentState]();
        }
        
        AIState previousState = currentState;
        currentState = newState;
        timeInCurrentState = 0f;
        
        // 获取新状态的配置
        currentStateConfig = stateConfigurations.Find(c => c.state == newState);
        
        // 执行进入新状态的行为
        if (stateEnterActions.ContainsKey(newState))
        {
            stateEnterActions[newState]();
        }
        
        Debug.Log($"状态转换: {previousState} -> {newState}");
        
        // 触发状态变化事件
        OnStateChanged?.Invoke(previousState, newState);
    }

    #region 状态行为实现

    private void OnEnterIdle()
    {
        animator.SetBool("IsMoving", false);
        Debug.Log("进入空闲状态");
    }

    private void OnUpdateIdle()
    {
        // 空闲状态:缓慢旋转,偶尔移动位置
        if (Random.value < 0.01f)
        {
            transform.Rotate(0, Random.Range(-30f, 30f), 0);
        }
    }

    private void OnExitIdle()
    {
        Debug.Log("离开空闲状态");
    }

    private void OnEnterPatrol()
    {
        animator.SetBool("IsMoving", true);
        Debug.Log("进入巡逻状态");
    }

    private void OnUpdatePatrol()
    {
        // 巡逻逻辑
        // 这里应该实现实际的巡逻路径
        if (characterController != null)
        {
            Vector3 moveDirection = transform.forward;
            characterController.Move(moveDirection * 3f * Time.deltaTime);
        }
    }

    private void OnExitPatrol()
    {
        Debug.Log("离开巡逻状态");
    }

    private void OnEnterInvestigate()
    {
        animator.SetBool("IsMoving", true);
        Debug.Log("进入调查状态,前往: " + lastKnownTargetPosition);
    }

    private void OnUpdateInvestigate()
    {
        // 前往最后已知位置
        if (characterController != null && lastKnownTargetPosition != Vector3.zero)
        {
            Vector3 direction = (lastKnownTargetPosition - transform.position).normalized;
            characterController.Move(direction * 4f * Time.deltaTime);
            
            // 面向移动方向
            if (direction.magnitude > 0.1f)
            {
                Quaternion targetRotation = Quaternion.LookRotation(direction);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 5f * Time.deltaTime);
            }
            
            // 检查是否到达调查点
            if (Vector3.Distance(transform.position, lastKnownTargetPosition) < 1f)
            {
                // 环顾四周
                transform.Rotate(0, 45f * Time.deltaTime, 0);
            }
        }
    }

    private void OnExitInvestigate()
    {
        Debug.Log("离开调查状态");
    }

    private void OnEnterChase()
    {
        animator.SetBool("IsMoving", true);
        animator.SetBool("IsRunning", true);
        Debug.Log("进入追逐状态");
    }

    private void OnUpdateChase()
    {
        if (primaryTarget == null)
        {
            return;
        }
        
        // 追逐目标
        Vector3 direction = (primaryTarget.position - transform.position).normalized;
        
        if (characterController != null)
        {
            characterController.Move(direction * 6f * Time.deltaTime);
            
            // 面向目标
            if (direction.magnitude > 0.1f)
            {
                Quaternion targetRotation = Quaternion.LookRotation(direction);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 10f * Time.deltaTime);
            }
        }
    }

    private void OnExitChase()
    {
        animator.SetBool("IsRunning", false);
        Debug.Log("离开追逐状态");
    }

    private void OnEnterAttack()
    {
        animator.SetBool("IsAttacking", true);
        Debug.Log("进入攻击状态");
    }

    private void OnUpdateAttack()
    {
        if (primaryTarget == null)
        {
            return;
        }
        
        // 面向目标
        Vector3 direction = (primaryTarget.position - transform.position).normalized;
        direction.y = 0;
        
        if (direction.magnitude > 0.1f)
        {
            Quaternion targetRotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 15f * Time.deltaTime);
        }
        
        // 执行攻击逻辑
        if (timeInCurrentState > 0.5f && ammo > 0)
        {
            // 模拟攻击
            ammo--;
            Debug.Log($"攻击!剩余弹药: {ammo}");
            
            // 重置计时器以模拟攻击间隔
            timeInCurrentState = 0f;
        }
    }

    private void OnExitAttack()
    {
        animator.SetBool("IsAttacking", false);
        Debug.Log("离开攻击状态");
    }

    private void OnEnterTakeCover()
    {
        animator.SetBool("IsCrouching", true);
        Debug.Log("进入寻找掩护状态");
    }

    private void OnUpdateTakeCover()
    {
        // 寻找最近的掩护位置
        // 简化实现:移动到固定位置
        Vector3 coverPosition = transform.position - transform.forward * 2f;
        
        if (characterController != null)
        {
            Vector3 direction = (coverPosition - transform.position).normalized;
            characterController.Move(direction * 2f * Time.deltaTime);
        }
        
        // 蹲下
        if (characterController != null)
        {
            characterController.height = Mathf.Lerp(characterController.height, 1f, 5f * Time.deltaTime);
        }
    }

    private void OnExitTakeCover()
    {
        animator.SetBool("IsCrouching", false);
        
        // 恢复站立高度
        if (characterController != null)
        {
            characterController.height = 2f;
        }
        
        Debug.Log("离开寻找掩护状态");
    }

    private void OnEnterReload()
    {
        animator.SetTrigger("Reload");
        Debug.Log("进入重新装弹状态");
    }

    private void OnUpdateReload()
    {
        // 装弹动画播放中...
        // 完成后自动返回适当状态
    }

    private void OnExitReload()
    {
        // 完成装弹
        ammo = 30f;
        Debug.Log("离开重新装弹状态,弹药已装满");
    }

    private void OnEnterHeal()
    {
        animator.SetTrigger("Heal");
        Debug.Log("进入治疗状态");
    }

    private void OnUpdateHeal()
    {
        // 治疗中...
        health = Mathf.Min(100f, health + 20f * Time.deltaTime);
    }

    private void OnExitHeal()
    {
        Debug.Log("离开治疗状态,当前生命值: " + health);
    }

    private void OnEnterDead()
    {
        animator.SetTrigger("Die");
        
        if (characterController != null)
        {
            characterController.enabled = false;
        }
        
        Debug.Log("进入死亡状态");
    }

    private void OnUpdateDead()
    {
        // 死亡状态不需要更新逻辑
    }

    private void OnExitDead()
    {
        // 死亡状态不会退出
    }

    #endregion

    #region 条件检查方法

    private bool TargetInSight()
    {
        if (primaryTarget == null)
        {
            return false;
        }
        
        float distance = Vector3.Distance(transform.position, primaryTarget.position);
        
        if (distance > detectionRange)
        {
            return false;
        }
        
        // 检查是否在视野内
        Vector3 directionToTarget = (primaryTarget.position - transform.position).normalized;
        float angleToTarget = Vector3.Angle(transform.forward, directionToTarget);
        
        if (angleToTarget > fieldOfView / 2)
        {
            return false;
        }
        
        // 检查视线遮挡
        RaycastHit hit;
        if (Physics.Raycast(
            transform.position + Vector3.up,
            directionToTarget,
            out hit,
            detectionRange
        ))
        {
            return hit.collider.transform == primaryTarget;
        }
        
        return false;
    }

    private bool TargetInAttackRange()
    {
        if (primaryTarget == null)
        {
            return false;
        }
        
        float distance = Vector3.Distance(transform.position, primaryTarget.position);
        return distance < 5f; // 攻击范围
    }

    private bool HeardSuspiciousSound()
    {
        // 检查是否听到可疑声音
        // 简化实现:随机决定
        return Random.value < 0.05f;
    }

    private bool HasHealthPack()
    {
        // 检查是否有治疗包
        // 简化实现:随机决定
        return Random.value < 0.7f;
    }

    #endregion

    private void UpdateAnimations()
    {
        if (animator == null)
        {
            return;
        }
        
        // 设置移动速度
        float speed = 0f;
        if (characterController != null)
        {
            speed = characterController.velocity.magnitude;
        }
        
        animator.SetFloat("Speed", speed);
        
        // 设置生命值比例
        animator.SetFloat("Health", health / 100f);
    }

    public void TakeDamage(float damage, GameObject damageSource)
    {
        if (currentState == AIState.Dead)
        {
            return;
        }
        
        health -= damage;
        
        Debug.Log($"受到伤害: {damage},剩余生命: {health}");
        
        // 记录伤害来源位置
        if (damageSource != null)
        {
            lastKnownTargetPosition = damageSource.transform.position;
            targetLastSeenTime = Time.time;
        }
        
        // 如果受到攻击且不在战斗状态,开始调查或追逐
        if (currentState != AIState.Chase && 
            currentState != AIState.Attack && 
            currentState != AIState.Investigate)
        {
            if (damageSource != null && damageSource.CompareTag("Player"))
            {
                ChangeState(AIState.Chase);
            }
            else
            {
                ChangeState(AIState.Investigate);
            }
        }
    }

    public void OnSoundHeard(Vector3 soundPosition, float soundIntensity)
    {
        if (currentState == AIState.Dead)
        {
            return;
        }
        
        // 记录声音位置
        lastKnownTargetPosition = soundPosition;
        targetLastSeenTime = Time.time;
        
        // 如果不是在战斗状态,前往调查
        if (currentState != AIState.Chase && 
            currentState != AIState.Attack && 
            currentState != AIState.Investigate)
        {
            ChangeState(AIState.Investigate);
        }
    }

    public AIState CurrentState
    {
        get { return currentState; }
    }

    public float Health
    {
        get { return health; }
    }

    public event Action<AIState, AIState> OnStateChanged;

    private void OnDrawGizmosSelected()
    {
        if (!Application.isPlaying)
        {
            return;
        }
        
        // 绘制状态相关可视化
        if (currentStateConfig != null)
        {
            Gizmos.color = currentStateConfig.debugColor;
            
            // 绘制状态范围
            float radius = 0f;
            
            switch (currentState)
            {
                case AIState.Idle:
                    radius = 1f;
                    break;
                    
                case AIState.Patrol:
                    radius = 2f;
                    break;
                    
                case AIState.Investigate:
                    radius = 3f;
                    Gizmos.DrawWireSphere(lastKnownTargetPosition, 0.5f);
                    Gizmos.DrawLine(transform.position, lastKnownTargetPosition);
                    break;
                    
                case AIState.Chase:
                case AIState.Attack:
                    radius = 4f;
                    if (primaryTarget != null)
                    {
                        Gizmos.DrawLine(transform.position, primaryTarget.position);
                    }
                    break;
            }
            
            Gizmos.DrawWireSphere(transform.position, radius);
        }
        
        // 绘制检测范围
        Gizmos.color = new Color(1, 1, 0, 0.3f);
        Gizmos.DrawWireSphere(transform.position, detectionRange);
        
        // 绘制视野锥
        DrawFieldOfViewGizmo();
        
        // 绘制状态信息
        #if UNITY_EDITOR
        string info = $"状态: {currentState}\n";
        info += $"时间: {timeInCurrentState:F1}s\n";
        info += $"生命: {health:F0}\n";
        info += $"弹药: {ammo:F0}";
        
        UnityEditor.Handles.Label(
            transform.position + Vector3.up * 2.5f,
            info
        );
        #endif
    }

    private void DrawFieldOfViewGizmo()
    {
        Gizmos.color = new Color(1, 1, 0, 0.2f);
        
        int segments = 10;
        float stepAngle = fieldOfView / segments;
        float halfFov = fieldOfView / 2;
        float range = detectionRange;
        
        Vector3 forward = transform.forward * range;
        
        for (int i = 0; i <= segments; i++)
        {
            float angle = -halfFov + (stepAngle * i);
            Vector3 direction = Quaternion.Euler(0, angle, 0) * forward;
            Vector3 point = transform.position + direction;
            
            Gizmos.DrawLine(transform.position, point);
            
            if (i > 0)
            {
                Vector3 prevDirection = Quaternion.Euler(0, -halfFov + (stepAngle * (i - 1)), 0) * forward;
                Vector3 prevPoint = transform.position + prevDirection;
                Gizmos.DrawLine(prevPoint, point);
            }
        }
    }
}

这个增强的switch语句状态机通过配置系统和条件注册机制,大大提高了代码的可维护性和扩展性。它适合中等复杂度的AI系统,在保持简单性的同时提供了足够的灵活性。

6.3 通用FSM框架的设计与实现

6.3.1 面向对象的状态机框架设计

对于大型商业项目,一个可扩展、可维护的通用FSM框架是必不可少的。这种框架应该支持以下特性:

  1. 状态和转换的模块化设计
  2. 状态间的数据传递
  3. 层级状态机(HFSM)
  4. 并行状态机
  5. 状态历史记录和回退

下面是一个完整的通用FSM框架实现:

using UnityEngine;
using System;
using System.Collections.Generic;

namespace AdvancedFSM
{
    /// <summary>
    /// 状态接口
    /// </summary>
    public interface IState
    {
        string StateId { get; }
        void OnEnter();
        void OnUpdate(float deltaTime);
        void OnExit();
        void OnPause();
        void OnResume();
    }

    /// <summary>
    /// 状态转换条件
    /// </summary>
    public interface ITransitionCondition
    {
        bool IsMet();
        int Priority { get; }
    }

    /// <summary>
    /// 状态转换
    /// </summary>
    public class StateTransition
    {
        public string FromStateId { get; private set; }
        public string ToStateId { get; private set; }
        public ITransitionCondition Condition { get; private set; }
        public Action OnTransition { get; private set; }
        
        public StateTransition(string fromStateId, string toStateId, 
            ITransitionCondition condition, Action onTransition = null)
        {
            FromStateId = fromStateId;
            ToStateId = toStateId;
            Condition = condition;
            OnTransition = onTransition;
        }
    }

    /// <summary>
    /// 高级有限状态机
    /// </summary>
    public class AdvancedFiniteStateMachine
    {
        private Dictionary<string, IState> states = new Dictionary<string, IState>();
        private List<StateTransition> transitions = new List<StateTransition>();
        private List<StateTransition> anyTransitions = new List<StateTransition>();
        
        private IState currentState;
        private IState previousState;
        private IState defaultState;
        
        private Stack<IState> stateHistory = new Stack<IState>();
        private int maxHistorySize = 10;
        
        private bool isPaused = false;
        private float timeInCurrentState = 0f;
        
        public IState CurrentState 
        { 
            get { return currentState; } 
        }
        
        public IState PreviousState 
        { 
            get { return previousState; } 
        }
        
        public float TimeInCurrentState 
        { 
            get { return timeInCurrentState; } 
        }
        
        public event Action<IState, IState> OnStateChanged;
        public event Action<string> OnTransitionTriggered;
        
        /// <summary>
        /// 添加状态
        /// </summary>
        public void AddState(IState state, bool isDefault = false)
        {
            if (states.ContainsKey(state.StateId))
            {
                Debug.LogWarning($"状态已存在: {state.StateId}");
                return;
            }
            
            states.Add(state.StateId, state);
            
            if (isDefault)
            {
                defaultState = state;
            }
        }
        
        /// <summary>
        /// 添加状态转换
        /// </summary>
        public void AddTransition(string fromStateId, string toStateId, 
            ITransitionCondition condition, Action onTransition = null)
        {
            transitions.Add(new StateTransition(fromStateId, toStateId, condition, onTransition));
        }
        
        /// <summary>
        /// 添加从任意状态转换
        /// </summary>
        public void AddAnyTransition(string toStateId, ITransitionCondition condition, Action onTransition = null)
        {
            anyTransitions.Add(new StateTransition(null, toStateId, condition, onTransition));
        }
        
        /// <summary>
        /// 初始化状态机
        /// </summary>
        public void Initialize()
        {
            if (defaultState != null)
            {
                ChangeState(defaultState);
            }
            else if (states.Count > 0)
            {
                // 使用第一个状态作为默认状态
                using (var enumerator = states.Values.GetEnumerator())
                {
                    if (enumerator.MoveNext())
                    {
                        ChangeState(enumerator.Current);
                    }
                }
            }
        }
        
        /// <summary>
        /// 更新状态机
        /// </summary>
        public void Update(float deltaTime)
        {
            if (isPaused || currentState == null)
            {
                return;
            }
            
            // 更新当前状态时间
            timeInCurrentState += deltaTime;
            
            // 更新当前状态
            currentState.OnUpdate(deltaTime);
            
            // 检查状态转换
            CheckTransitions();
        }
        
        /// <summary>
        /// 强制改变状态
        /// </summary>
        public void ChangeState(string stateId, bool recordHistory = true)
        {
            if (!states.ContainsKey(stateId))
            {
                Debug.LogError($"状态不存在: {stateId}");
                return;
            }
            
            ChangeState(states[stateId], recordHistory);
        }
        
        /// <summary>
        /// 强制改变状态
        /// </summary>
        public void ChangeState(IState newState, bool recordHistory = true)
        {
            if (currentState == newState)
            {
                return;
            }
            
            // 暂停当前状态
            if (currentState != null)
            {
                currentState.OnPause();
                currentState.OnExit();
                
                // 记录状态历史
                if (recordHistory && currentState != newState)
                {
                    stateHistory.Push(currentState);
                    
                    // 限制历史记录大小
                    if (stateHistory.Count > maxHistorySize)
                    {
                        // 移除最旧的状态
                        Stack<IState> temp = new Stack<IState>();
                        while (stateHistory.Count > 1)
                        {
                            temp.Push(stateHistory.Pop());
                        }
                        stateHistory = temp;
                    }
                }
            }
            
            // 更新状态引用
            previousState = currentState;
            currentState = newState;
            timeInCurrentState = 0f;
            
            // 进入新状态
            currentState.OnEnter();
            
            // 触发事件
            OnStateChanged?.Invoke(previousState, currentState);
            
            Debug.Log($"状态改变: {previousState?.StateId ?? "None"} -> {currentState.StateId}");
        }
        
        /// <summary>
        /// 返回上一个状态
        /// </summary>
        public bool RevertToPreviousState()
        {
            if (stateHistory.Count == 0)
            {
                return false;
            }
            
            IState previous = stateHistory.Pop();
            ChangeState(previous, false); // 不记录历史,避免循环
            
            return true;
        }
        
        /// <summary>
        /// 暂停状态机
        /// </summary>
        public void Pause()
        {
            if (isPaused)
            {
                return;
            }
            
            isPaused = true;
            currentState?.OnPause();
        }
        
        /// <summary>
        /// 恢复状态机
        /// </summary>
        public void Resume()
        {
            if (!isPaused)
            {
                return;
            }
            
            isPaused = false;
            currentState?.OnResume();
        }
        
        /// <summary>
        /// 重置状态机
        /// </summary>
        public void Reset()
        {
            if (defaultState != null)
            {
                ChangeState(defaultState);
            }
            
            stateHistory.Clear();
            timeInCurrentState = 0f;
            isPaused = false;
        }
        
        /// <summary>
        /// 获取指定状态
        /// </summary>
        public IState GetState(string stateId)
        {
            return states.ContainsKey(stateId) ? states[stateId] : null;
        }
        
        /// <summary>
        /// 检查是否处于指定状态
        /// </summary>
        public bool IsInState(string stateId)
        {
            return currentState != null && currentState.StateId == stateId;
        }
        
        /// <summary>
        /// 获取状态历史
        /// </summary>
        public List<string> GetStateHistory()
        {
            List<string> history = new List<string>();
            foreach (IState state in stateHistory)
            {
                history.Add(state.StateId);
            }
            return history;
        }
        
        private void CheckTransitions()
        {
            // 首先检查从任意状态的转换
            foreach (StateTransition transition in anyTransitions)
            {
                if (transition.Condition.IsMet())
                {
                    ExecuteTransition(transition);
                    return;
                }
            }
            
            // 然后检查从当前状态的转换
            foreach (StateTransition transition in transitions)
            {
                if (transition.FromStateId == currentState.StateId && transition.Condition.IsMet())
                {
                    ExecuteTransition(transition);
                    return;
                }
            }
        }
        
        private void ExecuteTransition(StateTransition transition)
        {
            if (!states.ContainsKey(transition.ToStateId))
            {
                Debug.LogError($"目标状态不存在: {transition.ToStateId}");
                return;
            }
            
            // 执行转换回调
            transition.OnTransition?.Invoke();
            
            // 触发转换事件
            OnTransitionTriggered?.Invoke($"{transition.FromStateId ?? "Any"} -> {transition.ToStateId}");
            
            // 改变状态
            ChangeState(states[transition.ToStateId]);
        }
    }

    /// <summary>
    /// 基础状态类
    /// </summary>
    public abstract class BaseState : IState
    {
        public abstract string StateId { get; }
        
        protected GameObject owner;
        protected AdvancedFiniteStateMachine fsm;
        
        public BaseState(GameObject owner, AdvancedFiniteStateMachine fsm)
        {
            this.owner = owner;
            this.fsm = fsm;
        }
        
        public virtual void OnEnter() { }
        public virtual void OnUpdate(float deltaTime) { }
        public virtual void OnExit() { }
        public virtual void OnPause() { }
        public virtual void OnResume() { }
    }

    /// <summary>
    /// 基础转换条件类
    /// </summary>
    public abstract class BaseTransitionCondition : ITransitionCondition
    {
        public abstract bool IsMet();
        public virtual int Priority { get { return 0; } }
    }

    /// <summary>
    /// 延迟条件
    /// </summary>
    public class DelayCondition : BaseTransitionCondition
    {
        private float delayDuration;
        private float elapsedTime;
        private bool isActive;
        
        public DelayCondition(float duration)
        {
            delayDuration = duration;
            elapsedTime = 0f;
            isActive = false;
        }
        
        public void Start()
        {
            isActive = true;
            elapsedTime = 0f;
        }
        
        public void Reset()
        {
            isActive = false;
            elapsedTime = 0f;
        }
        
        public override bool IsMet()
        {
            if (!isActive)
            {
                return false;
            }
            
            elapsedTime += Time.deltaTime;
            return elapsedTime >= delayDuration;
        }
    }

    /// <summary>
    /// 布尔条件
    /// </summary>
    public class BoolCondition : BaseTransitionCondition
    {
        private Func<bool> conditionFunc;
        private int priority;
        
        public BoolCondition(Func<bool> condition, int priority = 0)
        {
            conditionFunc = condition;
            this.priority = priority;
        }
        
        public override bool IsMet()
        {
            return conditionFunc();
        }
        
        public override int Priority
        {
            get { return priority; }
        }
    }

    /// <summary>
    /// 数值条件
    /// </summary>
    public class ValueCondition<T> : BaseTransitionCondition where T : IComparable<T>
    {
        public enum ComparisonType
        {
            LessThan,
            LessThanOrEqual,
            Equal,
            GreaterThanOrEqual,
            GreaterThan,
            NotEqual
        }
        
        private Func<T> valueGetter;
        private T threshold;
        private ComparisonType comparison;
        private int priority;
        
        public ValueCondition(Func<T> valueGetter, T threshold, 
            ComparisonType comparison, int priority = 0)
        {
            this.valueGetter = valueGetter;
            this.threshold = threshold;
            this.comparison = comparison;
            this.priority = priority;
        }
        
        public override bool IsMet()
        {
            T currentValue = valueGetter();
            int comparisonResult = currentValue.CompareTo(threshold);
            
            switch (comparison)
            {
                case ComparisonType.LessThan:
                    return comparisonResult < 0;
                    
                case ComparisonType.LessThanOrEqual:
                    return comparisonResult <= 0;
                    
                case ComparisonType.Equal:
                    return comparisonResult == 0;
                    
                case ComparisonType.GreaterThanOrEqual:
                    return comparisonResult >= 0;
                    
                case ComparisonType.GreaterThan:
                    return comparisonResult > 0;
                    
                case ComparisonType.NotEqual:
                    return comparisonResult != 0;
                    
                default:
                    return false;
            }
        }
        
        public override int Priority
        {
            get { return priority; }
        }
    }
}

// 使用示例:AI巡逻状态
namespace AdvancedFSM.Example
{
    /// <summary>
    /// 巡逻状态
    /// </summary>
    public class PatrolState : AdvancedFSM.BaseState
    {
        private Transform transform;
        private CharacterController characterController;
        private Animator animator;
        
        private Vector3[] patrolPoints;
        private int currentPatrolIndex = 0;
        private float moveSpeed = 3f;
        private float rotationSpeed = 5f;
        private float waitTimeAtPoint = 2f;
        private float waitTimer = 0f;
        private bool isWaiting = false;
        
        public override string StateId 
        { 
            get { return "Patrol"; } 
        }
        
        public PatrolState(GameObject owner, AdvancedFiniteStateMachine fsm) 
            : base(owner, fsm)
        {
            transform = owner.transform;
            characterController = owner.GetComponent<CharacterController>();
            animator = owner.GetComponent<Animator>();
            
            // 初始化巡逻点
            InitializePatrolPoints();
        }
        
        private void InitializePatrolPoints()
        {
            // 在实际项目中,巡逻点可能来自关卡设计或动态生成
            patrolPoints = new Vector3[]
            {
                transform.position + new Vector3(5, 0, 0),
                transform.position + new Vector3(5, 0, 5),
                transform.position + new Vector3(0, 0, 5),
                transform.position + new Vector3(-5, 0, 5),
                transform.position + new Vector3(-5, 0, 0),
                transform.position + new Vector3(-5, 0, -5),
                transform.position + new Vector3(0, 0, -5),
                transform.position + new Vector3(5, 0, -5)
            };
        }
        
        public override void OnEnter()
        {
            Debug.Log("进入巡逻状态");
            
            if (animator != null)
            {
                animator.SetBool("IsWalking", true);
                animator.SetBool("IsRunning", false);
            }
            
            isWaiting = false;
            waitTimer = 0f;
            currentPatrolIndex = 0;
            
            MoveToNextPatrolPoint();
        }
        
        public override void OnUpdate(float deltaTime)
        {
            if (isWaiting)
            {
                // 在巡逻点等待
                waitTimer += deltaTime;
                
                if (waitTimer >= waitTimeAtPoint)
                {
                    isWaiting = false;
                    MoveToNextPatrolPoint();
                }
                
                // 等待时环顾四周
                transform.Rotate(0, 30f * deltaTime, 0);
            }
            else
            {
                // 移动到当前巡逻点
                Vector3 targetPoint = patrolPoints[currentPatrolIndex];
                Vector3 direction = (targetPoint - transform.position).normalized;
                
                // 移动
                if (characterController != null)
                {
                    characterController.Move(direction * moveSpeed * deltaTime);
                }
                else
                {
                    transform.position += direction * moveSpeed * deltaTime;
                }
                
                // 旋转面向移动方向
                if (direction.magnitude > 0.1f)
                {
                    Quaternion targetRotation = Quaternion.LookRotation(direction);
                    transform.rotation = Quaternion.Slerp(
                        transform.rotation, 
                        targetRotation, 
                        rotationSpeed * deltaTime
                    );
                }
                
                // 检查是否到达巡逻点
                float distanceToTarget = Vector3.Distance(transform.position, targetPoint);
                if (distanceToTarget < 0.5f)
                {
                    StartWaiting();
                }
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出巡逻状态");
            
            if (animator != null)
            {
                animator.SetBool("IsWalking", false);
            }
        }
        
        private void MoveToNextPatrolPoint()
        {
            currentPatrolIndex = (currentPatrolIndex + 1) % patrolPoints.Length;
        }
        
        private void StartWaiting()
        {
            isWaiting = true;
            waitTimer = 0f;
        }
    }

    /// <summary>
    /// 追逐状态
    /// </summary>
    public class ChaseState : AdvancedFSM.BaseState
    {
        private Transform transform;
        private CharacterController characterController;
        private Animator animator;
        private Transform playerTarget;
        
        private float chaseSpeed = 6f;
        private float rotationSpeed = 10f;
        private float attackRange = 3f;
        private float maxChaseDistance = 20f;
        
        public override string StateId 
        { 
            get { return "Chase"; } 
        }
        
        public ChaseState(GameObject owner, AdvancedFiniteStateMachine fsm, Transform playerTarget) 
            : base(owner, fsm)
        {
            transform = owner.transform;
            characterController = owner.GetComponent<CharacterController>();
            animator = owner.GetComponent<Animator>();
            this.playerTarget = playerTarget;
        }
        
        public override void OnEnter()
        {
            Debug.Log("进入追逐状态");
            
            if (animator != null)
            {
                animator.SetBool("IsRunning", true);
                animator.SetBool("IsWalking", false);
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            if (playerTarget == null)
            {
                // 没有目标,返回巡逻
                fsm.ChangeState("Patrol");
                return;
            }
            
            // 计算到玩家的距离
            float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
            
            // 检查是否超出最大追逐距离
            if (distanceToPlayer > maxChaseDistance)
            {
                fsm.ChangeState("Patrol");
                return;
            }
            
            // 检查是否在攻击范围内
            if (distanceToPlayer <= attackRange)
            {
                fsm.ChangeState("Attack");
                return;
            }
            
            // 追逐玩家
            Vector3 directionToPlayer = (playerTarget.position - transform.position).normalized;
            
            // 移动
            if (characterController != null)
            {
                characterController.Move(directionToPlayer * chaseSpeed * deltaTime);
            }
            else
            {
                transform.position += directionToPlayer * chaseSpeed * deltaTime;
            }
            
            // 旋转面向玩家
            if (directionToPlayer.magnitude > 0.1f)
            {
                Quaternion targetRotation = Quaternion.LookRotation(directionToPlayer);
                transform.rotation = Quaternion.Slerp(
                    transform.rotation, 
                    targetRotation, 
                    rotationSpeed * deltaTime
                );
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出追逐状态");
            
            if (animator != null)
            {
                animator.SetBool("IsRunning", false);
            }
        }
    }

    /// <summary>
    /// 攻击状态
    /// </summary>
    public class AttackState : AdvancedFSM.BaseState
    {
        private Transform transform;
        private Animator animator;
        private Transform playerTarget;
        
        private float attackCooldown = 1f;
        private float attackTimer = 0f;
        private float attackRange = 3f;
        private float attackDamage = 10f;
        
        public override string StateId 
        { 
            get { return "Attack"; } 
        }
        
        public AttackState(GameObject owner, AdvancedFiniteStateMachine fsm, Transform playerTarget) 
            : base(owner, fsm)
        {
            transform = owner.transform;
            animator = owner.GetComponent<Animator>();
            this.playerTarget = playerTarget;
        }
        
        public override void OnEnter()
        {
            Debug.Log("进入攻击状态");
            attackTimer = 0f;
            
            if (animator != null)
            {
                animator.SetBool("IsAttacking", true);
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            if (playerTarget == null)
            {
                fsm.ChangeState("Patrol");
                return;
            }
            
            // 更新攻击计时器
            attackTimer += deltaTime;
            
            // 面向玩家
            Vector3 directionToPlayer = (playerTarget.position - transform.position).normalized;
            directionToPlayer.y = 0;
            
            if (directionToPlayer.magnitude > 0.1f)
            {
                Quaternion targetRotation = Quaternion.LookRotation(directionToPlayer);
                transform.rotation = Quaternion.Slerp(
                    transform.rotation, 
                    targetRotation, 
                    15f * deltaTime
                );
            }
            
            // 检查玩家是否在攻击范围内
            float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
            
            if (distanceToPlayer > attackRange * 1.5f)
            {
                // 玩家离开攻击范围,返回追逐
                fsm.ChangeState("Chase");
                return;
            }
            
            // 执行攻击
            if (attackTimer >= attackCooldown)
            {
                PerformAttack();
                attackTimer = 0f;
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出攻击状态");
            
            if (animator != null)
            {
                animator.SetBool("IsAttacking", false);
            }
        }
        
        private void PerformAttack()
        {
            Debug.Log("执行攻击,造成伤害: " + attackDamage);
            
            // 触发攻击动画
            if (animator != null)
            {
                animator.SetTrigger("AttackTrigger");
            }
            
            // 在实际项目中,这里会对玩家造成伤害
            if (playerTarget != null)
            {
                PlayerHealth playerHealth = playerTarget.GetComponent<PlayerHealth>();
                if (playerHealth != null)
                {
                    playerHealth.TakeDamage(attackDamage);
                }
            }
        }
    }

    /// <summary>
    /// 死亡状态
    /// </summary>
    public class DeadState : AdvancedFSM.BaseState
    {
        private Transform transform;
        private Animator animator;
        private CharacterController characterController;
        
        private float deathTimer = 0f;
        private float destroyDelay = 3f;
        
        public override string StateId 
        { 
            get { return "Dead"; } 
        }
        
        public DeadState(GameObject owner, AdvancedFiniteStateMachine fsm) 
            : base(owner, fsm)
        {
            transform = owner.transform;
            animator = owner.GetComponent<Animator>();
            characterController = owner.GetComponent<CharacterController>();
        }
        
        public override void OnEnter()
        {
            Debug.Log("进入死亡状态");
            
            if (animator != null)
            {
                animator.SetTrigger("Die");
            }
            
            if (characterController != null)
            {
                characterController.enabled = false;
            }
            
            // 禁用碰撞器
            Collider collider = owner.GetComponent<Collider>();
            if (collider != null)
            {
                collider.enabled = false;
            }
            
            deathTimer = 0f;
        }
        
        public override void OnUpdate(float deltaTime)
        {
            deathTimer += deltaTime;
            
            // 一段时间后销毁对象
            if (deathTimer >= destroyDelay)
            {
                GameObject.Destroy(owner);
            }
        }
    }

    /// <summary>
    /// AI控制器
    /// </summary>
    public class AIController : MonoBehaviour
    {
        [Header("目标设置")]
        [SerializeField]
        private Transform playerTarget;
        
        [Header("AI属性")]
        [SerializeField]
        private float health = 100f;
        
        [SerializeField]
        private float detectionRange = 15f;
        
        [SerializeField]
        private float attackRange = 3f;
        
        [Header("组件引用")]
        [SerializeField]
        private Animator animator;
        
        private AdvancedFiniteStateMachine fsm;
        private bool isPlayerInSight = false;
        private float lastHealth;
        
        private void Awake()
        {
            InitializeAI();
        }
        
        private void InitializeAI()
        {
            // 初始化FSM
            fsm = new AdvancedFiniteStateMachine();
            
            // 创建状态
            PatrolState patrolState = new PatrolState(gameObject, fsm);
            ChaseState chaseState = new ChaseState(gameObject, fsm, playerTarget);
            AttackState attackState = new AttackState(gameObject, fsm, playerTarget);
            DeadState deadState = new DeadState(gameObject, fsm);
            
            // 添加状态
            fsm.AddState(patrolState, true); // 默认状态
            fsm.AddState(chaseState);
            fsm.AddState(attackState);
            fsm.AddState(deadState);
            
            // 添加转换条件
            
            // 巡逻 -> 追逐 (看到玩家)
            fsm.AddTransition("Patrol", "Chase",
                new BoolCondition(() => IsPlayerInSight() && IsPlayerInRange(), 1));
            
            // 追逐 -> 攻击 (玩家在攻击范围内)
            fsm.AddTransition("Chase", "Attack",
                new BoolCondition(() => IsPlayerInAttackRange(), 2));
            
            // 攻击 -> 追逐 (玩家离开攻击范围)
            fsm.AddTransition("Attack", "Chase",
                new BoolCondition(() => !IsPlayerInAttackRange() && IsPlayerInSight(), 1));
            
            // 追逐 -> 巡逻 (丢失玩家)
            fsm.AddTransition("Chase", "Patrol",
                new BoolCondition(() => !IsPlayerInSight(), 1));
            
            // 攻击 -> 巡逻 (丢失玩家)
            fsm.AddTransition("Attack", "Patrol",
                new BoolCondition(() => !IsPlayerInSight(), 1));
            
            // 任意状态 -> 死亡 (生命值<=0)
            fsm.AddAnyTransition("Dead",
                new BoolCondition(() => health <= 0, 10));
            
            // 注册事件
            fsm.OnStateChanged += OnStateChanged;
            fsm.OnTransitionTriggered += OnTransitionTriggered;
            
            // 初始化FSM
            fsm.Initialize();
            
            lastHealth = health;
            
            Debug.Log("AI控制器初始化完成");
        }
        
        private void Update()
        {
            // 更新FSM
            fsm.Update(Time.deltaTime);
            
            // 更新玩家检测
            UpdatePlayerDetection();
            
            // 检查生命值变化
            if (health != lastHealth)
            {
                OnHealthChanged();
                lastHealth = health;
            }
        }
        
        private void UpdatePlayerDetection()
        {
            if (playerTarget == null)
            {
                isPlayerInSight = false;
                return;
            }
            
            float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
            isPlayerInSight = distanceToPlayer <= detectionRange;
        }
        
        private bool IsPlayerInSight()
        {
            return isPlayerInSight;
        }
        
        private bool IsPlayerInRange()
        {
            if (playerTarget == null)
            {
                return false;
            }
            
            float distance = Vector3.Distance(transform.position, playerTarget.position);
            return distance <= detectionRange;
        }
        
        private bool IsPlayerInAttackRange()
        {
            if (playerTarget == null)
            {
                return false;
            }
            
            float distance = Vector3.Distance(transform.position, playerTarget.position);
            return distance <= attackRange;
        }
        
        public void TakeDamage(float damage)
        {
            if (health <= 0)
            {
                return;
            }
            
            health -= damage;
            health = Mathf.Max(0, health);
            
            Debug.Log($"AI受到伤害: {damage},剩余生命: {health}");
            
            // 如果受到伤害且不在战斗状态,开始追逐
            if (!fsm.IsInState("Chase") && !fsm.IsInState("Attack") && !fsm.IsInState("Dead"))
            {
                fsm.ChangeState("Chase");
            }
        }
        
        private void OnHealthChanged()
        {
            // 更新动画参数
            if (animator != null)
            {
                float healthRatio = health / 100f;
                animator.SetFloat("Health", healthRatio);
            }
        }
        
        private void OnStateChanged(AdvancedFSM.IState previousState, AdvancedFSM.IState newState)
        {
            Debug.Log($"状态变化: {previousState?.StateId ?? "None"} -> {newState.StateId}");
        }
        
        private void OnTransitionTriggered(string transition)
        {
            Debug.Log($"触发转换: {transition}");
        }
        
        private void OnDrawGizmosSelected()
        {
            if (!Application.isPlaying)
            {
                return;
            }
            
            // 绘制检测范围
            Gizmos.color = isPlayerInSight ? Color.red : Color.yellow;
            Gizmos.DrawWireSphere(transform.position, detectionRange);
            
            // 绘制攻击范围
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, attackRange);
            
            // 绘制当前状态
            #if UNITY_EDITOR
            string info = $"状态: {fsm.CurrentState?.StateId ?? "None"}\n";
            info += $"生命: {health:F0}\n";
            info += $"状态时间: {fsm.TimeInCurrentState:F1}s";
            
            UnityEditor.Handles.Label(
                transform.position + Vector3.up * 2f,
                info
            );
            #endif
        }
        
        private void OnDestroy()
        {
            // 清理FSM事件
            if (fsm != null)
            {
                fsm.OnStateChanged -= OnStateChanged;
                fsm.OnTransitionTriggered -= OnTransitionTriggered;
            }
        }
    }
}

6.3.2 通用FSM框架的高级特性

上述通用FSM框架已经具备了商业项目所需的核心功能。为了进一步增强其实用性,我们可以添加以下高级特性:

  1. 层级状态机(HFSM):支持状态的嵌套,允许状态内部包含子状态机
  2. 并行状态机:同时运行多个状态,用于处理独立的行为(如移动、攻击、动画)
  3. 状态间通信:允许状态之间传递数据
  4. 状态黑板:共享数据存储,供所有状态访问
  5. 可视化调试工具:实时显示状态机运行状态

下面是一个增强的通用FSM框架,包含这些高级特性:

using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AdvancedFSMPro
{
    /// <summary>
    /// 状态黑板 - 用于状态间数据共享
    /// </summary>
    public class StateBlackboard
    {
        private Dictionary<string, object> data = new Dictionary<string, object>();
        private Dictionary<string, List<Action<object>>> listeners = new Dictionary<string, List<Action<object>>>();
        
        public void SetValue<T>(string key, T value)
        {
            data[key] = value;
            
            // 通知监听者
            if (listeners.ContainsKey(key))
            {
                foreach (Action<object> listener in listeners[key])
                {
                    listener(value);
                }
            }
        }
        
        public T GetValue<T>(string key, T defaultValue = default(T))
        {
            if (data.ContainsKey(key) && data[key] is T)
            {
                return (T)data[key];
            }
            return defaultValue;
        }
        
        public bool HasValue(string key)
        {
            return data.ContainsKey(key);
        }
        
        public void RemoveValue(string key)
        {
            if (data.ContainsKey(key))
            {
                data.Remove(key);
            }
        }
        
        public void AddListener(string key, Action<object> listener)
        {
            if (!listeners.ContainsKey(key))
            {
                listeners[key] = new List<Action<object>>();
            }
            
            if (!listeners[key].Contains(listener))
            {
                listeners[key].Add(listener);
            }
        }
        
        public void RemoveListener(string key, Action<object> listener)
        {
            if (listeners.ContainsKey(key))
            {
                listeners[key].Remove(listener);
            }
        }
        
        public void Clear()
        {
            data.Clear();
            listeners.Clear();
        }
    }
    
    /// <summary>
    /// 状态上下文 - 包含状态运行所需的所有信息
    /// </summary>
    public class StateContext
    {
        public GameObject Owner { get; private set; }
        public StateBlackboard Blackboard { get; private set; }
        public AdvancedFiniteStateMachine FSM { get; private set; }
        public StateMachineController Controller { get; private set; }
        
        public StateContext(GameObject owner, StateBlackboard blackboard, 
            AdvancedFiniteStateMachine fsm, StateMachineController controller)
        {
            Owner = owner;
            Blackboard = blackboard;
            FSM = fsm;
            Controller = controller;
        }
    }
    
    /// <summary>
    /// 增强版状态接口
    /// </summary>
    public interface IEnhancedState
    {
        string StateId { get; }
        int Priority { get; }
        bool CanRunParallel { get; }
        
        void Initialize(StateContext context);
        void OnEnter();
        void OnUpdate(float deltaTime);
        void OnFixedUpdate(float fixedDeltaTime);
        void OnLateUpdate(float deltaTime);
        void OnExit();
        void OnPause();
        void OnResume();
        
        bool CanEnter();
        bool CanExit();
        
        List<Type> RequiredComponents();
    }
    
    /// <summary>
    /// 基础增强状态
    /// </summary>
    public abstract class BaseEnhancedState : IEnhancedState
    {
        public abstract string StateId { get; }
        public virtual int Priority { get { return 0; } }
        public virtual bool CanRunParallel { get { return false; } }
        
        protected StateContext context;
        protected GameObject owner;
        protected StateBlackboard blackboard;
        protected AdvancedFiniteStateMachine fsm;
        
        private Dictionary<Type, Component> cachedComponents = new Dictionary<Type, Component>();
        
        public virtual void Initialize(StateContext context)
        {
            this.context = context;
            this.owner = context.Owner;
            this.blackboard = context.Blackboard;
            this.fsm = context.FSM;
        }
        
        public virtual void OnEnter() { }
        public virtual void OnUpdate(float deltaTime) { }
        public virtual void OnFixedUpdate(float fixedDeltaTime) { }
        public virtual void OnLateUpdate(float deltaTime) { }
        public virtual void OnExit() { }
        public virtual void OnPause() { }
        public virtual void OnResume() { }
        
        public virtual bool CanEnter() { return true; }
        public virtual bool CanExit() { return true; }
        
        public virtual List<Type> RequiredComponents()
        {
            return new List<Type>();
        }
        
        protected T GetComponent<T>() where T : Component
        {
            Type type = typeof(T);
            
            if (!cachedComponents.ContainsKey(type))
            {
                cachedComponents[type] = owner.GetComponent<T>();
            }
            
            return cachedComponents[type] as T;
        }
        
        protected T GetOrAddComponent<T>() where T : Component
        {
            T component = GetComponent<T>();
            if (component == null)
            {
                component = owner.AddComponent<T>();
                cachedComponents[typeof(T)] = component;
            }
            return component;
        }
    }
    
    /// <summary>
    /// 层级状态 - 可以包含子状态机
    /// </summary>
    public abstract class HierarchicalState : BaseEnhancedState
    {
        protected AdvancedFiniteStateMachine subFSM;
        private bool isSubFSMInitialized = false;
        
        public override void Initialize(StateContext context)
        {
            base.Initialize(context);
            
            // 创建子状态机
            subFSM = new AdvancedFiniteStateMachine();
            InitializeSubFSM();
        }
        
        protected abstract void InitializeSubFSM();
        
        public override void OnEnter()
        {
            if (!isSubFSMInitialized)
            {
                subFSM.Initialize();
                isSubFSMInitialized = true;
            }
            else
            {
                subFSM.Resume();
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            subFSM.Update(deltaTime);
        }
        
        public override void OnExit()
        {
            subFSM.Pause();
        }
        
        public override void OnPause()
        {
            subFSM.Pause();
        }
        
        public override void OnResume()
        {
            subFSM.Resume();
        }
    }
    
    /// <summary>
    /// 并行状态容器 - 管理多个并行运行的状态
    /// </summary>
    public class ParallelStateContainer : BaseEnhancedState
    {
        public override string StateId { get { return "ParallelContainer"; } }
        public override bool CanRunParallel { get { return true; } }
        
        private List<IEnhancedState> parallelStates = new List<IEnhancedState>();
        private Dictionary<IEnhancedState, bool> stateActiveStatus = new Dictionary<IEnhancedState, bool>();
        
        public void AddParallelState(IEnhancedState state)
        {
            if (!parallelStates.Contains(state))
            {
                parallelStates.Add(state);
                stateActiveStatus[state] = false;
                
                // 按优先级排序
                parallelStates = parallelStates.OrderByDescending(s => s.Priority).ToList();
            }
        }
        
        public void RemoveParallelState(IEnhancedState state)
        {
            if (parallelStates.Contains(state))
            {
                if (stateActiveStatus[state])
                {
                    state.OnExit();
                }
                
                parallelStates.Remove(state);
                stateActiveStatus.Remove(state);
            }
        }
        
        public override void Initialize(StateContext context)
        {
            base.Initialize(context);
            
            foreach (IEnhancedState state in parallelStates)
            {
                state.Initialize(context);
            }
        }
        
        public override void OnEnter()
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (state.CanEnter())
                {
                    state.OnEnter();
                    stateActiveStatus[state] = true;
                }
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnUpdate(deltaTime);
                }
            }
        }
        
        public override void OnFixedUpdate(float fixedDeltaTime)
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnFixedUpdate(fixedDeltaTime);
                }
            }
        }
        
        public override void OnLateUpdate(float deltaTime)
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnLateUpdate(deltaTime);
                }
            }
        }
        
        public override void OnExit()
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnExit();
                    stateActiveStatus[state] = false;
                }
            }
        }
        
        public override void OnPause()
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnPause();
                }
            }
        }
        
        public override void OnResume()
        {
            foreach (IEnhancedState state in parallelStates)
            {
                if (stateActiveStatus[state])
                {
                    state.OnResume();
                }
            }
        }
    }
    
    /// <summary>
    /// 状态机控制器 - 管理增强版FSM
    /// </summary>
    public class StateMachineController : MonoBehaviour
    {
        [Header("调试设置")]
        [SerializeField]
        private bool enableDebug = true;
        
        [SerializeField]
        private bool drawGizmos = true;
        
        [Header("状态机配置")]
        [SerializeField]
        private List<MonoBehaviour> stateBehaviours = new List<MonoBehaviour>();
        
        private AdvancedFiniteStateMachine mainFSM;
        private ParallelStateContainer parallelContainer;
        private StateBlackboard blackboard;
        private StateContext context;
        
        private List<IEnhancedState> allStates = new List<IEnhancedState>();
        private Dictionary<string, IEnhancedState> stateMap = new Dictionary<string, IEnhancedState>();
        
        public AdvancedFiniteStateMachine MainFSM { get { return mainFSM; } }
        public StateBlackboard Blackboard { get { return blackboard; } }
        public StateContext Context { get { return context; } }
        
        public event Action<string, string> OnStateChanged;
        public event Action<string> OnTransitionTriggered;
        public event Action<string, object> OnBlackboardValueChanged;
        
        private void Awake()
        {
            InitializeStateMachine();
        }
        
        private void InitializeStateMachine()
        {
            // 创建黑板
            blackboard = new StateBlackboard();
            
            // 创建主FSM
            mainFSM = new AdvancedFiniteStateMachine();
            
            // 创建并行容器
            parallelContainer = new ParallelStateContainer();
            
            // 创建上下文
            context = new StateContext(gameObject, blackboard, mainFSM, this);
            
            // 初始化状态
            InitializeStates();
            
            // 注册黑板监听
            RegisterBlackboardListeners();
            
            // 初始化FSM
            mainFSM.Initialize();
            
            // 注册事件
            mainFSM.OnStateChanged += OnMainFSMStateChanged;
            mainFSM.OnTransitionTriggered += OnMainFSMTransitionTriggered;
            
            Debug.Log("状态机控制器初始化完成");
        }
        
        private void InitializeStates()
        {
            // 从MonoBehaviour添加状态
            foreach (MonoBehaviour behaviour in stateBehaviours)
            {
                if (behaviour is IEnhancedState enhancedState)
                {
                    AddState(enhancedState);
                }
            }
            
            // 添加并行容器到主FSM
            mainFSM.AddState(parallelContainer);
        }
        
        public void AddState(IEnhancedState state)
        {
            if (stateMap.ContainsKey(state.StateId))
            {
                Debug.LogWarning($"状态已存在: {state.StateId}");
                return;
            }
            
            // 初始化状态
            state.Initialize(context);
            
            // 检查所需组件
            List<Type> requiredComponents = state.RequiredComponents();
            foreach (Type componentType in requiredComponents)
            {
                if (gameObject.GetComponent(componentType) == null)
                {
                    Debug.LogError($"状态 {state.StateId} 需要组件: {componentType.Name}");
                    return;
                }
            }
            
            // 添加到相应集合
            allStates.Add(state);
            stateMap[state.StateId] = state;
            
            if (state.CanRunParallel)
            {
                // 添加到并行容器
                parallelContainer.AddParallelState(state);
            }
            else
            {
                // 添加到主FSM
                mainFSM.AddState(state);
            }
            
            Debug.Log($"添加状态: {state.StateId} (并行: {state.CanRunParallel})");
        }
        
        public void AddTransition(string fromStateId, string toStateId, 
            ITransitionCondition condition, Action onTransition = null)
        {
            mainFSM.AddTransition(fromStateId, toStateId, condition, onTransition);
        }
        
        public void AddAnyTransition(string toStateId, ITransitionCondition condition, Action onTransition = null)
        {
            mainFSM.AddAnyTransition(toStateId, condition, onTransition);
        }
        
        private void RegisterBlackboardListeners()
        {
            // 示例:监听玩家位置变化
            blackboard.AddListener("PlayerPosition", (value) =>
            {
                OnBlackboardValueChanged?.Invoke("PlayerPosition", value);
            });
            
            blackboard.AddListener("Health", (value) =>
            {
                OnBlackboardValueChanged?.Invoke("Health", value);
            });
        }
        
        private void Update()
        {
            // 更新主FSM
            mainFSM.Update(Time.deltaTime);
        }
        
        private void FixedUpdate()
        {
            // 固定更新(用于物理相关状态)
            // 注意:基础FSM不支持FixedUpdate,需要状态自己处理
        }
        
        private void LateUpdate()
        {
            // 后期更新(用于相机相关状态)
            // 注意:基础FSM不支持LateUpdate,需要状态自己处理
        }
        
        private void OnMainFSMStateChanged(IState previousState, IState newState)
        {
            string previousId = previousState?.StateId ?? "None";
            string newId = newState?.StateId ?? "None";
            
            if (enableDebug)
            {
                Debug.Log($"主FSM状态变化: {previousId} -> {newId}");
            }
            
            OnStateChanged?.Invoke(previousId, newId);
        }
        
        private void OnMainFSMTransitionTriggered(string transition)
        {
            if (enableDebug)
            {
                Debug.Log($"主FSM触发转换: {transition}");
            }
            
            OnTransitionTriggered?.Invoke(transition);
        }
        
        public IEnhancedState GetState(string stateId)
        {
            return stateMap.ContainsKey(stateId) ? stateMap[stateId] : null;
        }
        
        public void ChangeState(string stateId)
        {
            mainFSM.ChangeState(stateId);
        }
        
        public bool IsInState(string stateId)
        {
            return mainFSM.IsInState(stateId);
        }
        
        public void SetBlackboardValue<T>(string key, T value)
        {
            blackboard.SetValue(key, value);
        }
        
        public T GetBlackboardValue<T>(string key, T defaultValue = default(T))
        {
            return blackboard.GetValue(key, defaultValue);
        }
        
        private void OnDrawGizmos()
        {
            if (!drawGizmos || !Application.isPlaying)
            {
                return;
            }
            
            // 绘制状态机信息
            DrawStateMachineGizmos();
        }
        
        private void DrawStateMachineGizmos()
        {
            #if UNITY_EDITOR
            // 绘制当前状态信息
            string info = $"状态机控制器\n";
            info += $"当前状态: {mainFSM.CurrentState?.StateId ?? "None"}\n";
            info += $"状态时间: {mainFSM.TimeInCurrentState:F1}s\n";
            
            // 显示黑板重要值
            if (blackboard.HasValue("Health"))
            {
                float health = blackboard.GetValue<float>("Health");
                info += $"生命值: {health:F0}\n";
            }
            
            if (blackboard.HasValue("PlayerPosition"))
            {
                Vector3 playerPos = blackboard.GetValue<Vector3>("PlayerPosition");
                info += $"玩家距离: {Vector3.Distance(transform.position, playerPos):F1}";
            }
            
            UnityEditor.Handles.Label(
                transform.position + Vector3.up * 3f,
                info
            );
            
            // 绘制到玩家的线(如果有玩家位置)
            if (blackboard.HasValue("PlayerPosition"))
            {
                Vector3 playerPos = blackboard.GetValue<Vector3>("PlayerPosition");
                Gizmos.color = Color.red;
                Gizmos.DrawLine(transform.position, playerPos);
            }
            #endif
        }
        
        private void OnDestroy()
        {
            // 清理事件
            if (mainFSM != null)
            {
                mainFSM.OnStateChanged -= OnMainFSMStateChanged;
                mainFSM.OnTransitionTriggered -= OnMainFSMTransitionTriggered;
            }
        }
    }
    
    /// <summary>
    /// 示例:移动状态(可作为并行状态运行)
    /// </summary>
    public class MovementState : BaseEnhancedState
    {
        public override string StateId { get { return "Movement"; } }
        public override bool CanRunParallel { get { return true; } }
        public override int Priority { get { return 1; } }
        
        private CharacterController characterController;
        private Animator animator;
        
        private Vector3 moveDirection;
        private float moveSpeed = 3f;
        private float rotationSpeed = 5f;
        
        public override List<Type> RequiredComponents()
        {
            return new List<Type> { typeof(CharacterController), typeof(Animator) };
        }
        
        public override void Initialize(StateContext context)
        {
            base.Initialize(context);
            
            characterController = GetComponent<CharacterController>();
            animator = GetComponent<Animator>();
        }
        
        public override void OnEnter()
        {
            Debug.Log("进入移动状态");
            
            if (animator != null)
            {
                animator.SetBool("IsMoving", true);
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            // 从黑板获取移动方向
            if (blackboard.HasValue("MoveDirection"))
            {
                moveDirection = blackboard.GetValue<Vector3>("MoveDirection");
            }
            
            // 从黑板获取移动速度
            if (blackboard.HasValue("MoveSpeed"))
            {
                moveSpeed = blackboard.GetValue<float>("MoveSpeed");
            }
            
            // 应用移动
            if (characterController != null && moveDirection.magnitude > 0.1f)
            {
                characterController.Move(moveDirection * moveSpeed * deltaTime);
                
                // 旋转面向移动方向
                Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
                owner.transform.rotation = Quaternion.Slerp(
                    owner.transform.rotation,
                    targetRotation,
                    rotationSpeed * deltaTime
                );
            }
            
            // 更新动画速度
            if (animator != null)
            {
                float speed = characterController != null ? 
                    characterController.velocity.magnitude : 0f;
                animator.SetFloat("Speed", speed);
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出移动状态");
            
            if (animator != null)
            {
                animator.SetBool("IsMoving", false);
                animator.SetFloat("Speed", 0f);
            }
        }
    }
    
    /// <summary>
    /// 示例:战斗状态(层级状态,包含子状态机)
    /// </summary>
    public class CombatState : HierarchicalState
    {
        public override string StateId { get { return "Combat"; } }
        
        private Transform playerTarget;
        
        public override List<Type> RequiredComponents()
        {
            return new List<Type> { typeof(Animator) };
        }
        
        protected override void InitializeSubFSM()
        {
            // 创建战斗子状态
            CombatEngageState engageState = new CombatEngageState();
            CombatAttackState attackState = new CombatAttackState();
            CombatRetreatState retreatState = new CombatRetreatState();
            
            // 初始化状态
            engageState.Initialize(context);
            attackState.Initialize(context);
            retreatState.Initialize(context);
            
            // 添加到子FSM
            subFSM.AddState(engageState, true); // 默认状态
            subFSM.AddState(attackState);
            subFSM.AddState(retreatState);
            
            // 添加转换
            subFSM.AddTransition("CombatEngage", "CombatAttack",
                new BoolCondition(() => IsPlayerInAttackRange(), 1));
            
            subFSM.AddTransition("CombatAttack", "CombatEngage",
                new BoolCondition(() => !IsPlayerInAttackRange(), 1));
            
            subFSM.AddTransition("CombatEngage", "CombatRetreat",
                new BoolCondition(() => IsHealthLow(), 2));
            
            subFSM.AddTransition("CombatAttack", "CombatRetreat",
                new BoolCondition(() => IsHealthLow(), 2));
            
            subFSM.AddTransition("CombatRetreat", "CombatEngage",
                new BoolCondition(() => !IsHealthLow(), 1));
        }
        
        public override void OnEnter()
        {
            base.OnEnter();
            Debug.Log("进入战斗状态(层级)");
            
            // 获取玩家目标
            playerTarget = blackboard.GetValue<Transform>("PlayerTarget", null);
        }
        
        private bool IsPlayerInAttackRange()
        {
            if (playerTarget == null)
            {
                return false;
            }
            
            float attackRange = blackboard.GetValue<float>("AttackRange", 3f);
            float distance = Vector3.Distance(owner.transform.position, playerTarget.position);
            
            return distance <= attackRange;
        }
        
        private bool IsHealthLow()
        {
            float health = blackboard.GetValue<float>("Health", 100f);
            return health < 30f;
        }
    }
    
    /// <summary>
    /// 战斗接触状态
    /// </summary>
    public class CombatEngageState : BaseEnhancedState
    {
        public override string StateId { get { return "CombatEngage"; } }
        
        private Transform playerTarget;
        private float engageSpeed = 4f;
        
        public override void OnEnter()
        {
            Debug.Log("进入战斗接触状态");
        }
        
        public override void OnUpdate(float deltaTime)
        {
            playerTarget = blackboard.GetValue<Transform>("PlayerTarget", null);
            
            if (playerTarget != null)
            {
                // 向玩家移动
                Vector3 direction = (playerTarget.position - owner.transform.position).normalized;
                blackboard.SetValue("MoveDirection", direction);
                blackboard.SetValue("MoveSpeed", engageSpeed);
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出战斗接触状态");
        }
    }
    
    /// <summary>
    /// 战斗攻击状态
    /// </summary>
    public class CombatAttackState : BaseEnhancedState
    {
        public override string StateId { get { return "CombatAttack"; } }
        
        private Transform playerTarget;
        private float attackCooldown = 1f;
        private float attackTimer = 0f;
        private float attackDamage = 10f;
        
        public override void OnEnter()
        {
            Debug.Log("进入战斗攻击状态");
            attackTimer = 0f;
        }
        
        public override void OnUpdate(float deltaTime)
        {
            playerTarget = blackboard.GetValue<Transform>("PlayerTarget", null);
            
            if (playerTarget != null)
            {
                // 面向玩家
                Vector3 direction = (playerTarget.position - owner.transform.position).normalized;
                direction.y = 0;
                
                if (direction.magnitude > 0.1f)
                {
                    Quaternion targetRotation = Quaternion.LookRotation(direction);
                    owner.transform.rotation = Quaternion.Slerp(
                        owner.transform.rotation,
                        targetRotation,
                        10f * deltaTime
                    );
                }
                
                // 停止移动
                blackboard.SetValue("MoveDirection", Vector3.zero);
                
                // 攻击逻辑
                attackTimer += deltaTime;
                if (attackTimer >= attackCooldown)
                {
                    PerformAttack();
                    attackTimer = 0f;
                }
            }
        }
        
        private void PerformAttack()
        {
            Debug.Log("执行攻击,伤害: " + attackDamage);
            
            // 在实际项目中,这里会对玩家造成伤害
            if (playerTarget != null)
            {
                PlayerHealth playerHealth = playerTarget.GetComponent<PlayerHealth>();
                if (playerHealth != null)
                {
                    playerHealth.TakeDamage(attackDamage);
                }
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出战斗攻击状态");
        }
    }
    
    /// <summary>
    /// 战斗撤退状态
    /// </summary>
    public class CombatRetreatState : BaseEnhancedState
    {
        public override string StateId { get { return "CombatRetreat"; } }
        
        private Transform playerTarget;
        private float retreatSpeed = 3f;
        private Vector3 retreatPosition;
        
        public override void OnEnter()
        {
            Debug.Log("进入战斗撤退状态");
            
            // 计算撤退位置(远离玩家)
            playerTarget = blackboard.GetValue<Transform>("PlayerTarget", null);
            if (playerTarget != null)
            {
                Vector3 awayFromPlayer = (owner.transform.position - playerTarget.position).normalized;
                retreatPosition = owner.transform.position + awayFromPlayer * 10f;
            }
            else
            {
                retreatPosition = owner.transform.position;
            }
        }
        
        public override void OnUpdate(float deltaTime)
        {
            // 向撤退位置移动
            Vector3 direction = (retreatPosition - owner.transform.position).normalized;
            blackboard.SetValue("MoveDirection", direction);
            blackboard.SetValue("MoveSpeed", retreatSpeed);
            
            // 检查是否到达撤退位置
            float distance = Vector3.Distance(owner.transform.position, retreatPosition);
            if (distance < 1f)
            {
                // 短暂休息
                blackboard.SetValue("MoveDirection", Vector3.zero);
            }
        }
        
        public override void OnExit()
        {
            Debug.Log("退出战斗撤退状态");
        }
    }
}

// 使用示例
public class AdvancedAIController : MonoBehaviour
{
    [Header("AI设置")]
    [SerializeField]
    private Transform playerTarget;
    
    [SerializeField]
    private float detectionRange = 15f;
    
    [SerializeField]
    private float health = 100f;
    
    [Header("状态机")]
    [SerializeField]
    private StateMachineController stateMachineController;
    
    [SerializeField]
    private List<MonoBehaviour> initialStateBehaviours;
    
    private void Awake()
    {
        InitializeAI();
    }
    
    private void InitializeAI()
    {
        // 创建状态机控制器(如果不存在)
        if (stateMachineController == null)
        {
            stateMachineController = gameObject.AddComponent<StateMachineController>();
        }
        
        // 添加初始状态
        foreach (MonoBehaviour behaviour in initialStateBehaviours)
        {
            if (behaviour != null)
            {
                stateMachineController.AddState(behaviour as AdvancedFSMPro.IEnhancedState);
            }
        }
        
        // 设置初始黑板值
        stateMachineController.SetBlackboardValue("PlayerTarget", playerTarget);
        stateMachineController.SetBlackboardValue("Health", health);
        stateMachineController.SetBlackboardValue("DetectionRange", detectionRange);
        stateMachineController.SetBlackboardValue("AttackRange", 3f);
        stateMachineController.SetBlackboardValue("MoveSpeed", 3f);
        
        // 注册事件
        stateMachineController.OnStateChanged += OnAIStateChanged;
        stateMachineController.OnTransitionTriggered += OnAITransitionTriggered;
        stateMachineController.OnBlackboardValueChanged += OnBlackboardValueChanged;
        
        // 添加初始状态转换
        AddInitialTransitions();
        
        Debug.Log("高级AI控制器初始化完成");
    }
    
    private void AddInitialTransitions()
    {
        // 空闲 -> 巡逻 (一段时间后)
        stateMachineController.AddTransition("Idle", "Patrol",
            new AdvancedFSM.DelayCondition(3f));
        
        // 巡逻 -> 战斗 (看到玩家)
        stateMachineController.AddTransition("Patrol", "Combat",
            new AdvancedFSM.BoolCondition(() => IsPlayerInSight(), 1));
        
        // 战斗 -> 巡逻 (丢失玩家一段时间)
        stateMachineController.AddTransition("Combat", "Patrol",
            new AdvancedFSM.BoolCondition(() => !IsPlayerInSight() && GetTimeSinceLastSeen() > 5f, 1));
    }
    
    private void Update()
    {
        // 更新玩家检测
        UpdatePlayerDetection();
        
        // 更新黑板值
        UpdateBlackboardValues();
    }
    
    private void UpdatePlayerDetection()
    {
        if (playerTarget == null)
        {
            return;
        }
        
        float distance = Vector3.Distance(transform.position, playerTarget.position);
        bool inSight = distance <= detectionRange;
        
        if (inSight)
        {
            stateMachineController.SetBlackboardValue("PlayerPosition", playerTarget.position);
            stateMachineController.SetBlackboardValue("PlayerLastSeenTime", Time.time);
        }
    }
    
    private void UpdateBlackboardValues()
    {
        // 更新生命值到黑板
        stateMachineController.SetBlackboardValue("Health", health);
    }
    
    private bool IsPlayerInSight()
    {
        if (playerTarget == null)
        {
            return false;
        }
        
        float detectionRange = stateMachineController.GetBlackboardValue<float>("DetectionRange", 15f);
        float distance = Vector3.Distance(transform.position, playerTarget.position);
        
        return distance <= detectionRange;
    }
    
    private float GetTimeSinceLastSeen()
    {
        float lastSeenTime = stateMachineController.GetBlackboardValue<float>("PlayerLastSeenTime", 0f);
        return Time.time - lastSeenTime;
    }
    
    public void TakeDamage(float damage)
    {
        if (health <= 0)
        {
            return;
        }
        
        health -= damage;
        health = Mathf.Max(0, health);
        
        Debug.Log($"AI受到伤害: {damage},剩余生命: {health}");
        
        // 更新黑板
        stateMachineController.SetBlackboardValue("Health", health);
        
        // 如果受到伤害且不在战斗状态,进入战斗
        if (!stateMachineController.IsInState("Combat"))
        {
            stateMachineController.ChangeState("Combat");
        }
    }
    
    private void OnAIStateChanged(string previousState, string newState)
    {
        Debug.Log($"AI状态变化: {previousState} -> {newState}");
    }
    
    private void OnAITransitionTriggered(string transition)
    {
        Debug.Log($"AI触发转换: {transition}");
    }
    
    private void OnBlackboardValueChanged(string key, object value)
    {
        // 处理黑板值变化
        if (key == "Health")
        {
            float newHealth = (float)value;
            if (newHealth <= 0)
            {
                // AI死亡
                OnDeath();
            }
        }
    }
    
    private void OnDeath()
    {
        Debug.Log("AI死亡");
        // 处理死亡逻辑
    }
    
    private void OnDestroy()
    {
        // 清理事件
        if (stateMachineController != null)
        {
            stateMachineController.OnStateChanged -= OnAIStateChanged;
            stateMachineController.OnTransitionTriggered -= OnAITransitionTriggered;
            stateMachineController.OnBlackboardValueChanged -= OnBlackboardValueChanged;
        }
    }
}

这个增强的通用FSM框架提供了商业游戏开发所需的所有高级特性。通过状态黑板、层级状态机、并行状态和模块化设计,开发者可以创建复杂而强大的AI系统,同时保持代码的可维护性和可扩展性。

总结

有限状态机是游戏AI开发的基石技术之一。从简单的switch语句实现到复杂的通用框架,FSM可以适应各种规模和复杂度的项目需求。通过本章的学习,你应该能够:

  1. 理解有限状态机的基本概念和设计原则
  2. 实现基于switch语句的简单状态机
  3. 设计和实现通用的FSM框架
  4. 应用高级FSM特性如层级状态、并行状态和状态黑板
  5. 将FSM集成到实际的游戏AI系统中

在实际项目开发中,选择合适的FSM实现方式非常重要。对于小型项目或原型开发,简单的switch语句状态机可能就足够了。对于大型商业项目,使用成熟的FSM框架可以显著提高开发效率和代码质量。无论选择哪种方式,理解状态机的基本原理和设计模式都是成功实现游戏AI的关键。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐