框架搭建
概念
有限状态机(FSM),即在有限的状态里面进行状态的转移,并执行相应状态下的动作。
状态机主要要素有
- 当前状态
- 当前状态下执行的动作
- 切换到下一个状态的条件
- 下一个状态
Animator就是一个状态机模型
状态机架构对现有控制模式的改变
拿角色移动举例
现状
void Update()
{
// Move(-Input.GetAxis("Horizontal"), -Input.GetAxis("Vertical"));
}
//private void Move(float horizontal, float vertical)
//{
// if (Mathf.Abs(horizontal) > 0.5 || Mathf.Abs(vertical) > 0.5)
// {
// this.m_Animator.SetBool("IsRun", true);
// Rotating(horizontal, vertical);
// Vector3 direct = Vector3.zero;
// if (m_Controller.isGrounded)
// {
// direct = new Vector3(transform.forward.x, -1, transform.forward.z);
// }
// direct.y -= 20 * Time.deltaTime;
// m_Controller.Move(direct * speed * Time.deltaTime);
// }
// else
// {
// this.m_Animator.SetBool("IsRun", false);
// }
//}
1.PlayerController 监听键盘事件
2.当用户按下前进按钮,执行Move方法
状态机模式
1.FSM监听键盘事件
2.当用户按下前进按钮后,验证是否满足由 Idle 切换至 Move 状态的条件
3.满足后, 当前状态由Idle变为Move,执行Move状态的Action
4.Move状态调用PlayerController的Move方法进行移动
状态机模式的好处
- 结构清晰,避免程序的复杂性,提高系统的可维护性
- 方便状态的扩展
状态机模式的坏处
- 子类会很多
设计
主要有三大类:
- 控制类,用于控制状态的切换,如上图Animator就是一个控制类
- 状态类,表示当前处于的状态,如Idle, Run
- 条件触发类,就是每个状态之间的转换条件,就是上图中的连线
由于状态机不只是控制角色,也可以用来实现敌人的AI,所以再抽象下
实现
Trigger
负责状态切换检测条件是否满足
TriggerType: 唯一标识,枚举类型
HandleEvaluate : 检测条件是否满足
在派生类中具体实现检查方法
public enum FSMTriggerType
{
CanBeMove,
IsIdle,
}
public abstract class FSMTrigger
{
private List<FSMTrigger> m_SubTriggerList = new List<FSMTrigger>();
public FSMTriggerType TriggerType { get; set; }
public FSMTrigger()
{
Init();
}
public abstract void</