笔者介绍:姜雪伟,IT公司技术合伙人。IT高级讲师,优快云社区专家,特邀编辑。畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术具体解释》电子工业出版社等。
优快云视频网址:http://edu.youkuaiyun.com/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模式。并将其应用到项目开发中去,各个模块之间使用的是封装的消息传递。减少了模块之间的耦合性。我们使用该模式实现了多款游戏,整体上感觉还是不错的。