/// <summary> /// 切换GameState /// </summary> /// <param name="force">false时, 如果当前状态为目标状态, 不执行切换, 直接返回当前状态</param> public T EnterState <T>(object userData = null, bool force = false) where T : GameStateBase { if (force == false) { // 如果当前状态为目标状态, 直接返回 if (currentState != null && typeof(T) == currentState.GetType()) { return(currentState as T); } } GameStateBase oldState = currentState; currentState = rootGo.AddComponent <T>(); currentState.MachineManager = this; currentState.Create(userData); if (oldState != null) { oldState.PrepareExit(); } currentState.PrepareEnter(); if (oldState != null) { var oldStateType = oldState.StateType; oldState.Exit(); // 记录上次的状态 stateChangingContex.RecordLastState(oldStateType); } currentState.Enter(); if (oldState != null) { oldState.DoneExit(); oldState.Dispose(); GameObject.Destroy(oldState); } currentState.DoneEnter(); return(currentState as T); }
//private void InitialiseTransitions() //{ // transitions = new Dictionary<StateTransition<System.Type, Command>, System.Type> // { // /* Initial Game State */ // { new StateTransition<System.Type, Command>(typeof(GameStateInit), Command.End), typeof(GameStateMenuMain) }, // /*Main Menu*/ // { new StateTransition<System.Type, Command>(typeof(GameStateMenuMain), Command.Begin), typeof(GameStateEndless) }, // /*Endless*/ // { new StateTransition<System.Type, Command>(typeof(GameStateEndless), Command.QuitLevel), typeof(GameStateMenuMain) }, // { new StateTransition<System.Type, Command>(typeof(GameStateEndless), Command.End), typeof(GameStateEndlessScoreboard) }, // // { new StateTransition<System.Type, Command>(typeof(GameStateEndless), Command.End), typeof(GameStateMenuMain) }, // /*Endless Scoreboard*/ // { new StateTransition<System.Type, Command>(typeof(GameStateEndlessScoreboard), Command.End), typeof(GameStateMenuMain) }, // { new StateTransition<System.Type, Command>(typeof(GameStateEndlessScoreboard), Command.Begin), typeof(GameStateMenuMain) }, // { new StateTransition<System.Type, Command>(typeof(GameStateMenuMain), Command.Edit), typeof(GameStateEdit) } // }; // // NOTE: Could change the value of an entry at runtime, if necessary // // NOTE: It would also be possible to use a function/ delegate call or other type for the value // // https://stackoverflow.com/questions/20983342/how-to-store-a-type-not-type-object-for-future-use // // https://social.msdn.microsoft.com/Forums/en-US/0e4a2fc8-1db3-4093-8b83-83c598044917/syntax-help-calling-a-delegate-from-a-dictionary?forum=csharplanguage // // Note: May want to prevent/remove duplicate values (could use a custom "Add" method to check for conflicts) //} //public enum Events { LaunchApplication, CloseApplication, OpenMainMenu, OpenScoreMenu, StartGame, QuitGame } #region External Events public bool ProcessCommand(Command newCommand) { if (newCommand.IsTransitionCommand()) // Using an extension method to test whether the manager should look for a transition { StateTransition <System.Type, Command> transitionToFind = new StateTransition <System.Type, Command>(currentGameState.GetType(), newCommand); TransitionData <GameStateBase> outTransitionData; if (currentGameState.StateTransition(newCommand, out outTransitionData)) { GameStateBase newState = (GameStateBase)System.Activator.CreateInstance(outTransitionData.GetStateType()); ChangeGameState(newState); return(true); } else { Debug.LogWarning("GameManager: Command " + newCommand + " process failed - no possible transition found for state " + currentGameState.GetType().ToString()); return(false); } //if (transitions.ContainsKey(transitionToFind)) // Check whether a rule exists for this Gamestate //{ // GameStateBase newState = (GameStateBase)System.Activator.CreateInstance(transitions[transitionToFind]); // ChangeGameState(newState); // return true; //} //else //{ // Debug.LogWarning("GameManager: Command process failed - no possible transition found"); // return false; //} } else { switch (newCommand) { case (Command.BackMenu): Debug.Log("Back Menu Switch Called"); //currentGameState.BackMenu(); break; case (Command.NextMenu): Debug.Log("Next Menu Switch Called"); currentGameState.NextMenu(); break; default: return(false); } return(true); } }
public Type GetStateType() => state.GetType();