菜鸟上路,请多指教
关于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() { }
}