一些玩家或者物体的状态可以用状态机来实现,而状态机一般由状态模式这个思想去实现。
大致思路:
Controller:管理器来管理状态的生命周期
Data:用字典来储存状态,以及储存当前的状态(比如说创建,以及删除状态)
Factroy:状态工厂
Satat:具体状态
Config:用枚举类型来表示所有的状态,并且用枚举类型来判断一个状态时候可以转换(当添加新状态时,只需再在枚举类型里面注册即可)
Controller脚本:
public class PlayerStateController : MonoBehaviour
{
protected Dictionary<PlayerState, PlayerBaseState> statesDic;
protected PlayerStateData stateData;
protected PlayerStateFactory stateFactory;
public PlayerBaseState currentState;
protected void Awake()
{
Create();
Init();
}
protected void Create()
{
stateFactory = new PlayerStateFactory();
stateData = new PlayerStateData();
}
protected void Init()
{
stateFactory.Init(stateData);
stateData.Init(stateFactory);
statesDic = stateData.GetStateDic();
currentState = stateData.GetCurrentState();
}
protected void Update()
{
currentState.UpdateState();
}
public void ChanageState()
{
}
}
Data:
public class PlayerStateData
{
protected Dictionary<PlayerState, PlayerBaseState> statesDic = new Dictionary<PlayerState, PlayerBaseState>();
protected PlayerState currentStateEnum;
protected PlayerStateFactory stateFactory;
public PlayerStateData()
{
currentStateEnum = PlayerState.Idle;
}
public void Init(PlayerStateFactory factory)
{
stateFactory = factory;
CreateNewState(currentStateEnum);
}
public Dictionary <PlayerState, PlayerBaseState> GetStateDic()
{
return statesDic;
}
public void AddState(PlayerState stateEnum, PlayerBaseState state)
{
if (statesDic.ContainsKey(stateEnum))
return;
statesDic.Add(stateEnum, state);
}
public void RemoveState(PlayerState stateEnum)
{
if (!statesDic.ContainsKey(stateEnum))
return;
statesDic.Remove(stateEnum);
}
public PlayerBaseState GetCurrentState()
{
return statesDic[currentStateEnum];
}
public PlayerBaseState SetCurrentState(PlayerState state)
{
currentStateEnum = state;
return statesDic[currentStateEnum];
}
public void CreateNewState(PlayerState newStateEnum)
{
if (statesDic.ContainsKey(newStateEnum))
return;
PlayerBaseState state = stateFactory.CreateState(newStateEnum);
AddState(newStateEnum, state);
}
}
Factroy:
public class PlayerStateFactory
{
private PlayerStateData _stateData;
public void Init(PlayerStateData data)
{
_stateData = data;
}
public PlayerBaseState CreateState(PlayerState stateEnum)
{
switch (stateEnum)
{
case PlayerState.Idle:
return new PlayerIdleState(stateEnum, _stateData);
case PlayerState.Run:
return new PlayerRunState(stateEnum, _stateData);
case PlayerState.Walk:
return new PlayerWalkState(stateEnum, _stateData);
default:
throw new ArgumentOutOfRangeException(nameof(stateEnum), stateEnum, "Invalid state type");
}
}
}
StateBase:
public class PlayerBaseState
{
protected PlayerState playerStateEnum;
protected Dictionary<PlayerState, PlayerBaseState> statesDic;
protected PlayerStateData stateData;
protected PlayerIdleStateChange[] validIdleStateChanges =
(PlayerIdleStateChange[])Enum.GetValues(typeof(PlayerIdleStateChange));
public PlayerBaseState(PlayerState stateEnum , PlayerStateData data )
{
playerStateEnum = stateEnum;
stateData = data;
statesDic = stateData.GetStateDic();
}
public virtual void OnEnterState()
{
stateData.SetCurrentState(playerStateEnum);
}
public virtual void UpdateState()
{
}
public virtual void OnExitState()
{
}
public virtual void ChangeState(PlayerState newStateEnum)
{
if( !IsChangeState(newStateEnum))
return;
if (!statesDic.ContainsKey(newStateEnum))
stateData.CreateNewState(newStateEnum);
OnExitState();
statesDic[newStateEnum].OnEnterState();
}
public virtual bool IsChangeState(PlayerState newStateEnum)
{
return false;
}
}
State:
public PlayerIdleState(PlayerState stateEnum , PlayerStateData data) : base(stateEnum, data)
{
}
public override void UpdateState()
{
Debug.Log("物体处于 Idel状态");
}
public override void ChangeState(PlayerState newState)
{
base.ChangeState(newState);
}
public override bool IsChangeState(PlayerState newState)
{
foreach (PlayerIdleStateChange state in validIdleStateChanges)
{
if((int)newState == (int) state)
return true;
}
return false;
}
}
Config:
public enum PlayerState
{
Idle = 1,
Run = 2,
Walk = 3,
}
public enum PlayerIdleStateChange
{
Run = 2,
Walk = 3
}
public enum PlayerRunStateChange
{
Idle = 1,
Walk = 3,
}
public enum PlayerWalkStateChange
{
Idle = 1,
Run = 2,
}
public class PlayerConfig
{
}