|
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using UnityEngine;
-
- public class FiniteStateMachine : MonoBehaviour
- {
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event FiniteStateMachine.StatesInitializedEventHandler StatesInitializedEvent;
-
- private void FireStatesInitializedEvent()
- {
- if (this.StatesInitializedEvent != null)
- {
- this.StatesInitializedEvent();
- }
- }
-
- //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public event FiniteStateMachine.StateSwitched StateSwitchedEvent;
-
- private void FireStateSwitchedEvent(State oldState, State newState)
- {
- if (this.StateSwitchedEvent != null)
- {
- this.StateSwitchedEvent(oldState, newState);
- }
- }
-
- private void Start()
- {
- this.InitStatesDict();
- this.SwitchState(this._startState);
- this.AreStatesInitialized = true;
- this.FireStatesInitializedEvent();
- }
-
- public State CurrentState { get; private set; }
-
- public bool AreStatesInitialized { get; private set; }
-
- public State GetState(Type stateType)
- {
- if (!this._statesDict.ContainsKey(stateType.Name))
- {
- UnityEngine.Debug.LogError(string.Format("Requested state {0} does not exist.", stateType.Name));
- return null;
- }
- return this._statesDict[stateType.Name];
- }
-
- public T GetState<T>() where T : State
- {
- State state = this.GetState(typeof(T));
- return state as T;
- }
-
- public void SwitchState(string newStateName)
- {
- if (string.IsNullOrEmpty(newStateName))
- {
- UnityEngine.Debug.LogError("FiniteStateMachine.SwitchState() new state name not valid");
- return;
- }
- if (!this._statesDict.ContainsKey(newStateName))
- {
- UnityEngine.Debug.LogError(string.Format("Requested state {0} does not exist.", newStateName));
- return;
- }
- if (this.CurrentState != null && newStateName == this.CurrentState.GetType().Name)
- {
- UnityEngine.Debug.Log(string.Format("FSM is already in state {0} and cannot switch.", newStateName));
- return;
- }
- State currentState = this.CurrentState;
- State state = this._statesDict[newStateName];
- if (this.CurrentState)
- {
- this.CurrentState.Leave(state);
- this.CurrentState.enabled = false;
- }
- GameEvents.Invoke<UnemiShouldCloseEvent>(new UnemiShouldCloseEvent(this));
- this.CurrentState = state;
- this.CurrentState.enabled = true;
- this.CurrentState.Enter(currentState);
- if (this.CurrentState is PopupBaseState)
- {
- this.CurrentState.transform.parent.SetAsLastSibling();
- }
- this.FireStateSwitchedEvent(currentState, state);
- }
-
- public T SwitchState<T>() where T : State
- {
- this.SwitchState(typeof(T).Name);
- return this.CurrentState as T;
- }
-
- public void SwitchState(State s)
- {
- if (s == null)
- {
- UnityEngine.Debug.LogError("Cannot switch to a null state.");
- }
- else
- {
- this.SwitchState(s.GetType().Name);
- }
- }
-
- private void InitStatesDict()
- {
- this._statesDict.Clear();
- int i = 0;
- int num = this._states.Length;
- while (i < num)
- {
- State state = this._states[i];
- string name = state.GetType().Name;
- if (!this._statesDict.ContainsKey(name))
- {
- this._statesDict.Add(name, state);
- state.fsm = this;
- state.enabled = false;
- state.Init();
- }
- i++;
- }
- }
-
- [SerializeField]
- private State[] _states;
-
- [SerializeField]
- private State _startState;
-
- private readonly Dictionary<string, State> _statesDict = new Dictionary<string, State>();
-
- public delegate void StatesInitializedEventHandler();
-
- public delegate void StateSwitched(State oldState, State newState);
- }
|