大家好,今天要为大家介绍的是游戏中常用的设计模式之状态者模式,这个模式常用于我们Unity3D中的状态机切换,接下来就来看看这个模式的实现 (⊙_⊙)!
状态者模式
定义
每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为。那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码。这样的设计显然违背了开闭原则。状态模式正是用来解决这样的问题的。状态模式将每种状态对应的行为抽象出来成为单独新的对象,这样状态的变化不再依赖于对象内部的行为。
简而言之就是
把状态和逻辑分开,实现代码的解耦,有利与后期新状态的添加。
代码实现
public abstract class FSMState
{
//状态id
private byte stateId ;
public virtual void OnEnterBefore()
{
}
public virtual void CopyState(FSMState BeforeState) { }
public abstract void OnEnter();
public virtual void Update() { }
public virtual void OnLeave() { }
}
↑ 作为各个子类状态的父类,每个子类状态都有进入状态、进入状态后、离开状态的方法
public class AtackFSM: FSMState
{
ParticleEmitter emmitor ;
public override void OnEnter ()
{
}
float timeCount =0 ;
public override void Update()
{
timeCount += Time.deltaTime;
if (timeCount > 0.5f) {
//......
}
}
}
public class WalkFSM: FSMState
{
public override void OnEnter ()
{
// animator.setint()
}
}
↑ 生成 AttackFSM类和 WalkFSM类 ,继承于FSMState。
public class FSMManager
{
private FSMState[] fsmManager;
// 增加了几个state
private byte curAdd ;
// 当前状态Id
public byte curStateId ;
public FSMManager (byte stateNumber)
{
curAdd = 0;
curStateId = 0;
fsmManager = new FSMState[stateNumber];
}
public void AddState(FSMState tmpState)
{
if (curAdd < fsmManager.Length) {
fsmManager [curAdd] = tmpState;
curAdd++;
}
}
public void ChangeState(byte stateId)
{
fsmManager [curStateId].OnLeave ();
fsmManager [stateId].CopyState (fsmManager [curStateId]);
fsmManager [stateId].OnBeforEntor ();
fsmManager [stateId].OnEnter ();
curStateId = stateId;
}
public void Update()
{
fsmManager[curStateId].Update ();
}
}
↑ 建立一个FSMManager管理类,对外提供 AddState 和 ChangeState 接口
public class FSM : MonoBehaviour {
public enum FSMStateId
{
Idle,
Attack,
Walk,
MaxValue
}
FSMManager manager ;
// Use this for initialization
void Start () {
WalkFSM tmpWalk = new WalkFSM ();
AtackFSM tmpAttack = new AtackFSM ();
manager = new FSMManager ((byte)FSMStateId.MaxValue);
manager.AddState (tmpWalk);
manager.AddState (tmpAttack);
}
public void PlayAttack()
{
manager.ChangeState ((byte)FSMStateId.Attack);
}
// Update is called once per frame
void Update () {
manager.Update ();
}
}
↑ 外界调用。
结束语
设计模式对于编程是非常重要的,但我对设计模式的理解还是不够深入的,还是要不停的学习,不停的码代码,才能揭开它的面纱。