C#状态机简记

非 Y 不嫁゛ 提交于 2019-12-23 00:23:23


本人的状态机使用代码简记。

简介

只是简单地状态转换。

基础状态抽象类

using UnityEngine;

/// <summary>
/// 基础状态机抽象类
/// </summary>
/// <typeparam name="T">其状态衍生类的状态类型枚举</typeparam>
public abstract class BaseState<T> : OnStateEnter, OnStateUpdate, OnStateRepeat, OnStateExit
    where T : struct
{
    public BaseState(Object owner) { m_owner = owner; }
    protected T m_stateType;
    public T StateType { get { return m_stateType; } }
    protected Object m_owner;
    public Object Owner { get { return m_owner; } }
    public virtual void OnEnter() { }
    public virtual void OnUpdate() { }
    public virtual void OnRepeat() { }
    public virtual void OnExit() { }
}

public interface OnStateEnter
{
    void OnEnter();
}
public interface OnStateUpdate
{
    void OnUpdate();
}
public interface OnStateRepeat
{
    void OnRepeat();
}
public interface OnStateExit
{
    void OnExit();
}

状态机父类

using System.Collections.Generic;

/// <summary>
/// 状态机父类
/// </summary>
/// <typeparam name="T">状态机中状态的直接父类</typeparam>
/// <typeparam name="S">状态机中状态的类型枚举</typeparam>
public class FSM<T, S> where T : BaseState<S>
                       where S : struct
{
    /// <summary>
    /// 储存状态的字典
    /// </summary>
    private Dictionary<S, T> m_dic = new Dictionary<S, T>();
    /// <summary>
    /// 当前状态的类型
    /// </summary>
    private S m_currentTYPE;

    /// <summary>
    /// 根据状态类型,返回新建状态对象
    /// </summary>
    /// <param name="type">状态类型</param>
    /// <returns>状态对象</returns>
    protected virtual T GetState(S type)
    {
        return null;
    }

    /// <summary>
    /// 状态机中增加状态
    /// </summary>
    /// <param name="type">添加的状态</param>
    /// <returns>添加成功为true,已存在则添加失败为false</returns>
    public bool AddState(S type)
    {
        if (!m_dic.ContainsKey(type))
        {
            T state = GetState(type);
            if (state == null) return false;
            m_dic[type] = state;
            return true;
        }
        return false;
    }

    /// <summary>
    /// 改变状态
    /// </summary>
    /// <param name="statetype">改变后的状态类型</param>
    /// <returns>转换状态成功返回true,状态不存在或已在该状态则转换状态失败返回false</returns>
    public bool ChangeState(S statetype)
    {
        if (m_dic.ContainsKey(statetype))
        {
            if (m_dic.ContainsKey(m_currentTYPE))
            {
                if (m_dic[m_currentTYPE] == m_dic[statetype])
                {
                    m_dic[m_currentTYPE].OnRepeat();
                    return false;
                }
                m_dic[m_currentTYPE].OnExit();
            }
            m_currentTYPE = statetype;
            m_dic[m_currentTYPE].OnEnter();
            return true;
        }
        return false;
    }

    /// <summary>
    /// 状态Update
    /// </summary>
    public void UpdateState()
    {
        m_dic[m_currentTYPE].OnUpdate();
    }
}

示例

衍生的状态类以及每个状态的枚举。

using UnityEngine;

/// <summary>
/// 应用状态的类型
/// </summary>
public enum AppStateType
{
    None,
    /// <summary>
    /// 登录或创建
    /// </summary>
    LoginAndCreate
}

/// <summary>
/// 应用的状态父类
/// </summary>
public abstract class AppBaseState : BaseState<AppStateType>
{
    public AppBaseState(MonoBehaviour owner) : base(owner)
    {
        m_stateType = AppStateType.None;
        m_owner = owner;
        m_ownerobject = owner.gameObject;
    }
    protected new MonoBehaviour m_owner;
    protected GameObject m_ownerobject;
    public override void OnEnter()
    {
        base.OnEnter();
    }
    public override void OnUpdate()
    {
        base.OnUpdate();
    }
    public override void OnRepeat()
    {
        base.OnRepeat();
    }
    public override void OnExit()
    {
        base.OnExit();
    }
}

衍生类的子类,及每个状态的类

using UnityEngine;

/// <summary>
/// 登录或创建房间
/// </summary>
public class App_LoginAndCreateState : AppBaseState
{
    public App_LoginAndCreateState(MonoBehaviour owner) : base(owner)
    {
        m_stateType = AppStateType.LoginAndCreate;
    }
    public override void OnEnter()
    {
        base.OnEnter();
    }
    public override void OnUpdate()
    {
        base.OnUpdate();
    }
    public override void OnRepeat()
    {
        base.OnRepeat();
    }
    public override void OnExit()
    {
        base.OnExit();
    }
}

对应的状态机,类似所有状态的管理者

using System;
using UnityEngine;

/// <summary>
/// 应用的状态机
/// </summary>
public class AppFSM : FSM<AppBaseState, AppStateType>
{
    protected MonoBehaviour m_owner;

    public AppFSM(MonoBehaviour owner)
    {
        m_owner = owner;
        EventManager.GetInstance().AddEvent<AppStateChangeEvent>(owner.gameObject, (object sender, EventArgs e) => { AppStateChangeEvent sce = (AppStateChangeEvent)e; ChangeState(sce.type); });
        UpdateManager.GetInstance().AddCallBack(UpdateState);
    }

    protected override AppBaseState GetState(AppStateType type)
    {
        switch (type)
        {
            case AppStateType.LoginAndCreate:
                return new App_LoginAndCreateState(m_owner);
        }
        return base.GetState(type);
    }

    public static AppFSM Create(MonoBehaviour mono)
    {
        AppFSM fsm = new AppFSM(mono);
        fsm.AddState(AppStateType.LoginAndCreate);
        return fsm;
    }
}

/// <summary>
/// 状态改变事件参数
/// </summary>
public class AppStateChangeEvent : EventArgs
{
    public AppStateType type;
    public AppStateChangeEvent(AppStateType type)
    {
        this.type = type;
    }
}

其中的EventManager类和AppStateChangeEvent类的内容:点击查看;UpdateManager类的内容:点击查看
函数GetState用于穿件对应的每个状态,使用switch区分每个状态;函数Create则是状态机的静态创建函数,其中要通过AddState函数添加所有用到的状态。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!