一、工程截图
AIState.cs
using System; /// <summary> /// AI状态基类 /// </summary> public class AIState { //状态ID public virtual int StateId { get { return -1; } set { } } // 进入状态 public virtual void Enter(Enum previousState, params object[] args) { } public virtual void Enter(int previousStateId, object p) { } // 更新状态 public virtual void Update() { } // 退出状态 public virtual void Exit() { } // 动画事件 public virtual void OnAnimationEvent(string p) { } // 销毁 public virtual void Dispose() { } //检测完成条件(对于并行任务,需要同时检测) public virtual void CheckCompletionCondition() { } //是否完成(true: CheckCompletionCondition()方法将不会被调用,否则会每帧调用) public virtual bool IsCompleted { get; set; } = true; //转换状态 public virtual AIStateMachine.TransformParams TransformState() { return null; } }
AIStateMachine.cs
using System.Collections.Generic; using UnityEngine; /// <summary> /// AI状态机 /// </summary> public class AIStateMachine { private Dictionary<int, AIState> stateDic = new Dictionary<int, AIState>(); private AIState currentState; private TransformParams nextStateParam = null; //转换参数 public class TransformParams { public int nextStateId; public object p; } //添加状态 public void Add(int id, AIState state) { if (stateDic.ContainsKey(id)) { Debug.LogErrorFormat("[AIStateMachine] state id({0}) already exist.", id); return; } stateDic.Add(id, state); } //移除状态 public void Remove(int id) { if (stateDic.ContainsKey(id)) stateDic.Remove(id); } //动画事件 public void OnAnimationEvent(string p) { if (currentState != null) currentState.OnAnimationEvent(p); } //转换状态 public void ChangeState(int id, object p=null) { if (!stateDic.ContainsKey(id)) { Debug.LogErrorFormat("[AIStateMachine] Not found state by id({0})", id); return; } int preStateId = currentState != null ? currentState.StateId : -1; currentState?.Exit(); currentState = stateDic[id]; currentState.Enter(preStateId, p); } private void ChangeState(TransformParams tp) { ChangeState(tp.nextStateId, tp.p); } //状态机的驱动函数,需要每帧调用。 public void Tick() { if (currentState == null) return; if (nextStateParam != null) { ChangeState(nextStateParam); nextStateParam = null; return; } nextStateParam = currentState.TransformState(); if (nextStateParam != null) return; currentState.Update(); //检测各状态完成条件 foreach(var state in stateDic.Values) { if (!state.IsCompleted) state.CheckCompletionCondition(); } } //释放 public void Dispose() { currentState = null; nextStateParam = null; foreach (var state in stateDic.Values) state.Dispose(); stateDic.Clear(); } }
ActionStateEnum.cs
namespace AI.Player { /// <summary> /// 状态枚举 /// </summary> public enum ActionStateEnum { None, Idle, //待机 Goto, //前往目的地 TalkNPC, //NPC对话 } }