예제 #1
0
        private IEnumerator ChangeToNewStateRoutine(StateMapping newState, MonoFSMStateTransitionOption transition)
        {
            destinationState = newState;

            if (currentState != null)
            {
                if (currentState.HasExitRoutine)
                {
                    exitRoutine = currentState.ExitRoutine();

                    if (exitRoutine != null && transition != MonoFSMStateTransitionOption.Overwrite)
                    {
                        yield return(engine.StartCoroutine(exitRoutine));
                    }

                    exitRoutine = null;
                }
                else
                {
                    currentState.ExitCall();
                }

                currentState.Finally();
            }

            lastState    = currentState;
            currentState = destinationState;

            if (currentState != null)
            {
                if (currentState.HasEnterRoutine)
                {
                    enterRoutine = currentState.EnterRoutine();

                    if (enterRoutine != null)
                    {
                        yield return(engine.StartCoroutine(enterRoutine));
                    }

                    enterRoutine = null;
                }
                else
                {
                    currentState.EnterCall();
                }

                if (OnFSMStateChangedEventHandler != null)
                {
                    OnFSMStateChangedEventHandler((T)currentState.state);
                }
            }

            isInTransition = false;
        }
예제 #2
0
        public void ChangeState(T newState, MonoFSMStateTransitionOption transition)
        {
            if (stateLookup == null)
            {
                throw new Exception("没有配置状态机的状态,请调用Init方法进行初始化");
            }

            if (!stateLookup.ContainsKey(newState))
            {
                throw new Exception("没有定义<<" + newState.ToString() + ">>这个状态");
            }

            var nextState = stateLookup[newState];

            if (currentState == nextState)
            {
                return;
            }

            if (queuedChange != null)
            {
                engine.StopCoroutine(queuedChange);
                queuedChange = null;
            }

            switch (transition)
            {
            case MonoFSMStateTransitionOption.Safe:
                if (isInTransition)
                {
                    if (exitRoutine != null)
                    {
                        destinationState = nextState;
                        return;
                    }

                    if (enterRoutine != null)
                    {
                        queuedChange = WaitForPreviousTransition(nextState);
                        engine.StartCoroutine(queuedChange);
                        return;
                    }
                }
                break;

            case MonoFSMStateTransitionOption.Overwrite:
                if (currentTransition != null)
                {
                    engine.StopCoroutine(currentTransition);
                }
                if (exitRoutine != null)
                {
                    engine.StopCoroutine(exitRoutine);
                }
                if (enterRoutine != null)
                {
                    engine.StopCoroutine(enterRoutine);
                }

                break;
            }


            if ((currentState != null && currentState.HasExitRoutine) || nextState.HasEnterRoutine)
            {
                isInTransition    = true;
                currentTransition = ChangeToNewStateRoutine(nextState, transition);
                engine.StartCoroutine(currentTransition);
            }
            else
            {
                if (currentState != null)
                {
                    currentState.ExitCall();
                    currentState.Finally();
                }

                lastState    = currentState;
                currentState = nextState;
                if (currentState != null)
                {
                    currentState.EnterCall();
                    if (OnFSMStateChangedEventHandler != null)
                    {
                        OnFSMStateChangedEventHandler((T)currentState.state);
                    }
                }
                isInTransition = false;
            }
        }