StateMachine.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using UnityEngine;
  6. public class StateMachine : BaseBehaviour
  7. {
  8. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  9. public event EventHandler<StateMachine.StateEventArgs> OnEnter;
  10. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  11. public event EventHandler<StateMachine.StateEventArgs> OnExit;
  12. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  13. public event EventHandler<StateMachine.StateEventArgs> StateUpdate;
  14. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  15. public event EventHandler<StateMachine.TransferEventArgs> OnTransfer;
  16. public string currentState { get; private set; }
  17. private void Awake()
  18. {
  19. string.Intern("__Empty__");
  20. this.AddState("__Empty__");
  21. this.currentState = "__Empty__";
  22. }
  23. private void Update()
  24. {
  25. StateMachine.State state;
  26. if (!string.IsNullOrEmpty(this.currentState) && this.currentState != "__Empty__" && this.states.TryGetValue(this.currentState, out state))
  27. {
  28. this.OnTrigger(this.StateUpdate, state.name);
  29. this.OnTrigger(state.StateUpdate, state.name);
  30. }
  31. }
  32. public void AddStates(Type type)
  33. {
  34. this.AddStates(Enum.GetNames(type));
  35. }
  36. public StateMachine.State AddState(Enum state)
  37. {
  38. return this.AddState(state.ToString());
  39. }
  40. private StateMachine.State AddState(string name)
  41. {
  42. if (this.states.ContainsKey(name))
  43. {
  44. this.Info("在状态机中添加了同名方法" + name);
  45. }
  46. StateMachine.State state = new StateMachine.State
  47. {
  48. name = name
  49. };
  50. this.states[name] = state;
  51. return state;
  52. }
  53. public void AddStates(string[] names)
  54. {
  55. for (int i = 0; i < names.Length; i++)
  56. {
  57. this.AddState(names[i]);
  58. }
  59. }
  60. public StateMachine.State GetState(string name)
  61. {
  62. return this.states[name];
  63. }
  64. public StateMachine.State GetState(Enum name)
  65. {
  66. return this.GetState(name.ToString());
  67. }
  68. public void SetState(Enum nextState)
  69. {
  70. this.SetState(nextState.ToString());
  71. }
  72. public void SetState(string nextState)
  73. {
  74. this.Info(string.Format("当前状态为{0},准备转换状态为{1}", this.currentState, nextState));
  75. if (this.currentState == "__Empty__")
  76. {
  77. this.OnTrigger(this.states[nextState].OnEnter, this.states[nextState].name);
  78. this.OnTrigger(this.OnEnter, this.states[nextState].name);
  79. this.currentState = nextState;
  80. return;
  81. }
  82. this.OnTrigger(this.states[this.currentState].OnExit, this.states[this.currentState].name);
  83. this.OnTrigger(this.OnExit, this.states[this.currentState].name);
  84. this.OnTrigger(this.OnTransfer, this.currentState, nextState);
  85. try
  86. {
  87. this.OnTrigger(this.states[nextState].OnEnter, this.states[nextState].name);
  88. }
  89. catch (KeyNotFoundException)
  90. {
  91. Log.Error(nextState);
  92. throw;
  93. }
  94. this.OnTrigger(this.OnEnter, this.states[nextState].name);
  95. this.currentState = nextState;
  96. }
  97. public void SetStateDelay(Enum nextState, float time)
  98. {
  99. this._nextState = nextState;
  100. base.StartCoroutine(this.SetStateDelayCoroutine(time));
  101. }
  102. private IEnumerator SetStateDelayCoroutine(float time)
  103. {
  104. yield return new WaitForSeconds(time);
  105. this.SetState(this._nextState);
  106. yield break;
  107. }
  108. private void OnTrigger(EventHandler<StateMachine.StateEventArgs> handler, string lastState)
  109. {
  110. if (handler != null)
  111. {
  112. StateMachine.StateEventArgs e = new StateMachine.StateEventArgs(lastState);
  113. handler(this, e);
  114. }
  115. }
  116. private void OnTrigger(EventHandler<StateMachine.TransferEventArgs> handler, string lastState, string nextState)
  117. {
  118. if (handler != null)
  119. {
  120. StateMachine.TransferEventArgs e = new StateMachine.TransferEventArgs(lastState, nextState);
  121. handler(this, e);
  122. }
  123. }
  124. private void Info(object obj)
  125. {
  126. if (this._logLevel <= Log.LogLevel.Info)
  127. {
  128. Log.Info(obj);
  129. }
  130. }
  131. public Dictionary<string, StateMachine.State> states = new Dictionary<string, StateMachine.State>();
  132. private const string EmptyState = "__Empty__";
  133. private Enum _nextState;
  134. private Log.LogLevel _logLevel = Log.LogLevel.Warning;
  135. public class State
  136. {
  137. public EventHandler<StateMachine.StateEventArgs> OnEnter;
  138. public EventHandler<StateMachine.StateEventArgs> OnExit;
  139. public EventHandler<StateMachine.StateEventArgs> StateUpdate;
  140. public string name;
  141. }
  142. public class TransferEventArgs : EventArgs
  143. {
  144. public TransferEventArgs(string lastState, string nextState)
  145. {
  146. this.lastState = lastState;
  147. this.nextState = nextState;
  148. }
  149. public readonly string lastState;
  150. public readonly string nextState;
  151. }
  152. public class StateEventArgs : EventArgs
  153. {
  154. public StateEventArgs(string state)
  155. {
  156. this.state = state;
  157. }
  158. public readonly string state;
  159. }
  160. }