C#状态机

来源:互联网 发布:杰迈科技 java 编辑:程序博客网 时间:2024/05/17 08:20
状态机可以拆分复杂的控制逻辑到各个状态之中,使之更加清晰,更容易理解

以下是在UNITY3D中的一个实现

using System.Collections;/// <summary>/// 基于字符串标识状态的状态机/// 请自行确保FSMStatus的Name的唯一性/// </summary>public class FSM {    FSMStatus curStatus;// Use this for initializationpublic FSM(){        var t = CoroutineWrapper.Inst;        t.OnPerFrame += Update;    }// Update is called once per framevoid Update () {        if (curStatus != null) {            curStatus.Update();        }}    public void SetStatus(FSMStatus status) {        if (curStatus!=null) {            curStatus.Out();        }        curStatus = status;        curStatus.In();    }}

using System.Collections;/// <summary>/// 基于字符串标识的状态机状态/// </summary>public interface FSMStatus {    string Name {        get;    }// Use this for initialization    void In();// Update is called once per frame    void Update();    void Out();}


using UnityEngine;using System.Collections;using System.Collections.Generic;using System;public class CoroutineWrapper : MonoBehaviour {    #region 单例    static CoroutineWrapper inst;    private readonly static object mutex = new object();    public static CoroutineWrapper Inst {        get {            lock (mutex) {                if (inst == null) {                    var obj = new GameObject("CoroutineWrapper");                    inst = obj.AddComponent<CoroutineWrapper>();                }                return inst;            }        }    }    void Awake() {        inst = this;        DontDestroyOnLoad(this);    }    #endregion    public IEnumerator ExeDelay(int frames,Action ev) {        for (int i = 0; i < frames;i++ ) {            yield return new WaitForEndOfFrame();        }        ev();    }    public IEnumerator ExeDelayS(float sec, Action ev) {        yield return new WaitForSeconds(sec);        ev();;    }    public static void EXES(float sec, Action ev) {        inst.StartCoroutine(inst.ExeDelayS(sec,ev));    }    public static void EXEF(int frames, Action ev) {        inst.StartCoroutine(inst.ExeDelay(frames, ev));    }    public static void EXEE(Func<IEnumerator> ien) {        inst.StartCoroutine(ien());    }    public static void EXEE(Func<object[],IEnumerator> ien,params object[] p) {        inst.StartCoroutine(ien(p));    }    public event Action OnPerFrame;    void Update() {        if (OnPerFrame != null)            OnPerFrame();    }}


使用时,可以跟据自己的需要去编写实现了FSMStatus接口类,来表示各个状态,然后状态间的跳转就被分散到了每个状态的代码之中

0 0
原创粉丝点击