有限状态机FSM
是对行为逻辑的抽象。
在整个FSM架构中
首先有一个状态基类stateObject
里面有三个方法,分别是状态前、状态中、状态后。
所有具体行为类都要继承这个基类,在这三个方法中具体实现各种方法的逻辑。
然后,需要一个stateManager(大脑)状态管理类来管理这些状态,特别注意的是里面changeState方法,他是状态跳转的关键。
至于如果存储各种状态,你可以用list类 ,字典类等等。
写法:
建类:确认一共有几个状态,新建对应的几个类,还有他的Manager(管理类)和父类State
代码:
1.在父类中先public一个管理类类型的变量,为的是让每个状态对应一个状态管理者。然后写状态前,状态中,状态后三个方法。注意这三个方法的类型为virtual,方便子类进行重写。
因为状态前后都只执行一次,所以返回值为void。状态中的返回值类型为该类类型,可以先返回空值。
2.让所有状态类继承该父类,并对里面的方法进行重写。在三个方法中添加自己的行为逻辑。注意在状态中的return中返回this(当前状态自身)
3.写管理类(重点):
1)首先管理类也要继承该父类。可以做成状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用。注意,如果要使用字典必须using System.Collection.Generic。字典写法:Dictionary<string, State> stateDic;
String用来传状态名称,State为当前状态所有对象。然后定义当前状态:State currentState;
和上一个状态:State lastState;
2)在构造器中进行初始化stateDic = new Dictionary<string, State>();
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class StateManager : State
{
//状态管理类 用字典,是功能类
//状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用
Dictionary<string, State> stateDic;
//当前状态
State currentState;
//上一个状态
State lastState;
//初始化放在构造器中
public StateManager()
{
stateDic = new Dictionary<string, State>();
}
//注册状态,需要状态名字和状态参数的形参
public void RegisterState(string stateName, State state)
{
//每一次注册一个状态时,就指定这个状态的状态管理者的字段对应注册的这个对象
//this指代当前类对象实例Dictionary<string, State>(),谁.RegisterState就是谁
//作用是让一个对象的多个状态都指向同一个管理者
state.stateManager = this;
//向状态字典中添加,传递形参状态
stateDic.Add(stateName, state);
}
//设置默认状态,传递状态名为形参
public void SetDefaultState(string stateName)
{
//判断方法列表是否包含这样的一个状态(key值)
if (!stateDic.ContainsKey(stateName))
{
Debug.LogError("状态列表无此状态");
}
//设置默认状态
currentState = stateDic[stateName];
}
//改变状态
public void ChangeState(string stateName)
{
//判断方法列表是否包含这样的一个状态(key值)
//改变状态失败
if (!stateDic.ContainsKey(stateName))
{
Debug.LogError("状态列表无此状态,切换失败");
currentState = lastState;
}
//切换成功,更改状态
currentState = stateDic[stateName];
}
//状态的执行
public void DoState()
{
//第一次执行的时候current是设置的默认状态,lastState是空
if (currentState != lastState)//加入默认状态为sleep//current=sleep;last=null //第2轮.current=eat;last=sleep
{
currentState.EnterState();//sleep的进入方法,只执行一次//current=sleep;last=null
//把后一个状态赋给当前状态,跳出if条件
lastState = currentState;//current=sleep;last=sleep
}
//执行“状态中”
lastState.StayState();//sleep的持续方法 //current=sleep;last=sleep
//退出状态 //sleep切换为eat//current=eat;last=sleep
if (lastState != currentState)//current=eat;last=sleep
{
lastState.ExitState(); //sleep退出
}
}
}
然后新建一个挂在游戏物体上的类
using UnityEngine;
using System.Collections;
public class FSMManager_Boss : MonoBehaviour {
StateManager_Boss manager;
// Use this for initialization
void Start () {
manager = new StateManager_Boss();
// 注册状态
manager.RegisterState("idle", new IdleState_Boss());
manager.RegisterState("run", new RunState_Boss());
manager.RegisterState("attack", new AttackState_Boss());
manager.RegisterState("Death", new DeathState_Boss());
//设置初始状态
manager.SetDefaultState("idle");
}
// Update is called once per frame
void Update () {
manager.DoState();
}
}