The author introduces: Jiang Xiewei, IT company technology partner, it senior lecturer, CSDN Community expert, guest editor, best-selling author, national patent inventor; published books: Teach You architecture 3D game engine, electronic industry press andUnity3d Actual combat core technical details of the electronic industry publishing house.
CSDN Video URL: http://edu.csdn.net/lecturer/144
Architecture design is also a kind of optimization, a game without a good architecture, the problem of the program is difficult to respond in a timely manner, the reader can imagine, if the programming is just to achieve the function and realize the function, in the end is the code more and more chaotic, various functions intertwined. After the problem everywhere to find bug fixes, optimization is even more impossible to talk about, who do not want to put the upcoming project code, re-construction again, it is better to do it again, so the architecture design in the game development is very important, and it is necessary to master the technology. The following focuses on the MVC and FSM architecture patterns, with the following effects:
The MVC architecture pattern was mentioned to the reader in the previous Optimization series, which tells the reader how to write the code in detail below. To the reader detailed analysis, take the window to switch distance, the game run, the first is the creation of the interface, we have each interface as a window, such as Loginwindow,herowindow. They are also used as the view interface, so the game will have a lot of interface design, the effect is as follows:
The following analysis interface is written, each of the above mentioned UI is a window, is also a view, so many view must have its own commonality, we can define it as a base class, the base class is called Basewindow, code is written as follows:
Namespace game.view{public abstract class Basewindow {protected Transform mroot; protected Escenestype Mscenestype; Scene type protected string mresname; Resource name protected bool mresident; Whether resident protected bool mvisible = FALSE; is visible//class object initialized public abstract void Init (); Class object release public abstract void Realse (); Window control initialization protected abstract void initwidget (); The window control releases protected abstract void Realsewidget (); Game Event Registration protected abstract void Onaddlistener (); Game event note protected abstract void Onremovelistener (); Display initialization public abstract void onenable (); Hide processing public abstract void ondisable (); Per frame update public virtual void update (float deltatime) {}//Get so scene type public escenestype getscensetype () {return mscenestype; }//is open public bool IsVisible () {return mvisible; }//Whether resident public bool Isresident () {return mresident;} Show public void Show () {if (mroot = = null) {if (Create ()) {Initwidget (); }} if (mroot && mRoot.gameObject.activeSelf = = False) {Mroot.gam Eobject.setactive (TRUE); Mvisible = true; Onenable (); Onaddlistener (); }}//Hide public void hide () {if (mroot && mRoot.gameObject.activeSelf = = T Rue) {Onremovelistener (); Ondisable (); if (mresident) {mRoot.gameObject.SetActive (false); } else {realsewidget (); Destroy (); }} mvisible = false; }//preload public void preload () {if (mroot = = null) {if (C Reate ()) {initwidget (); }}}//delay delete public void delaydestory () {if (mroot) { Realsewidget (); Destroy (); }}//Create form private bool Create () {if (mroot) {Debug.Log Error ("Window Create error exist!"); return false; } if (Mresname = = NULL | | mresname = = "") {debug.logerror ("window Create Error Resna Me 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; }//destroys the form protected void Destroy () {if (mroot) {Loaduiresource. Destroyload (Mroot.gameobject); Mroot = null; }}//Get root node public Transform getroot () {return mroot; } }}The above is about the form's base class, which implements all forms needed to create a method, create a form, destroy the form, preload, hide, and so on. The specific action class that is implemented requires inheriting the form class, such as Loginwindow, as follows:
Namespace game.view{public class Lobbywindow:basewindow {public Lobbywindow () {Mscenes Type = Escenestype.est_login; Scene type mresname = Gameconstdefine.loadgamelobbyui; Resource Name mresident = false; Whether resident memory}////////////////////////////Inherits interface///////////////////////////class object initialization public override void Init () {Eventcenter.addlistener (Egameevent.egameevent_lobbyenter, Show); Eventcenter.addlistener (Egameevent.egameevent_lobbyexit, Hide); }//Class object release public override void Realse () {Eventcenter.removelistener (egameevent.egameevent _lobbyenter, Show); Eventcenter.removelistener (Egameevent.egameevent_lobbyexit, Hide); }//Window control initialization protected override void Initwidget () {mhomepage = Mroot.findchild ( "Startmenumanager/startmenubtn/homepage"). Getcomponent<uitoggle> (); Uiguidectrl. INSTANCE.ADDUIGUIDEEVENTBTN (Mhomepage.gameobject); Mbattle = Mroot.findchild ("Startmenumanager/startmenubtn/battle"). Getcomponent<uitoggle> (); Mmarket = Mroot.findchild ("Startmenumanager/startmenubtn/market"). Getcomponent<uitoggle> (); Minteraction = Mroot.findchild ("Startmenumanager/startmenubtn/interaction"). Getcomponent<uitoggle> (); UIGuideCtrl.Instance.AddUiGuideEventBtn (Mmarket.gameobject); Mdiamondtext = Mroot.findchild ("Status/diamond/label"). Getcomponent<uilabel> (); Mgoldtext = Mroot.findchild ("Status/gold/label"). Getcomponent<uilabel> (); MSETTINGBTN = Mroot.findchild ("status/setting"). Getcomponent<uibutton> (); 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.u Ieventtype_personalinfo); LobbyCtrl.Instance.AskPersonInfo (); PresonInfoCtrl.Instance.Enter (); }//Window control free protected override void Realsewidget () {}//Game event Registration protected O verride 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.ToStri Ng (); }//game event protected override void Onremovelistener () {Eventcenter.removelistener (Egameev Ent.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); }//Show public override void Onenable () {}//Hide public Override void Ondisable () {} public void Changeuserlevel () {mlevel.text = Gameuser Model.Instance.UserLevel.ToString (); } Callback Event public void Onhomepagechange () {//todo Mlevel.text = GameUserModel.Instance.Us Erlevel.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<uisprite> (). Fillamount = Gameusermodel.instance.gameuserexp/leveinfo. Levelupexp; if (level >= && GameUserModel.Instance.GameUserExp >= leveinfo. LEVELUPEXP) {level = 30; Mlevel.text = level. ToString (); MExp.gameObject.SetActive (FALSE); Mexp.transform.parent.getcomponent<uisprite> (). 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 (); }} publicvoid Onmarketchange () {if (mmarket.value) {GameLog.Instance.AddUIEvent (Gamel og. 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 (); } }}This class is primarily to implement the logic of the entire UI, other windows are written similar. Write the control-controlled class code below, as shown in the following example code:
public class loginctrl:singleton<loginctrl> {public void Enter () { Eventcenter.broadcast ( Egameevent.egameevent_loginenter); } public void Exit () { eventcenter.broadcast (egameevent.egameevent_loginexit); } Login public void Login (string account, String pass) { } //Login error feedback public void LoginError (int Code) { } //Receive gateserver information public void Recvgateserverinfo (Stream stream) { } / /Login failed public void Loginfail () { } //select Loginserver public void selectloginserver (int i) { } //start Game public void GamePlay () { } }
}
The main function of the control class is to carry out some message delivery, which is also to relieve the coupling between the modules, the main core of the module is the ENTER function and the Exit function. Continue writing the code later ....
Unity3d Optimization Tips Series Five