Untiy状态机框架
这套框架泛用性比较强但是需要重写的代码比较多
状态携带的数据基类
这个类中所需要携带的属性可以自己添加,这里只是简单示范,携带了一个Animator动画机和Nav导航组件
可以根据需要自己更改,Excute函数是接收这个数据的状态在运行时主要调用的函数,在这里进行处理比较方便,因为可以直接拿到本类的属性
/// <summary>
/// 状态数据基类
/// </summary>
public abstract class StateDataBase
{
public Animator anim;
public NavMeshAgent nav;
protected StateDataBase(Animator anim, NavMeshAgent nav)
{
this.anim = anim;
this.nav = nav;
}
public abstract void Excute();
}
状态基类
所有的状态都继承自这个类,所有的逻辑都在这三个函数中实现,包括状态的切换判断以及状态的执行,这里传进来的是上边定义过的状态数据基类,在这里就用到了
public abstract class StateBase
{
public abstract int ID { get; }//状态ID用来对比当前状态和上一个状态是否是同一个状态
public abstract void Enter(StateDataBase data);//第一次进入该状态所执行的逻辑
public abstract void Excute(StateDataBase data);//此状态执行时的行为
public abstract void Leave(StateDataBase data);//此状态退时执行的逻辑
}
状态机核心类
此类是状态机切换状态的核心类,负责状态的改变和执行,在每个挂载状态机的实体的脚本中都是用此类来实现状态的切换和执行
public class FsmCore
{
public StateBase curState;//当前状态
public StateBase prevState;//上一个状态
public StateDataBase data;//当前状态携带的数据
/// <summary>
/// 改变状态函数
/// </summary>
/// <param name="state"></param>
/// <param name="curData"></param>
public void ChangeState(StateBase state,StateDataBase curData)
{
if (curState != null && curState.ID == state.ID)
{
return;
}
if (prevState != null)
{
prevState.Leave(data);
}
data = curData;
curState = state;
prevState = curState;
curState.Enter(data);
}
/// <summary>
/// 状态执行过程
/// </summary>
public void Excute()
{
if (curState != null)
{
curState.Excute(data);
}
}
}