您好,登錄后才能下訂單哦!
最簡版本設計
--最簡版本設計
為降低難度決定先講解一個最簡版本,闡述UI框架的核心設計理念。這里先定義三個核心功能:
1:UI窗體的自動加載功能。
2:緩存UI窗體。
3:窗體生命周期(狀態)管理。
UI框架設計主要目的,就是盡可能的完成一些與具體游戲功能邏輯無關的一些底層事務性的功能實現。這些功能最好是自動或者是半自動的實現,無須客戶程序(調用框架的程序)過多處理與關心。
對于以上功能,筆者定義了UI框架的相關四個核心類:
BaseUIForms 基礎UI窗體腳本(父類,其他窗體都繼承此腳本)
UIManger.cs UI窗體管理器腳本(框架核心腳本)
UIType 窗體類型 (引用窗體的重要屬性[枚舉類型])
SysDefine 系統定義類(包含框架中使用到的枚舉類型、委托事件、系統常量、接口等)
在SysDefine 文件中,定義本框架三個核心枚舉類型:
1 //UI窗體(位置)類型
2 public enum UIFormType
3 {
4 //普通窗體
5 Normal,
6 //固定窗體
7 Fixed,
8 //彈出窗體
9 PopUp
10 }
11
12 //UI窗體的顯示類型
13 public enum UIFormShowMode
14 {
15 //普通
16 Normal,
17 //反向切換
18 ReverseChange,
19 //隱藏其他
20 HideOther
21 }
22
23 //UI窗體透明度類型
24 public enum UIFormLucenyType
25 {
26 //完全透明,不能穿透
27 Lucency,
28 //半透明,不能穿透
29 Translucence,
30 //低透明度,不能穿透
31 ImPenetrable,
32 //可以穿透
33 Pentrate
34 }
上述三個核心枚舉類型,解釋如下:
UIFormType 枚舉類型,表示Unity層級視圖中掛載不同類型窗體的空節點。這里Fixed 表示固定窗體,表示可以掛載"非全屏非彈出窗體",例如RPG游戲項目中的“英雄信息”窗體等。
UIFormShowMode 枚舉,表示窗體不同的顯示方式。Normal 類型表示窗體與其他窗體可以并列顯示; HideOther類型表示窗體顯示的時候,需要隱藏所有其他窗體; ReverseChange 窗體主要應用與"彈出窗體",維護多個彈出窗體的層級關系。
UIFormLucenyType 枚舉,是定義彈出“模態窗體”不同透明度的類型。
上圖是我們定義的UGUI 中的“根窗體”預設 "Canvas",在Untiy的層級視圖中,可以看到我們定義了若干空節點,用于不同類型的UI窗體加載到不同的“根窗體”預設中,實現不同顯示效果。
定義 UIType 類,主要是引用定義的三個核心枚舉,方便使用 。代碼如下:
1 /// <summary>
2 /// UI(窗體)類型
3 /// </summary>
4 internal class UIType
5 {
6 //是否需要清空“反向切換”
7 public boolIsClearReverseChange = false;
8 //UI窗體類型
9 public UIFormsType UIForms_Type = UIFormsType.Normal;
10 //UI窗體顯示類型
11 publicUIFormsShowMode UIForms_ShowMode =UIFormsShowMode.Normal;
12 //UI窗體透明度類型
13 publicUIFormsLucencyType UIForms_LucencyType =UIFormsLucencyType.Lucency;
14 }
定義基礎UI窗體 BaseUIForms 腳本,代碼如下:
1 public class BaseUIForms : MonoBehaviour
2 {
3 /* 字段 */
4 //當前(基類)窗口的類型
5 privateUIType _CurrentUIType=new UIType();
6
7 /* 屬性 */
8 /// <summary>
9 ///屬性_當前UI窗體類型
10 /// </summary>
11 internal UIType CurrentUIType
12 {
13 set
14 {
15 _CurrentUIType =value;
16 }
17
18 get
19 {
20 return _CurrentUIType;
21 }
22 }
23
24 //頁面顯示
25 publicvirtual void Display()
26 {
27 this.gameObject.SetActive(true);
28 }
29
30 //頁面隱藏(不在“棧”集合中)
31 publicvirtual void Hiding()
32 {
33 this.gameObject.SetActive(false);
34 }
35 //頁面重新顯示
36 publicvirtual void Redisplay()
37 {
38 this.gameObject.SetActive(true);
39 }
40 //頁面凍結(還在“棧”集合中)
41 publicvirtual void Freeze()
42 {
43 this.gameObject.SetActive(true);
44 }
45
46 }//Class_end
上述代碼中,主要定義了UI窗體基類的四個重要虛方法,分別對應窗體的打開顯示、隱藏、重新顯示、窗體凍結(即:窗體顯示在其他窗體下面)。方便窗體在不同狀態下,針對不同的行為進一步做處理操作。例如,當窗體為“隱藏”與“凍結”狀態時,如果此窗體有針對遠程服務的網絡連接(Socket套接字)時,則需要關閉網絡連接,以節省網絡資源。
定義“UI管理器”(UIManager.cs) 腳本,這是UI框架中的核心腳本,主要負責UI窗體的加載、緩存、以及對于“UI窗體基類”的各種生命周期的操作(顯示、隱藏、重新顯示、凍結)。
1 public class UIManager : MonoBehaviour {
2 /* 字段 */
3 private staticUIManager _Instance = null;
4 //UI窗體預設路徑(參數1:窗體預設名稱,2:表示窗體預設路徑)
5 private Dictionary<string,string>_DicFormsPaths;
6 //緩存所有UI窗體
7 private Dictionary<string,BaseUIForm> _DicALLUIForms;
8 //當前顯示的UI窗體
9 private Dictionary<string,BaseUIForm> _DicCurrentShowUIForms;
10 //UI根節點
11 private Transform _TraCanvasTransfrom = null;
12 //全屏幕顯示的節點
13 private Transform _TraNormal = null;
14 //固定顯示的節點
15 private Transform _TraFixed = null;
16 //彈出節點
17 private Transform _TraPopUp = null;
18 //UI管理腳本的節點
19 private Transform _TraUIScripts = null;
20
21
22 /// <summary>
23 ///得到實例
24 /// </summary>
25 /// <returns></returns>
26 public static UIManager GetInstance()
27 {
28 if (_Instance==null)
29 {
30 _Instance = new GameObject("_UIManager").AddComponent<UIManager>();
31 }
32 return _Instance;
33 }
34
35 //初始化核心數據,加載“UI窗體路徑”到集合中。
36 public void Awake()
37 {
38 //字段初始化
39 _DicALLUIForms=new Dictionary<string, BaseUIForm>();
40 _DicCurrentShowUIForms=newDictionary<string, BaseUIForm>();
41 _DicFormsPaths=new Dictionary<string, string>();
42 //初始化加載(根UI窗體)Canvas預設
43 InitRootCanvasLoading();
44 //得到UI根節點、全屏節點、固定節點、彈出節點
45 _TraCanvasTransfrom =GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS).transform;
46 _TraNormal = _TraCanvasTransfrom.Find("Normal");
47 _TraFixed = _TraCanvasTransfrom.Find("Fixed");
48 _TraPopUp = _TraCanvasTransfrom.Find("PopUp");
49 _TraUIScripts = _TraCanvasTransfrom.Find("_ScriptMgr");
50 //把本腳本作為“根UI窗體”的子節點。
51 this.gameObject.transform.SetParent(_TraUIScripts, false);
52 //"根UI窗體"在場景轉換的時候,不允許銷毀
53 DontDestroyOnLoad(_TraCanvasTransfrom);
54 //初始化“UI窗體預設”路徑數據
55 //先寫簡單的,后面我們使用Json做配置文件,來完善。
56 if(_DicFormsPaths!=null)
57 {
58 _DicFormsPaths.Add("LogonUIForm",@"UIPrefabs\LogonUIForm");
59 }
60 }
61
62 /// <summary>
63 ///顯示(打開)UI窗體
64 ///功能:
65 /// 1: 根據UI窗體的名稱,加載到“所有UI窗體”緩存集合中
66 /// 2: 根據不同的UI窗體的“顯示模式”,分別作不同的加載處理
67 /// </summary>
68 /// <paramname="uiFormName">UI窗體預設的名稱</param>
69 public voidShowUIForms(stringuiFormName)
70 {
71 BaseUIFormbaseUIForms=null; //UI窗體基類
72
73 //參數的檢查
74 if (string.IsNullOrEmpty(uiFormName))return;
75 //根據UI窗體的名稱,加載到“所有UI窗體”緩存集合中
76 baseUIForms = LoadFormsToAllUIFormsCatch(uiFormName);
77 if (baseUIForms == null)return;
78 //根據不同的UI窗體的顯示模式,分別作不同的加載處理
79 switch(baseUIForms.CurrentUIType.UIForms_ShowMode)
80 {
81 caseUIFormShowMode.Normal: //“普通顯示”窗口模式
82 //把當前窗體加載到“當前窗體”集合中。
83 LoadUIToCurrentCache(uiFormName);
84 break;
85 case UIFormShowMode.ReverseChange: //需要“反向切換”窗口模式
86 //更靠后課程進行講解。
87 break;
88 case UIFormShowMode.HideOther: //“隱藏其他”窗口模式
89 //更靠后課程進行講解。
90 break;
91 default:
92 break;
93 }
94 }
95
96 #region 私有方法
97 //初始化加載(根UI窗體)Canvas預設
98 private void InitRootCanvasLoading()
99 {
100 ResourcesMgr.GetInstance().LoadAsset(SysDefine.SYS_PATH_CANVAS,false);
101 }
102
103 /// <summary>
104 ///根據UI窗體的名稱,加載到“所有UI窗體”緩存集合中
105 ///功能: 檢查“所有UI窗體”集合中,是否已經加載過,否則才加載。
106 /// </summary>
107 /// <param name="uiFormsName">UI窗體(預設)的名稱</param>
108 /// <returns></returns>
109 privateBaseUIForm LoadFormsToAllUIFormsCatch(string uiFormsName)
110 {
111 BaseUIForm baseUIResult = null; //加載的返回UI窗體基類
112
113 _DicALLUIForms.TryGetValue(uiFormsName, out baseUIResult);
114 if(baseUIResult==null)
115 {
116 //加載指定名稱的“UI窗體”
117 baseUIResult = LoadUIForm(uiFormsName);
118 }
119
120 return baseUIResult;
121 }
122
123 /// <summary>
124 ///加載指定名稱的“UI窗體”
125 ///功能:
126 /// 1:根據“UI窗體名稱”,加載預設克隆體。
127 /// 2:根據不同預設克隆體中帶的腳本中不同的“位置信息”,加載到“根窗體”下不同的節點。
128 /// 3:隱藏剛創建的UI克隆體。
129 /// 4:把克隆體,加入到“所有UI窗體”(緩存)集合中。
130 ///
131 /// </summary>
132 /// <param name="uiFormName">UI窗體名稱</param>
133 privateBaseUIForm LoadUIForm(string uiFormName)
134 {
135 stringstrUIFormPaths = null; //UI窗體路徑
136 GameObject goCloneUIPrefabs = null; //創建的UI克隆體預設
137 BaseUIForm baseUiForm=null; //窗體基類
138
139
140 //根據UI窗體名稱,得到對應的加載路徑
141 _DicFormsPaths.TryGetValue(uiFormName,out strUIFormPaths);
142 //根據“UI窗體名稱”,加載“預設克隆體”
143 if(!string.IsNullOrEmpty(strUIFormPaths))
144 {
145 goCloneUIPrefabs =ResourcesMgr.GetInstance().LoadAsset(strUIFormPaths, false);
146 }
147 //設置“UI克隆體”的父節點(根據克隆體中帶的腳本中不同的“位置信息”)
148 if(_TraCanvasTransfrom != null &&goCloneUIPrefabs != null)
149 {
150 baseUiForm =goCloneUIPrefabs.GetComponent<BaseUIForm>();
151 if(baseUiForm == null)
152 {
153 Debug.Log("baseUiForm==null! ,請先確認窗體預設對象上是否加載了baseUIForm的子類腳本! 參數 uiFormName=" + uiFormName);
154 returnnull;
155 }
156 switch (baseUiForm.CurrentUIType.UIForms_Type)
157 {
158 caseUIFormType.Normal: //普通窗體節點
159 goCloneUIPrefabs.transform.SetParent(_TraNormal, false);
160 break;
161 caseUIFormType.Fixed: //固定窗體節點
162 goCloneUIPrefabs.transform.SetParent(_TraFixed, false);
163 break;
164 caseUIFormType.PopUp: //彈出窗體節點
165 goCloneUIPrefabs.transform.SetParent(_TraPopUp,false);
166 break;
167 default:
168 break;
169 }
170
171 //設置隱藏
172 goCloneUIPrefabs.SetActive(false);
173 //把克隆體,加入到“所有UI窗體”(緩存)集合中。
174 _DicALLUIForms.Add(uiFormName,baseUiForm);
175 return baseUiForm;
176 }
177 else
178 {
179 Debug.Log("_TraCanvasTransfrom==nullOr goCloneUIPrefabs==null!! ,Plese Check!, 參數uiFormName="+uiFormName);
180 }
181
182 Debug.Log("出現不可以預估的錯誤,請檢查,參數 uiFormName="+uiFormName);
183 returnnull;
184 }//Mehtod_end
185
186 /// <summary>
187 ///把當前窗體加載到“當前窗體”集合中
188 /// </summary>
189 /// <param name="uiFormName">窗體預設的名稱</param>
190 privatevoid LoadUIToCurrentCache(string uiFormName)
191 {
192 BaseUIForm baseUiForm; //UI窗體基類
193 BaseUIFormbaseUIFormFromAllCache; //從“所有窗體集合”中得到的窗體
194
195 //如果“正在顯示”的集合中,存在整個UI窗體,則直接返回
196 _DicCurrentShowUIForms.TryGetValue(uiFormName, out baseUiForm);
197 if(baseUiForm != null) return;
198 //把當前窗體,加載到“正在顯示”集合中
199 _DicALLUIForms.TryGetValue(uiFormName, out baseUIFormFromAllCache);
200 if(baseUIFormFromAllCache!=null)
201 {
202 _DicCurrentShowUIForms.Add(uiFormName,baseUIFormFromAllCache);
203 baseUIFormFromAllCache.Display(); //顯示當前窗體
204 }
205 }
206
207 #endregion
208
209 }//class_end
UI管理器腳本解釋如下:
一:上述代碼中重要字段的解釋如下:
1: “_DicFormsPaths” 表示“UI窗體預設路徑”集合,負責緩存所有UI窗體預設的名稱與對應資源路徑的關系。
2: “ _DicALLUIForms” 表示“所有UI窗體”集合,負責緩存已經加載過的所有UI窗體名稱以及與之對應的UI窗體。
3: “_DicCurrentShowUIForms”表示“當前正在顯示”集合,負責控制正在顯示UI窗體的內部邏輯。
4: UI管理器腳本中的“_TraCanvasTransfrom”、“_TraNormal”、“_TraFixed”、“_TraPopUp”、“_TraUIScripts”,分別表示Unity層級視圖中的根結點、普通節點、固定節點、彈出節點、管理腳本節點,這些節點是加載UI窗體的不同類型的父節點,用于各種UI窗體的管理工作。
二:上述代碼中重要方法的解釋如下:
1: ShowUIForms() 是外部程序調用本框架的對外公共方法,負責加載、緩存、打開與顯示制定窗體名稱的UI窗體預設。
2: LoadFormsToAllUIFormsCatch() 是根據UI窗體的名稱,加載到“所有UI窗體”緩存集合中。
3: LoadUIToCurrentCache() 是把當前窗體加載到“當前窗體”集合中。
上述(UI框架)腳本編寫完畢,測試成功后效果如下圖:
為廣大讀者進一步了解與熟悉本框架,特提供下載鏈接:http://pan.baidu.com/s/1skN2Njn 密碼:2ey6
本篇就先寫到這,下篇 "游戲UI框架設計(3)_窗體的層級管理" 繼續。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。