Unity中的狀態模式

菜鳥上路,請多指教

關於Unity3d的狀態模式可以參考wiki官網的教程。裏面說的很詳細,而且有相關的demo。由於我本人比較菜,所以精簡了一下代碼進行學習。製作了一個簡單案例。可訪問百度網盤下載查看。提取碼:i6zh。

使用狀態模式比較核心的爲FSMSystem類、FSMState類、Transition枚舉和StateID枚舉。

一、創建FSMSystem類

using System.Collections.Generic;
using UnityEngine;

public class FSMSystem:MonoBehaviour
{
    private List<FSMState> _stateList= new List<FSMState>();

    private StateID _currentStateID;
    public StateID CurrentStateID { get { return _currentStateID; } }

    private FSMState _currentState;
    public FSMState CurrentState { get { return _currentState; } }

    void Update()
    {
        _currentState.Reason();
        _currentState.Act();
    }

    public void AddState(FSMState state)
    {
        if (_stateList.Count == 0)
        {
            _stateList.Add(state);
            _currentState = state;
            _currentStateID = state.StateID;
            return;
        }

        foreach (FSMState temp in _stateList)
        {
            if (temp.StateID == state.StateID)
            {
                Debug.LogError("FSM ERROR: Impossible to add state " + state.StateID.ToString() +
                               " because state has already been added");
                return;
            }
        }
        _stateList.Add(state);
    }

    public void DeleteState(StateID stateID)
    {
        foreach (FSMState state in _stateList)
        {
            if (state.StateID == stateID)
            {
                _stateList.Remove(state);
                return;
            }
        }
        Debug.LogError("FSM ERROR: Impossible to delete state " + stateID.ToString() +
                       ". It was not on the list of states");
    }

    public void PerformTransition(Transition trans)
    {
        StateID stateID = _currentState.GetOutputState(trans);

        if (StateID.NullStateID == stateID) return;

        _currentStateID = stateID;

        foreach (FSMState state in _stateList)
        {
            if (state.StateID == _currentStateID)
            {
                _currentState.DoBeforeLeaving();
                _currentState = state;
                _currentState.DoBeforeEntering();
                break;
            }
        }
    }
}

二、創建Transition枚舉、StateID和FSMState抽象類

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Transition
{
    StartToPlay,
    PlayToStart,
    PlayToOver
}


public enum StateID
{
    NullStateID,
    Start,
    Play,
    Over
}

public abstract class FSMState:MonoBehaviour
{
    protected Dictionary<Transition, StateID> _map = new Dictionary<Transition, StateID>();

    protected StateID _stateID;

    public StateID StateID { get { return _stateID; } }

    public void AddTransition(Transition trans, StateID stateID)
    {
        if (_map.ContainsKey(trans))
        {
            Debug.LogError("FSMState ERROR: State " + _stateID.ToString() + " already has transition " + trans.ToString() +
                           "Impossible to assign to another state");
            return;
        }
        _map.Add(trans, stateID);
    }

    public void DeleteTransition(Transition trans)
    {
        if (_map.ContainsKey(trans))
        {
            _map.Remove(trans);
            return;
        }
        Debug.LogError("FSMState ERROR: Transition " + trans.ToString() + " passed to " + _stateID.ToString() +
                       " was not on the state's transition list");
    }

    public StateID GetOutputState(Transition trans)
    {
        if (_map.ContainsKey(trans))
        {
            return _map[trans];
        }
        return StateID.NullStateID;
    }

    public virtual void DoBeforeEntering() { }

    public virtual void DoBeforeLeaving() { }

    public virtual void Reason() { }

    public virtual void Act() { }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章