private IEnumerator ChangeToNewStateRoutine(StateMapping newState) { _destinationState = newState; //Chache this so that we can overwrite it and hijack a transition if (CurrentStateMap != null) { if (CurrentStateMap.HasExitRoutine) { _exitRoutine = CurrentStateMap.ExitRoutine(); if (_exitRoutine != null) //Don't wait for exit if we are overwriting { yield return(_engine.StartCoroutine(_exitRoutine)); } _exitRoutine = null; } else { CurrentStateMap.ExitCall(); } CurrentStateMap.Finally(); } _lastState = CurrentStateMap; CurrentStateMap = _destinationState; if (CurrentStateMap != null) { if (CurrentStateMap.HasEnterRoutine) { _enterRoutine = CurrentStateMap.EnterRoutine(); if (_enterRoutine != null) { yield return(_engine.StartCoroutine(_enterRoutine)); } _enterRoutine = null; } else { CurrentStateMap.EnterCall(); } //Broadcast change only after enter transition has begun. if (Changed != null) { Changed((T)CurrentStateMap.State); } } _isInTransition = false; }
public void ChangeState(T newState) { if (_stateLookup == null) { throw new Exception( "States have not been configured, please call initialized before trying to set state"); } if (!_stateLookup.ContainsKey(newState)) { throw new Exception("No state with the name " + newState + " can be found. Please make sure you are called the correct type the statemachine was initialized with"); } var nextState = _stateLookup[newState]; if (CurrentStateMap == nextState) { return; } //Cancel any queued changes. if (_queuedChange != null) { _engine.StopCoroutine(_queuedChange); _queuedChange = null; } if (_isInTransition) { if (_exitRoutine != null) //We are already exiting current state on our way to our previous target state { //Overwrite with our new target _destinationState = nextState; return; } if (_enterRoutine != null) //We are already entering our previous target state. Need to wait for that to finish and call the exit routine. { //Damn, I need to test this hard _queuedChange = WaitForPreviousTransition(nextState); _engine.StartCoroutine(_queuedChange); return; } } if ((CurrentStateMap != null && CurrentStateMap.HasExitRoutine) || nextState.HasEnterRoutine) { _isInTransition = true; _currentTransition = ChangeToNewStateRoutine(nextState); _engine.StartCoroutine(_currentTransition); } else { if (CurrentStateMap != null) { CurrentStateMap.ExitCall(); CurrentStateMap.Finally(); } _lastState = CurrentStateMap; CurrentStateMap = nextState; if (CurrentStateMap != null) { CurrentStateMap.EnterCall(); if (Changed != null) { Changed((T)CurrentStateMap.State); } } _isInTransition = false; } }