一、工程截图
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对话
}
}