FSM状态机
程序员文章站
2024-03-19 18:17:58
...
StateBase类、StateTemplate类、Idel类、PlayerCtrl类
StateBase:状态基类,标明状态的3个阶段,以及状态ID,并维护一个用来管理自己的状态机。
public class StateBase : MonoBehaviour {
//状态的ID
public int ID { get;set;}
//状态机
public StateMachine machine;
public StateBase(int id) {
this.ID = id;
}
//状态的三个阶段
public virtual void OnEnter(params object[] args) { }
public virtual void OnStay(params object[] args) { }
public virtual void OnExit(params object[] args) { }
}
StateTemplate:继承自StateBase,维护一个状态的拥有者(因为不同角色都有自己的动画要控制)
public class StateTemplate<T> : StateBase {
//定义状态的拥有者
public T m_owner;
public StateTemplate(int id, T o) : base(id) {
this.m_owner = o;
}
}
StateMachine:用来管理状态的存储、切换、保持
public class StateMachine : MonoBehaviour {
public Dictionary<int, StateBase> m_StateCache;
//用来保存当前角色执行的状态
public StateBase m_CurrentState;
//用来保存当前角色执行的上一个状态
public StateBase m_PreviousState;
public StateMachine(StateBase beganState) {
m_PreviousState = null;
m_CurrentState = beganState;
m_StateCache = new Dictionary<int, StateBase>();
RegisterState(beganState);//把开始状态注册进字典
beganState.OnEnter();//开始状态的执行
}
//存储状态
public void RegisterState(StateBase aState) {
int id = aState.ID;
if (m_StateCache.ContainsKey(id)) {
return;
}
//如果当前字典里没有这个状态,则添加进来
m_StateCache.Add(id,aState);
//表示当前状态由谁来存储、管理
aState.machine = this;
}
//保持状态
public void FSMUpdate() {
if (m_CurrentState != null) {
m_CurrentState.OnStay();
}
}
//切换状态
public void TranslateToState(int id,params object[] args) {
int keyID = id;
if (!m_StateCache.ContainsKey(keyID)) return;
m_PreviousState = m_CurrentState;
m_CurrentState = m_StateCache[keyID];
m_CurrentState.OnEnter();//让刚切换的状态进入
}
}
PlayerCtrl:维护属于他自己的状态机,并在Update中去控制动画的播放(其实是通过状态机来控制状态注册,转换和播放)
public enum PlayerStates {
Idle,
Attack,
Run
}
public class PlayerCtrl : MonoBehaviour {
private StateMachine m_StateMachine;
public Animation ani;
public PlayerStates state = PlayerStates.Idle;
void Awake() {
ani = GetComponent<Animation>();
}
void Start() {
m_StateMachine = new StateMachine(new IdelState(0, this));
m_StateMachine.RegisterState(new AttackState(1,this));
}
}
Idel:
public class IdelState : StateTemplate<PlayerCtrl> {
public IdelState(int id, PlayerCtrl owner):base(id,owner) {
}
public override void OnEnter(params object[] args)
{
base.OnEnter(args);
m_owner.ani.Play("Idle");
}
public override void OnStay(params object[] args)
{
base.OnStay(args);
if (!m_owner.ani.IsPlaying("Idle")) {
OnExit();
}
}
public override void OnExit(params object[] args)
{
base.OnExit(args);
}
}
Attack:
public class AttackState : StateTemplate<PlayerCtrl> {
public AttackState(int id, PlayerCtrl owner):base(id,owner) {
}
public override void OnEnter(params object[] args)
{
base.OnEnter(args);
m_owner.ani.Play("Attack");
}
public override void OnStay(params object[] args)
{
base.OnStay(args);
if (!m_owner.ani.IsPlaying("Attack"))
{
OnExit();
}
}
public override void OnExit(params object[] args)
{
base.OnExit(args);
m_owner.state = PlayerStates.Idle;
}
}
推荐阅读
-
生命周期组件框架:生命周期描述语言——可继承状态机示例 博客分类: 软件设计 javaLifecycle生命周期状态机State Machine
-
生命周期组件框架:带有多状态机的单实现类 博客分类: 软件设计 JavaLifecycleStateMachine状态机生命周期
-
生命周期组件框架:生命周期描述语言——复合状态机示例 博客分类: 软件设计 JavaLifecycle状态机生命周期生命周期描述语言
-
生命周期组件框架:生命周期描述语言——复合状态机示例 博客分类: 软件设计 JavaLifecycle状态机生命周期生命周期描述语言
-
生命周期组件框架:生命周期描述语言——生命周期事件示例 博客分类: 软件设计 javaLifecycleState Machine状态机生命周期
-
生命周期组件框架:加强版 UML State Machine:关系型复合状态机服务 示例 博客分类: 软件设计 Java生命周期设计状态转换图框架
-
生命周期组件框架:带有多状态机的单实现类 博客分类: 软件设计 JavaLifecycleStateMachine状态机生命周期
-
生命周期组件框架:加强版 UML State Machine:关系型复合状态机服务 示例 博客分类: 软件设计 Java生命周期设计状态转换图框架
-
使用Akka的有限状态机
-
有限状态机的应用