You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

143 line
3.5 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using UnityEngine;
  5. public class FiniteStateMachine : MonoBehaviour
  6. {
  7. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  8. public event FiniteStateMachine.StatesInitializedEventHandler StatesInitializedEvent;
  9. private void FireStatesInitializedEvent()
  10. {
  11. if (this.StatesInitializedEvent != null)
  12. {
  13. this.StatesInitializedEvent();
  14. }
  15. }
  16. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  17. public event FiniteStateMachine.StateSwitched StateSwitchedEvent;
  18. private void FireStateSwitchedEvent(State oldState, State newState)
  19. {
  20. if (this.StateSwitchedEvent != null)
  21. {
  22. this.StateSwitchedEvent(oldState, newState);
  23. }
  24. }
  25. private void Start()
  26. {
  27. this.InitStatesDict();
  28. this.SwitchState(this._startState);
  29. this.AreStatesInitialized = true;
  30. this.FireStatesInitializedEvent();
  31. }
  32. public State CurrentState { get; private set; }
  33. public bool AreStatesInitialized { get; private set; }
  34. public State GetState(Type stateType)
  35. {
  36. if (!this._statesDict.ContainsKey(stateType.Name))
  37. {
  38. UnityEngine.Debug.LogError(string.Format("Requested state {0} does not exist.", stateType.Name));
  39. return null;
  40. }
  41. return this._statesDict[stateType.Name];
  42. }
  43. public T GetState<T>() where T : State
  44. {
  45. State state = this.GetState(typeof(T));
  46. return state as T;
  47. }
  48. public void SwitchState(string newStateName)
  49. {
  50. if (string.IsNullOrEmpty(newStateName))
  51. {
  52. UnityEngine.Debug.LogError("FiniteStateMachine.SwitchState() new state name not valid");
  53. return;
  54. }
  55. if (!this._statesDict.ContainsKey(newStateName))
  56. {
  57. UnityEngine.Debug.LogError(string.Format("Requested state {0} does not exist.", newStateName));
  58. return;
  59. }
  60. if (this.CurrentState != null && newStateName == this.CurrentState.GetType().Name)
  61. {
  62. UnityEngine.Debug.Log(string.Format("FSM is already in state {0} and cannot switch.", newStateName));
  63. return;
  64. }
  65. State currentState = this.CurrentState;
  66. State state = this._statesDict[newStateName];
  67. if (this.CurrentState)
  68. {
  69. this.CurrentState.Leave(state);
  70. this.CurrentState.enabled = false;
  71. }
  72. GameEvents.Invoke<UnemiShouldCloseEvent>(new UnemiShouldCloseEvent(this));
  73. this.CurrentState = state;
  74. this.CurrentState.enabled = true;
  75. this.CurrentState.Enter(currentState);
  76. if (this.CurrentState is PopupBaseState)
  77. {
  78. this.CurrentState.transform.parent.SetAsLastSibling();
  79. }
  80. this.FireStateSwitchedEvent(currentState, state);
  81. }
  82. public T SwitchState<T>() where T : State
  83. {
  84. this.SwitchState(typeof(T).Name);
  85. return this.CurrentState as T;
  86. }
  87. public void SwitchState(State s)
  88. {
  89. if (s == null)
  90. {
  91. UnityEngine.Debug.LogError("Cannot switch to a null state.");
  92. }
  93. else
  94. {
  95. this.SwitchState(s.GetType().Name);
  96. }
  97. }
  98. private void InitStatesDict()
  99. {
  100. this._statesDict.Clear();
  101. int i = 0;
  102. int num = this._states.Length;
  103. while (i < num)
  104. {
  105. State state = this._states[i];
  106. string name = state.GetType().Name;
  107. if (!this._statesDict.ContainsKey(name))
  108. {
  109. this._statesDict.Add(name, state);
  110. state.fsm = this;
  111. state.enabled = false;
  112. state.Init();
  113. }
  114. i++;
  115. }
  116. }
  117. [SerializeField]
  118. private State[] _states;
  119. [SerializeField]
  120. private State _startState;
  121. private readonly Dictionary<string, State> _statesDict = new Dictionary<string, State>();
  122. public delegate void StatesInitializedEventHandler();
  123. public delegate void StateSwitched(State oldState, State newState);
  124. }