using System.Collections.Generic; using UnityEngine; namespace LTGame { public class NStateMachine where T : NBaseState { private Dictionary _state; public NStateMachine() { _state = new Dictionary(); } public T currentState { get; private set; } public T lastState { get; private set; } private int _forceChangeStateId = 0; private object _forceChangeParam = null; public bool Add(T state) { if (_state.ContainsKey(state.id)) { return false; } _state.Add(state.id, state); return true; } public bool Remove(int id) { return _state.Remove(id); } public T Find(int id) { if (_state.TryGetValue(id, out T find)) { return find; } return null; } public bool ChangeState(int id, object param = null) { var state = Find(id); if (state == null) { DebugUtil.LogError("NStateMachine.ChangeState: {0} not found", id); return false; } var canChange = true; if (null != currentState) { if (currentState.id == state.id && !state.canReEnter) { canChange = false; } } if (!canChange) { return false; } if (null != currentState) { currentState.Exit(state, param); } lastState = currentState; currentState = state; state.Enter(lastState, param); return true; } public void SetForceChangeState(int id, object param = null) { _forceChangeStateId = id; _forceChangeParam = param; } public void LogicUpdate(float dt) { if (currentState == null) { if (_forceChangeStateId != 0) { ChangeState(_forceChangeStateId, _forceChangeParam); _forceChangeStateId = 0; _forceChangeParam = null; OnRunning(dt); } return; } if (_forceChangeStateId != 0) { if (_forceChangeStateId == currentState.id) { if (currentState.canReEnter) { ChangeState(_forceChangeStateId, _forceChangeParam); } } else { ChangeState(_forceChangeStateId, _forceChangeParam); } _forceChangeStateId = 0; _forceChangeParam = null; OnRunning(dt); return; } var nextState = currentState.GetNextState(); if (nextState != 0) { ChangeState(nextState); } OnRunning(dt); } public void OnRunning(float dt) { if (null == currentState) { return; } currentState.Run(dt); } } }