Unity3D优化技巧系列(五):架构设计
架构设计也是优化的一种,一款游戏如果没有一个好的架构,程序出现问题很难做到及时的响应,试想一下,如果编程的时候只是为了实现功能而实现功能,到头来就是代码越写越乱,各种功能交织在一起。出现问题后到处找BUG修复,优化就更无从谈起了,谁也不希望把即将上线的项目代码,重新重构一遍,那还不如重新再做一遍,所以架构设计在游戏开发中是非常重要的,而且是必须要掌握的技术。下面重点给读者介绍架构设计中的MVC和FSM架构模式,效果如下所示:
MVC架构模式在前面的优化系列中给读者提过,下面就详细的告诉读者如何编写代码?给读者详细的分析一下,拿窗口的切换进行距离,游戏运行时,首先是创立界面,我们把每个界面作为一个窗口,比如LoginWindow,HeroWindow等。它们也是作为View界面,这样游戏中就会出现很多界面的设计,效果如下所示:
下面分析界面的编写,上文提到的每个UI就是一个Window,也是一个View,这么多View肯定有自己的共性,我们可以将其定义为基类,基类称为BaseWindow,代码编写如下所示:
[csharp] view plain copy 


- namespace Game.View
- {
- public abstract class BaseWindow
- {
- protected Transform mRoot;
- protected EScenesType mScenesType; //场景类型
- protected string mResName; //资源名
- protected bool mResident; //是否常驻
- protected bool mVisible = false; //是否可见
- //类对象初始化
- public abstract void Init();
- //类对象释放
- public abstract void Realse();
- //窗口控制初始化
- protected abstract void InitWidget();
- //窗口控件释放
- protected abstract void RealseWidget();
- //游戏事件注册
- protected abstract void OnAddListener();
- //游戏事件注消
- protected abstract void OnRemoveListener();
- //显示初始化
- public abstract void OnEnable();
- //隐藏处理
- public abstract void OnDisable();
- //每帧更新
- public virtual void Update(float deltaTime) { }
- //取得所以场景类型
- public EScenesType GetScenseType()
- {
- return mScenesType;
- }
- //是否已打开
- public bool IsVisible() { return mVisible; }
- //是否常驻
- public bool IsResident() { return mResident; }
- //显示
- public void Show()
- {
- if (mRoot == null)
- {
- if (Create())
- {
- InitWidget();
- }
- }
- if (mRoot && mRoot.gameObject.activeSelf == false)
- {
- mRoot.gameObject.SetActive(true);
- mVisible = true;
- OnEnable();
- OnAddListener();
- }
- }
- //隐藏
- public void Hide()
- {
- if (mRoot && mRoot.gameObject.activeSelf == true)
- {
- OnRemoveListener();
- OnDisable();
- if (mResident)
- {
- mRoot.gameObject.SetActive(false);
- }
- else
- {
- RealseWidget();
- Destroy();
- }
- }
- mVisible = false;
- }
- //预加载
- public void PreLoad()
- {
- if (mRoot == null)
- {
- if (Create())
- {
- InitWidget();
- }
- }
- }
- //延时删除
- public void DelayDestory()
- {
- if (mRoot)
- {
- RealseWidget();
- Destroy();
- }
- }
- //创建窗体
- private bool Create()
- {
- if (mRoot)
- {
- Debug.LogError("Window Create Error Exist!");
- return false;
- }
- if (mResName == null || mResName == "")
- {
- Debug.LogError("Window Create Error ResName is empty!");
- return false;
- }
- if (GameMethod.GetUiCamera.transform== null)
- {
- Debug.LogError("Window Create Error GetUiCamera is empty! WindowName = " + mResName);
- return false;
- }
- GameObject obj = LoadUiResource.LoadRes(GameMethod.GetUiCamera.transform, mResName);
- if (obj == null)
- {
- Debug.LogError("Window Create Error LoadRes WindowName = " + mResName);
- return false;
- }
- mRoot = obj.transform;
- mRoot.gameObject.SetActive(false);
- return true;
- }
- //销毁窗体
- protected void Destroy()
- {
- if (mRoot)
- {
- LoadUiResource.DestroyLoad(mRoot.gameObject);
- mRoot = null;
- }
- }
- //取得根节点
- public Transform GetRoot()
- {
- return mRoot;
- }
- }
- }
[csharp] view plain copy 


- namespace Game.View
- {
- public class LobbyWindow : BaseWindow
- {
- public LobbyWindow()
- {
- mScenesType = EScenesType.EST_Login; //场景类型
- mResName = GameConstDefine.LoadGameLobbyUI; //资源名字
- mResident = false; //是否常驻内存
- }
- ////////////////////////////继承接口/////////////////////////
- //类对象初始化
- public override void Init()
- {
- EventCenter.AddListener(EGameEvent.eGameEvent_LobbyEnter, Show);
- EventCenter.AddListener(EGameEvent.eGameEvent_LobbyExit, Hide);
- }
- //类对象释放
- public override void Realse()
- {
- EventCenter.RemoveListener(EGameEvent.eGameEvent_LobbyEnter, Show);
- EventCenter.RemoveListener(EGameEvent.eGameEvent_LobbyExit, Hide);
- }
- //窗口控件初始化
- protected override void InitWidget()
- {
- mHomepage = mRoot.FindChild("StartMenuManager/StartMenuBtn/Homepage").GetComponent();
- UIGuideCtrl.Instance.AddUiGuideEventBtn(mHomepage.gameObject);
- mBattle = mRoot.FindChild("StartMenuManager/StartMenuBtn/Battle").GetComponent();
- mMarket = mRoot.FindChild("StartMenuManager/StartMenuBtn/Market").GetComponent();
- mInteraction = mRoot.FindChild("StartMenuManager/StartMenuBtn/Interaction").GetComponent();
- UIGuideCtrl.Instance.AddUiGuideEventBtn(mMarket.gameObject);
- mDiamondText = mRoot.FindChild("Status/Diamond/Label").GetComponent();
- mGoldText = mRoot.FindChild("Status/Gold/Label").GetComponent();
- mSettingBtn = mRoot.FindChild("Status/Setting").GetComponent();
- UIGuideCtrl.Instance.AddUiGuideEventBtn(mBattle.gameObject);
- EventDelegate.Add(mHomepage.onChange, OnHomePageChange);
- EventDelegate.Add(mBattle.onChange, OnBattleChange);
- EventDelegate.Add(mMarket.onChange, OnMarketChange);
- EventDelegate.Add(mInteraction.onChange, OnInteractionChange);
- UIEventListener.Get(mHeadIcon.transform.parent.gameObject).onClick += InfoPersonPress;
- }
- private void InfoPersonPress(GameObject go)
- {
- GameLog.Instance.AddUIEvent(GameLog.UIEventType.UIEventType_PersonalInfo);
- LobbyCtrl.Instance.AskPersonInfo();
- //PresonInfoCtrl.Instance.Enter();
- }
- //窗口控件释放
- protected override void RealseWidget()
- {
- }
- //游戏事件注册
- protected override void OnAddListener()
- {
- EventCenter.AddListener(EGameEvent.eGameEent_ChangeMoney, RefreshMoney);
- EventCenter.AddListener<bool>(EGameEvent.eGameEvent_ReceiveLobbyMsg, NewChat);
- EventCenter.AddListener(EGameEvent.eGameEvent_AddNewMailReq, NoticeNewMail);
- EventCenter.AddListener(EGameEvent.eGameEvent_ChangeNickName,ChangeNickName);
- EventCenter.AddListener(EGameEvent.eGameEvent_ChangeHeadID, ChangeHeadID);
- EventCenter.AddListener(EGameEvent.eGameEvent_ChangeUserLevel, ChangeLevel);
- }
- private void ChangeHeadID()
- {
- mHeadIcon.spriteName = GameUserModel.Instance.GameUserHead.ToString();
- }
- //游戏事件注消
- protected override void OnRemoveListener()
- {
- EventCenter.RemoveListener(EGameEvent.eGameEent_ChangeMoney, RefreshMoney);
- EventCenter.RemoveListener<bool>(EGameEvent.eGameEvent_ReceiveLobbyMsg, NewChat);
- EventCenter.RemoveListener(EGameEvent.eGameEvent_AddNewMailReq, NoticeNewMail);
- EventCenter.RemoveListener(EGameEvent.eGameEvent_ChangeNickName, ChangeNickName);
- EventCenter.RemoveListener(EGameEvent.eGameEvent_ChangeHeadID, ChangeHeadID);
- EventCenter.RemoveListener(EGameEvent.eGameEvent_ChangeUserLevel, ChangeLevel);
- }
- //显示
- public override void OnEnable()
- {
- }
- //隐藏
- public override void OnDisable()
- {
- }
- public void ChangeUserLevel()
- {
- mLevel.text = GameUserModel.Instance.UserLevel.ToString();
- }
- ="white-space:pre"> //回调事件
- public void OnHomePageChange()
- {
- //todo
- mLevel.text = GameUserModel.Instance.UserLevel.ToString();
- mNickName.text = GameUserModel.Instance.GameUserNick;
- mHeadIcon.spriteName = GameUserModel.Instance.GameUserHead.ToString();
- mGold.text = GameUserModel.Instance.mGameUserGold.ToString();
- mDiamond.text = GameUserModel.Instance.mGameUserDmd.ToString();
- VipSignLevel.text = "VIP "+GameUserModel.Instance.GameUserVipLevel.ToString();
- int level = GameUserModel.Instance.UserLevel;
- mLevel.text = level.ToString();
- LevelConfigInfo leveinfo = ConfigReader.GetLevelInfo(level);
- if (leveinfo != null)
- {
- mExp.text = GameUserModel.Instance.GameUserExp + "/" + leveinfo.LevelUpExp;
- mExp.transform.parent.GetComponent().fillAmount = GameUserModel.Instance.GameUserExp / leveinfo.LevelUpExp;
- if (level >= 29 && GameUserModel.Instance.GameUserExp >= leveinfo.LevelUpExp)
- {
- level = 30;
- mLevel.text = level.ToString();
- mExp.gameObject.SetActive(false);
- mExp.transform.parent.GetComponent().fillAmount = 1f;
- }
- }
- if (mHomepage.value)
- {
- GameLog.Instance.AddUIEvent(GameLog.UIEventType.UIEventType_HomePage);
- HomePageCtrl.Instance.Enter();
- }
- else
- {
- HomePageCtrl.Instance.Exit();
- }
- }
- public void OnBattleChange()
- {
- if (mBattle.value)
- {
- GameLog.Instance.AddUIEvent(GameLog.UIEventType.UIEventType_Battle);
- BattleCtrl.Instance.Enter();
- }
- else
- {
- BattleCtrl.Instance.Exit();
- }
- }
- public void OnMarketChange()
- {
- if (mMarket.value)
- {
- GameLog.Instance.AddUIEvent(GameLog.UIEventType.UIEventType_Market);
- MarketCtrl.Instance.Enter();
- }
- else
- {
- MarketCtrl.Instance.Exit();
- }
- }
- public void OnInteractionChange()
- {
- if (mInteraction.value)
- {
- GameLog.Instance.AddUIEvent(GameLog.UIEventType.UIEventType_Friend);
- SocialCtrl.Instance.Enter();
- }
- else
- {
- SocialCtrl.Instance.Exit();
- }
- }
- public void MailListBtn(GameObject obj)
- {
- mMailBtnBg.SetActive(false);
- MailCtrl.Instance.Enter();
- }
- }
- }
[csharp] view plain copy 


- public class LoginCtrl : Singleton
- {
- public void Enter()
- {
- EventCenter.Broadcast(EGameEvent.eGameEvent_LoginEnter);
- }
- public void Exit()
- {
- EventCenter.Broadcast(EGameEvent.eGameEvent_LoginExit);
- }
- //登陆
- public void Login(string account, string pass)
- {
- }
- //登陆错误反馈
- public void LoginError(int code)
- {
- }
- //接收GateServer信息
- public void RecvGateServerInfo(Stream stream)
- {
- }
- //登陆失败
- public void LoginFail()
- {
- }
- //选择LoginServer
- public void SelectLoginServer(int i)
- {
- }
- //开始游戏
- public void GamePlay()
- {
- }
- }
[csharp] view plain copy 


- }