NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Fsm/NStateMachine.cs

151 lines
3.6 KiB
C#
Raw Normal View History

2023-08-22 19:08:45 +08:00
using System.Collections.Generic;
using UnityEngine;
namespace LTGame
{
2023-10-19 15:00:19 +08:00
public class NStateMachine<T> where T : NBaseState
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
private Dictionary<int, T> _state;
2023-08-22 19:08:45 +08:00
public NStateMachine()
{
2023-10-19 15:00:19 +08:00
_state = new Dictionary<int, T>();
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
public T currentState { get; private set; }
public T lastState { get; private set; }
2023-08-22 19:08:45 +08:00
private int _forceChangeStateId = 0;
private object _forceChangeParam = null;
2023-10-19 15:00:19 +08:00
public bool Add(T state)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (_state.ContainsKey(state.id))
2023-08-22 19:08:45 +08:00
{
return false;
}
2023-10-19 15:00:19 +08:00
_state.Add(state.id, state);
2023-08-22 19:08:45 +08:00
return true;
}
public bool Remove(int id)
{
2023-10-19 15:00:19 +08:00
return _state.Remove(id);
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
public T Find(int id)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (_state.TryGetValue(id, out T find))
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
return find;
2023-08-22 19:08:45 +08:00
}
return null;
}
2023-10-19 15:00:19 +08:00
public bool ChangeState(int id,
object param = null)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
var state = Find(id);
2023-08-22 19:08:45 +08:00
if (state == null)
{
2023-10-19 15:00:19 +08:00
DebugUtil.LogError("NStateMachine.ChangeState: {0} not found", id);
2023-08-22 19:08:45 +08:00
return false;
}
var canChange = true;
2023-10-19 15:00:19 +08:00
if (null != currentState)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (currentState.id == state.id && !state.canReEnter)
2023-08-22 19:08:45 +08:00
{
canChange = false;
}
}
if (!canChange)
{
return false;
}
2023-10-19 15:00:19 +08:00
if (null != currentState)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
currentState.Exit(state, param);
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
lastState = currentState;
currentState = state;
state.Enter(lastState, param);
2023-08-22 19:08:45 +08:00
return true;
}
2023-10-19 15:00:19 +08:00
public void SetForceChangeState(int id,
object param = null)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
_forceChangeStateId = id;
_forceChangeParam = param;
2023-08-22 19:08:45 +08:00
}
public void LogicUpdate(float dt)
{
2023-10-19 15:00:19 +08:00
if (currentState == null)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (_forceChangeStateId != 0)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
ChangeState(_forceChangeStateId, _forceChangeParam);
_forceChangeStateId = 0;
_forceChangeParam = null;
OnRunning(dt);
2023-08-22 19:08:45 +08:00
}
return;
}
2023-10-19 15:00:19 +08:00
if (_forceChangeStateId != 0)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (_forceChangeStateId == currentState.id)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
if (currentState.canReEnter)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
ChangeState(_forceChangeStateId, _forceChangeParam);
2023-08-22 19:08:45 +08:00
}
}
else
{
2023-10-19 15:00:19 +08:00
ChangeState(_forceChangeStateId, _forceChangeParam);
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
_forceChangeStateId = 0;
_forceChangeParam = null;
OnRunning(dt);
2023-08-22 19:08:45 +08:00
return;
}
2023-10-19 15:00:19 +08:00
var nextState = currentState.GetNextState();
2023-08-22 19:08:45 +08:00
if (nextState != 0)
{
2023-10-19 15:00:19 +08:00
ChangeState(nextState);
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
OnRunning(dt);
2023-08-22 19:08:45 +08:00
}
public void OnRunning(float dt)
{
2023-10-19 15:00:19 +08:00
if (null == currentState)
2023-08-22 19:08:45 +08:00
{
return;
}
2023-10-19 15:00:19 +08:00
currentState.Run(dt);
2023-08-22 19:08:45 +08:00
}
2024-11-14 14:22:30 +08:00
public void Exit()
{
if (null != currentState)
{
currentState.Exit(null, null);
2025-05-07 13:44:18 +08:00
currentState = null;
2024-11-14 14:22:30 +08:00
}
}
2023-08-22 19:08:45 +08:00
}
}