菜鳥上路,請多指教
關於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() { }
}