版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/stalendp/article/details/78025509
游戏中的逻辑少不了用状态机。但是面对复杂的状态(比如战斗角色控制,复杂的UI状态控制等),用状态机模式是最合适不过的了。结合C#的特点,我对状态机模式进行了简化。下面是个例子:
public abstract class FSMManager<T> {
public State current { get; protected set; }
public abstract void Start();
public class State {
private string name;
public System.Action OnEnter = FuncVoid;
public System.Action OnTick = FuncVoid;
public System.Action OnExit = FuncVoid;
public System.Action<T, object[]> SetTrigger = FuncVoid2;
}
public static void FuncVoid() { }
public static void FuncVoid2(T type, object[] ps) { }
public void SetTrigger(T type, Object[] ps = null) {
current.SetTrigger(type, ps);
}
public void SetState(State state) {
current.OnExit();
current = state;
current.OnEnter();
}
public void OnTick() {
current.OnTick();
}
}
使用:
public class MyFSM : FSMManager<MyFSM.Type> {
public enum Type {
Type1,
Type2,
Typ3
}
public int count = 0;
public State state1, state2;
public MyFSM() {
current = state1;
}
public override void Start() {
current = state1;
state1.OnEnter();
}
}
public string test1= "111", test2 = "222";
public MyFSM fsm;
[Test]
public void NewEditModeTestSimplePasses() {
// Use the Assert class to test conditions.
fsm = new MyFSM() {
state1 = new FSMManager<MyFSM.Type>.State() {
OnEnter = delegate {
Debug.Log("===>> " + fsm.count);
if (fsm.count++ < 2) {
fsm.SetState(fsm.state1);
} else {
fsm.SetState(fsm.state2);
}
},
},
state2 = new FSMManager<MyFSM.Type>.State() {
OnEnter = delegate {
Debug.Log("===>>>" + test2);
}
},
};
fsm.Start();
}
================ 另外的例子 ==================
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public abstract class FSM<T> : MonoBehaviour {
static void FuncVoid() { }
static void FuncVoid2(T type, object[] ps) { }
protected State state;
public class State {
public System.Action OnEnter = FuncVoid;
public System.Action OnTick = FuncVoid;
public System.Action OnExit = FuncVoid;
public System.Action<T, object[]> SetTrigger = FuncVoid2;
public int param;
}
public void setState(State _state) {
state.OnExit();
state = _state;
state.OnEnter();
}
protected void doStart(State ss) {
state = initState();
StartCoroutine(OnTick());
}
IEnumerator OnTick() {
while (true) {
state.OnTick();
yield return null;
}
}
protected abstract State initState();
}
public class UILoading : FSM<UILoading.MyEvent> {
public enum MyEvent {
Trig1,
Trig2,
Trig3
}
State state1, state2;
public Animator anim;
public Button btnLocal;
public Button btnOnline;
public Button btnOptions;
void printOK(string who) {
Debug.LogError("=====OKOKOK!! " + who);
}
private void Awake() {
doStart(state1);
btnLocal.onClick.AddListener(delegate {
state.SetTrigger(MyEvent.Trig1, null);
});
btnOnline.onClick.AddListener(delegate {
state.SetTrigger(MyEvent.Trig2, null);
});
anim.StopPlayback();
btnOptions.onClick.AddListener(delegate {
anim.StartPlayback();
Debug.LogError("======");
});
}
protected override State initState() {
state1 = new State() {
param = 7,
OnEnter = delegate {
state1.param = 5;
printOK("state1");
},
OnTick = delegate {
state1.param--;
Debug.LogError("State1 tick : " + state1.param);
if (state1.param <= 0) {
setState(state2);
}
},
OnExit = delegate {
Debug.LogError("<<< State1 exit");
}
};
state2 = new State() {
OnEnter = delegate {
printOK("state2");
},
OnTick = delegate {
Debug.LogError("state2 Tick");
},
OnExit = delegate {
Debug.LogError("<<< State2 exit");
},
SetTrigger = (e, ps) => {
switch (e) {
case MyEvent.Trig1:
setState(state1);
break;
case MyEvent.Trig2:
printOK("!!!!!");
break;
}
}
};
return state1;
}
}