142 lines
3.4 KiB
C#
142 lines
3.4 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace LTGame
|
|
{
|
|
|
|
public class NStateMachine<T> where T : NBaseState
|
|
{
|
|
|
|
private Dictionary<int, T> _state;
|
|
|
|
public NStateMachine()
|
|
{
|
|
_state = new Dictionary<int, T>();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
}
|
|
|
|
}
|