笔者介绍:姜雪伟,IT公司技术合伙人。IT高级讲师,CSDN社区专家,特邀编辑。畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术具体解释》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144、
上篇博客实现了LoginState的封装,事实上作为UI的各个窗体,每一个窗体都相应着自己的State也就是状态类。
这么多状态类,不能鼓孤立的存在着,它也须要我们封装一个状态管理类去处理全部的状态,它的主要功能是注冊状态, 状态之间的切换等操作,该函数继承于单例模式,代码例如以下所看到的:
using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Game.GameState { public enum GameStateType { GS_Continue, GS_Login, GS_User, GS_Lobby, GS_Room, GS_Hero, GS_Loading, GS_Play, GS_Over, } public class GameStateManager : Singleton<GameStateManager> { Dictionary<GameStateType, IGameState> gameStates; IGameState currentState; public GameStateManager() { gameStates = new Dictionary<GameStateType, IGameState>(); IGameState gameState; gameState = new LoginState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new UserState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new LobbyState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new RoomState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new HeroState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new LoadingState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new PlayState(); gameStates.Add(gameState.GetStateType(), gameState); gameState = new OverState(); gameStates.Add(gameState.GetStateType(), gameState); } public IGameState GetCurState() { return currentState; } public void ChangeGameStateTo(GameStateType stateType) { if (currentState != null && currentState.GetStateType() != GameStateType.GS_Loading && currentState.GetStateType() == stateType) return; if (gameStates.ContainsKey(stateType)) { if (currentState != null) { currentState.Exit(); } currentState = gameStates[stateType]; currentState.Enter(); } } public void EnterDefaultState() { ChangeGameStateTo(GameStateType.GS_Login); } public void FixedUpdate(float fixedDeltaTime) { if (currentState != null) { currentState.FixedUpdate(fixedDeltaTime); } } public void Update(float fDeltaTime) { GameStateType nextStateType = GameStateType.GS_Continue; if (currentState != null) { nextStateType = currentState.Update(fDeltaTime); } if (nextStateType > GameStateType.GS_Continue) { ChangeGameStateTo(nextStateType); } } public IGameState getState(GameStateType type) { if (!gameStates.ContainsKey(type)) { return null; } return gameStates[type]; } } }
该类首先定一个枚举用于表示各个状态。然后实现了状态之间的切换功能。接下来我们開始使用我们编写的脚步,实现起来比較简单,新建一个i额场景用于逻辑的编写,定义一个类比方GameLogic,在它的Awake函数和Start函数中分别调用接口例如以下:
void Awake(){ WindowManager.Instance.ChangeScenseToLogin(EScenesType.EST_None); } // Use this for initialization void Start () { GameStateManager.Instance.EnterDefaultState(); }
另外在它的Update函数中要进行状态的更新。函数代码例如以下所看到的:
//更新游戏状态机 GameStateManager.Instance.Update(Time.deltaTime); //UI更新 WindowManager.Instance.Update(Time.deltaTime);
这样就能够实现MVC模式。并将其应用到项目开发中去,各个模块之间使用的是封装的消息传递。减少了模块之间的耦合性。我们使用该模式实现了多款游戏,整体上感觉还是不错的。