state machine,状态机就是把character的各个状态,比如move, idle, attack分别写如相应的state script,虽然增加了代码的数量,但是可以让角色状态间的转化结构更加清晰,修改角色的状态也只需要进入相应state的代码中进行修改即可。
state machine主要有三个部分组成,state表示角色的各个状态,比如move, idle, attack等,statemachine负责对state的状态进行变化,然后CharacterController继承StateMachine,负责character的逻辑控控制。
第一部分:State
在unity中新建一个名为State.cs的文件,state为一个abstract类。定义了三个virtual函数,start()函数在state状态新建时运行,update函数在unitController类的update中运行,stop函数在state状态发生改变时运行。
public abstract class State
{
protected UnitController unitController;
protected Animator animator;
protected NavMeshAgent agent;
public State(UnitController unitController)
{
this.unitController = unitController;
}
public virtual void start()
{
}
public virtual void update()
{
}
public virtual void stop()
{
}
}
第二部分:StateMachine
新建文件StateMachine.cs。statemachine负责state状态的管理。
public class StateMachine : MonoBehaviour
{
protected State state;
public void StartState(State state)
{
this.state = state;
state.start();
}
public void ChangeState(State state)
{
this.state.stop();
this.state = state;
state.start();
}
}
第三部分:UnitController
新建UnitController.cs,继承StateMachine,其中的IdleState, AttackState, MoveState继承了abstract类state,里面是角色等待,攻击,移动的逻辑。update()函数中会持续运行当前state的update函数,等于是把需要通过很多if-else函数判断运行的代码分别放入一个个state中运行。
public class UnitController : StateMachine
{
// Start is called before the first frame update
void Start()
{
//set up state
IdleState = new IdleState(this);
AttackState = new AttackState(this);
MoveState = new MoveState(this);
StartState(IdleState);
}
// Update is called once per frame
void Update()
{
state.update();
}
}
第四部分:IdleState
第四部分写一个state的示例。IdleState继承了state类,生成构造函数,重写state内的三个函数start, update, stop。
public class IdleState : State
{
public IdleState(UnitController unitController) : base(unitController)
{
}
public override void start()
{
base.start();
// your code
}
public override void update()
{
base.update();
// your code
}
public override void stop()
{
base.stop();
// your code
}
}
写的比较简单,但需要的代码和结构都写出来了。
参考的文档是State Pattern using Unity