中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

游戲UI框架設計(三) : 窗體的層級管理

發布時間:2020-07-08 22:19:31 來源:網絡 閱讀:3490 作者:Liu_guozhu 欄目:開發技術

游戲UI框架設計(三)

---窗體的層級管理


  UI框架中UI窗體的“層級管理”,最核心的問題是如何進行窗體的顯示管理。窗體(預設)的顯示我們前面定義了三種類型: 普通、隱藏其他、反向切換。代碼如下:

游戲UI框架設計(三) : 窗體的層級管理

    

    “普通顯示”模式允許多個窗體同時顯示,這種類型應用最多。例如RPG中的主城界面(見下圖)。

游戲UI框架設計(三) : 窗體的層級管理


    “隱藏其他界面” 模式一般應用于全局性的窗體。我們在開發此類窗體時,為了減少UI渲染壓力、提高Unity渲染效率,則設置被覆蓋的窗體為“不可見”狀態。(即: this.gameObject.SetActive(false))。例如一般的登錄窗體、選擇英雄窗體等。

游戲UI框架設計(三) : 窗體的層級管理


  “反向切換”模式類型,一般都大量引用于“彈出窗體”中。此類窗體的特點是:顯示彈出窗體時不完全覆蓋底層窗體,一般在屏幕的四周會露出底層窗體。之所以命名“反向切換”是因為: 程序員要維護一種“后進先出”的“棧”的數據結構特點,即我們一般要求玩家必須先關閉彈出的頂層窗體,再依次關閉下一級窗體。如下圖所示。

游戲UI框架設計(三) : 窗體的層級管理


  上圖即一種典型的彈出窗體。一般我們都要求玩家先處理彈出窗體中的信息,然后關閉此窗體。一般不允許在沒有關閉子窗體的情況下,直接點擊父窗體。(關于彈出窗體時,不允許玩家點擊父窗體的功能實現,筆者在下節[“模態窗體管理”]一章著重講解)。

  以上說了這么多了,我們對于“層級管理”的核心代碼實現,基本都體現在“UI管理器腳本” (UIManager.cs )中。以下給出具體實現代碼:


/***

 *   Title: "SUIFW" 框架技術

 *          主題: UI管理器    

 *   Description:

 *          功能:整個UI框架的核心,用戶程序通過調用本類,來調用本框架的大多數功能。 

 *          功能1:關于入“棧”與出“棧”的UI窗體4個狀態的定義邏輯

 *                 入棧狀態:

 *                     Freeze();   (上一個UI窗體)凍結

 *                     Display();  (本UI窗體)顯示

 *                 出棧狀態:

 *                     Hiding();    (本UI窗體) 隱藏

 *                     Redisplay(); (上一個UI窗體) 重新顯示

 *         功能2:增加“非棧”緩存集合。

 */

using UnityEngine;

usingUnityEngine.UI;

using System;

usingSystem.Collections.Generic;

 

namespace SUIFW

{

   publicclassUIManager : MonoBehaviour

   {

        /* 字段  */

        //本類實例

        privatestaticUIManager_Instance = null;

        //存儲所有“UI窗體預設(Prefab)”路徑

        //參數含義: 第1個string 表示“窗體預設”名稱,后一個string 表示對應的路徑

        privateDictionary<string,string> _DicUIFormsPaths;

        //緩存所有已經打開的“UI窗體預設(Prefab)”

        //參數含義: 第1個string 表示“窗體預設”名稱,后一個BaseUI 表示對應的“窗體預設”

        privateDictionary<string,BaseUIForms> _DicALLUIForms;

        //“棧”結構表示的“當前UI窗體”集合。

        privateStack<BaseUIForms>_StaCurrentUIForms;

        //當前顯示狀態的UI窗體集合

        privateDictionary<string,BaseUIForms> _DicCurrentShowUIForms;

        //UI根節點

        privateTransform _CanvasTransform = null;

        //普通全屏界面節點

        privateTransform _CanTransformNormal = null;

        //固定界面節點

        privateTransform _CanTransformFixed = null;

        //彈出模式節點

        privateTransform _CanTransformPopUp = null;

        //UI腳本節點(加載各種管理腳本的節點)

        privateTransform _CanTransformUIScripts = null;

 

 

 

 

        ///<summary>

        ///得到本類實例

        ///</summary>

        ///<returns></returns>

        publicstaticUIManagerGetInstance()

        {

            if(_Instance == null)

            {

                _Instance = newGameObject("_UIManager").AddComponent<UIManager>();

            }

            return_Instance;

        }

 

        voidAwake()

        {

            //字段初始化

            _DicUIFormsPaths = newDictionary<string,string>();

            _DicALLUIForms = newDictionary<string,BaseUIForms>();

            _StaCurrentUIForms = newStack<BaseUIForms>();

            _DicCurrentShowUIForms = newDictionary<string,BaseUIForms>();

 

            //初始化項目開始必須的資源加載

           InitRootCanvasLoading();

 

            //得到UI根節點、及其重要子節點                    

            _CanvasTransform = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS).transform;

            //得到普通全屏界面節點、固定界面節點、彈出模式節點、UI腳本節點

            _CanTransformNormal = UnityHelper.FindTheChild(_CanvasTransform.gameObject,SysDefine.SYS_CANVAS_NORMAL_NODE_NAME);

            _CanTransformFixed = UnityHelper.FindTheChild(_CanvasTransform.gameObject,SysDefine.SYS_CANVAS_FIXED_NODE_NAME);

            _CanTransformPopUp = UnityHelper.FindTheChild(_CanvasTransform.gameObject,SysDefine.SYS_CANVAS_POPUP_NODE_NAME);

            _CanTransformUIScripts = UnityHelper.FindTheChild(_CanvasTransform.gameObject,SysDefine.SYS_CANVAS_UISCRIPTS_NODE_NAME);

 

            //把本腳本實例,作為Canvas的子節點

            UnityHelper.AddChildToParent(_CanTransformUIScripts,this.gameObject.transform);

 

            //本UI節點信息,場景轉換時,不允許銷毀

           DontDestroyOnLoad(_CanvasTransform);

            //初始化“UI窗體預設”路徑數據

            InitUIFormsPathsData();

        }

 

        ///<summary>

        ///顯示UI窗體

        ///</summary>

        ///<param name="strUIFormName">UI窗體的名稱</param>

        publicvoid ShowUIForms(stringstrUIFormName)

        {

            BaseUIFormsbaseUIForms;                        //UI窗體基類

 

            //參數檢查

            if(string.IsNullOrEmpty(strUIFormName)) return;

 

            //加載“UI窗體名稱”,到“所有UI窗體緩存”中

            baseUIForms =LoadUIFormsToAllUIFormsCatch(strUIFormName);

            if(baseUIForms == null) return;

 

            //判斷是否清空“棧”結構體集合

            if(baseUIForms.CurrentUIType.IsClearReverseChange)

            {

                ClearStackArray();

            }

 

            //判斷不同的窗體顯示模式,分別進行處理

            switch(baseUIForms.CurrentUIType.UIForms_ShowMode)

            {

                caseUIFormsShowMode.Normal:

                   EnterUIFormsCache(strUIFormName);

                    break;

                caseUIFormsShowMode.ReverseChange:

                    PushUIForms(strUIFormName);

                    break;

                caseUIFormsShowMode.HideOther:

                   EnterUIFormstToCacheHideOther(strUIFormName);

                    break;

                default:

                    break;

            }

        }

 

        ///<summary>

        ///關閉或返回上一個UI窗體(關閉當前UI窗體)

        ///</summary>

        publicvoid CloseOrReturnUIForms(stringstrUIFormName)

        {

            BaseUIFormsbaseUIForms = null;                   //UI窗體基類

 

            /* 參數檢查 */

            if(string.IsNullOrEmpty(strUIFormName)) return;

            //“所有UI窗體緩存”如果沒有記錄,則直接返回。

           _DicALLUIForms.TryGetValue(strUIFormName, outbaseUIForms);

            if(baseUIForms == null) return;

 

            /* 判斷不同的窗體顯示模式,分別進行處理 */

            switch(baseUIForms.CurrentUIType.UIForms_ShowMode)

            {

                caseUIFormsShowMode.Normal:

                   ExitUIFormsCache(strUIFormName);

                    break;

                caseUIFormsShowMode.ReverseChange:

                    PopUIForms();

                    break;

                caseUIFormsShowMode.HideOther:

                   ExitUIFormsFromCacheAndShowOther(strUIFormName);

                    break;

                default:

                    break;

            }

 

       }

 

        #region私有方法

        ///<summary>

        ///根據指定UI窗體名稱,加載到“所有UI窗體”緩存中。

        ///</summary>

        ///<param name="strUIFormName">UI窗體名稱</param>

        ///<returns></returns>

        privateBaseUIForms LoadUIFormsToAllUIFormsCatch(stringstrUIFormName)

        {

            BaseUIFormsbaseUI;                             //UI窗體

 

            //判斷“UI預設緩存集合”是否有指定的UI窗體,否則新加載窗體

           _DicALLUIForms.TryGetValue(strUIFormName, outbaseUI);

            if(baseUI == null)

            {

                //加載指定路徑的“UI窗體”

                baseUI =LoadUIForms(strUIFormName);

            }

 

            returnbaseUI;

        }

 

        ///<summary>

        ///加載UI窗體到“當前顯示窗體集合”緩存中。

        ///</summary>

        ///<param name="strUIFormsName"></param>

        privatevoid EnterUIFormsCache(stringstrUIFormsName)

        {

            BaseUIFormsbaseUIForms;                        //UI窗體基類

            BaseUIFormsbaseUIFormsFromAllCache;            //"所有窗體集合"中的窗體基類

 

            //“正在顯示UI窗體緩存”集合里有記錄,則直接返回。

           _DicCurrentShowUIForms.TryGetValue(strUIFormsName, outbaseUIForms);

            if(baseUIForms != null) return;

 

            //把當前窗體,加載到“正在顯示UI窗體緩存”集合里

           _DicALLUIForms.TryGetValue(strUIFormsName, outbaseUIFormsFromAllCache);

            if(baseUIFormsFromAllCache != null)

            {

               _DicCurrentShowUIForms.Add(strUIFormsName, baseUIFormsFromAllCache);

               baseUIFormsFromAllCache.Display();

            }

        }

 

        ///<summary>

        ///卸載UI窗體從“當前顯示窗體集合”緩存中。

        ///</summary>

        ///<paramname="strUIFormsName"></param>

        privatevoid ExitUIFormsCache(stringstrUIFormsName)

        {

            BaseUIFormsbaseUIForms;                        //UI窗體基類

 

            //“正在顯示UI窗體緩存”集合沒有記錄,則直接返回。

           _DicCurrentShowUIForms.TryGetValue(strUIFormsName, outbaseUIForms);

            if(baseUIForms == null) return;

 

            //指定UI窗體,運行隱藏狀態,且從“正在顯示UI窗體緩存”集合中移除。

            baseUIForms.Hiding();

           _DicCurrentShowUIForms.Remove(strUIFormsName);

        }

 

        ///<summary>

        ///加載UI窗體到“當前顯示窗體集合”緩存中,且隱藏其他正在顯示的頁面

        ///</summary>

        ///<paramname="strUIFormsName"></param>

        privatevoid EnterUIFormstToCacheHideOther(stringstrUIFormsName)

        {

            BaseUIFormsbaseUIForms;                        //UI窗體基類

            BaseUIFormsbaseUIFormsFromAllCache;            //"所有窗體集合"中的窗體基類

 

            //“正在顯示UI窗體緩存”集合里有記錄,則直接返回。

           _DicCurrentShowUIForms.TryGetValue(strUIFormsName, outbaseUIForms);

            if(baseUIForms != null) return;

 

            //“正在顯示UI窗體緩存”與“棧緩存”集合里所有窗體進行隱藏處理。

            foreach(BaseUIForms baseUIFormsItem in_DicCurrentShowUIForms.Values)

            {

                baseUIFormsItem.Hiding();

            }

            foreach(BaseUIForms basUIFormsItem in_StaCurrentUIForms)

            {

                basUIFormsItem.Hiding();

            }

 

            //把當前窗體,加載到“正在顯示UI窗體緩存”集合里

           _DicALLUIForms.TryGetValue(strUIFormsName,out baseUIFormsFromAllCache);

            if(baseUIFormsFromAllCache != null)

            {

               _DicCurrentShowUIForms.Add(strUIFormsName, baseUIFormsFromAllCache);

                baseUIFormsFromAllCache.Display();

            }

        }

 

        ///<summary>

        ///卸載UI窗體從“當前顯示窗體集合”緩存中,且顯示其他原本需要顯示的頁面

        ///</summary>

        ///<paramname="strUIFormsName"></param>

        privatevoidExitUIFormsFromCacheAndShowOther(stringstrUIFormsName)

        {

            BaseUIFormsbaseUIForms;                        //UI窗體基類

 

            //“正在顯示UI窗體緩存”集合沒有記錄,則直接返回。

           _DicCurrentShowUIForms.TryGetValue(strUIFormsName, outbaseUIForms);

            if(baseUIForms == null) return;

 

            //指定UI窗體,運行隱藏狀態,且從“正在顯示UI窗體緩存”集合中移除。

            baseUIForms.Hiding();

           _DicCurrentShowUIForms.Remove(strUIFormsName);

 

            //“正在顯示UI窗體緩存”與“棧緩存”集合里所有窗體進行再次顯示處理。

            foreach(BaseUIForms baseUIFormsItem in_DicCurrentShowUIForms.Values)

            {

                baseUIFormsItem.Redisplay();

            }

            foreach(BaseUIForms basUIFormsItem in_StaCurrentUIForms)

            {

                basUIFormsItem.Redisplay();

            }

        }

 

       ///<summary>

        ///UI窗體入棧

        ///功能1: 判斷棧里是否已經有窗體,有則“凍結”

        ///     2: 先判斷“UI預設緩存集合”是否有指定的UI窗體,有則處理。

        ///     3: 指定UI窗體入"棧"

        ///</summary>

        ///<paramname="strUIFormsName"></param>

        privatevoid PushUIForms(stringstrUIFormsName)

        {

            BaseUIFormsbaseUI;                             //UI預設窗體

 

 

            //判斷棧里是否已經有窗體,有則“凍結”

            if(_StaCurrentUIForms.Count > 0)

            {

                BaseUIFormstopUIForms = _StaCurrentUIForms.Peek();

                topUIForms.Freeze();

            }

 

            //先判斷“UI預設緩存集合”是否有指定的UI窗體,有則處理。

           _DicALLUIForms.TryGetValue(strUIFormsName, outbaseUI);

            if(baseUI != null)

            {

                baseUI.Display();

            }

            else

            {

                Log.Write(GetType()+ string.Format("/PushUIForms()/ baseUI==null! 核心錯誤,請檢查strUIFormsName={0}", strUIFormsName), Log.Level.High);

            }

 

            //指定UI窗體入"棧"

            _StaCurrentUIForms.Push(baseUI);

        }

 

        ///<summary>

        ///UI窗體出棧邏輯

        ///</summary>

        privatevoid PopUIForms()

        {

            if(_StaCurrentUIForms.Count >= 2)

            {

                /* 出棧邏輯 */

                BaseUIFormstopUIForms = _StaCurrentUIForms.Pop();

                //出棧的窗體,進行隱藏處理

                topUIForms.Hiding();

                //出棧窗體的下一個窗體邏輯

                BaseUIFormsnextUIForms = _StaCurrentUIForms.Peek();

                //下一個窗體"重新顯示"處理

                nextUIForms.Redisplay();

            }

            elseif (_StaCurrentUIForms.Count == 1)

            {

                /* 出棧邏輯 */

                BaseUIFormstopUIForms = _StaCurrentUIForms.Pop();

                //出棧的窗體,進行"隱藏"處理

                topUIForms.Hiding();

            }

        }

 

        ///<summary>

        ///加載與顯示UI窗體

        ///功能:

        ///    1:根據“UI窗體預設”名稱,加載預設克隆體。

        ///    2:預設克隆體添加UI“根節點”為父節點。

        ///    3:隱藏剛創建的UI克隆體。

        ///    4:新創建的“UI窗體”,加入“UI窗體緩存”中

        ///</summary>

        privateBaseUIForms LoadUIForms(stringstrUIFormsName)

        {

            stringstrUIFormsPaths = null;                  //UI窗體的路徑

            GameObjectgoCloneUIPrefab = null;              //克隆的"窗體預設"

           BaseUIFormsbaseUIForm;                         //UI窗體

 

 

            //得到UI窗體的路徑

           _DicUIFormsPaths.TryGetValue(strUIFormsName, outstrUIFormsPaths);

 

            //加載指定路徑的“UI窗體”

            if(!string.IsNullOrEmpty(strUIFormsPaths))

           {

                goCloneUIPrefab = ResourcesMgr.GetInstance().LoadAsset(strUIFormsPaths,false);

            }

 

            //設置“UI窗體”克隆體的父節點,以及隱藏處理與加入“UI窗體緩存”中

            if(_CanvasTransform != null&& goCloneUIPrefab != null)

            {

               baseUIForm = goCloneUIPrefab.GetComponent<BaseUIForms>();

                if(baseUIForm == null)

                {

                    Log.Write(GetType()+ string.Format("/LoadUIForms()/ baseUIForm==null!,請先確認克隆對象上是否加載了BaseUIForms的子類。參數 strUIFormsName='{0}' ", strUIFormsName), Log.Level.High);

                    returnnull;

                }

                switch(baseUIForm.CurrentUIType.UIForms_Type)

                {

                    caseUIFormsType.Normal:

                        goCloneUIPrefab.transform.SetParent(_CanTransformNormal,false);

                        break;

                    caseUIFormsType.Fixed:

                       goCloneUIPrefab.transform.SetParent(_CanTransformFixed, false);

                        break;

                    caseUIFormsType.PopUp:

                       goCloneUIPrefab.transform.SetParent(_CanTransformPopUp, false);

                        break;

                    default:

                        break;

                }

 

               goCloneUIPrefab.SetActive(false);

                //新創建的“UI窗體”,加入“UI窗體緩存”中

               _DicALLUIForms.Add(strUIFormsName, baseUIForm);

                returnbaseUIForm;

            }

            else

            {

                Log.Write(GetType()+ string.Format("/LoadUIForms()/‘_CanvasTransform’ Or ‘goCloneUIPrefab’==NULL!  , 方法參數strUIFormsName={0},請檢查!", strUIFormsName), Log.Level.High);

            }

 

            Log.Write(GetType()+ string.Format("/LoadUIForms()/ 出現不可預知錯誤,請檢查! 方法參數strUIFormsName={0}", strUIFormsName), Log.Level.High);

            returnnull;

        }

 

        ///<summary>

        ///初始化項目開始必須的資源加載

        ///</summary>

        privatevoid InitRootCanvasLoading()

        {

            if(UnityHelper.isFirstLoad)

            {

                ResourcesMgr.GetInstance().LoadAsset(SysDefine.SYS_PATH_CANVAS, false);

            }

        }

 

        ///<summary>

        ///初始化“UI窗體預設”路徑數據

        ///</summary>

        privatevoid InitUIFormsPathsData()

        {

            //測試也成功

            IConfigManagerconfigMgr = newConfigManagerByJson(SysDefine.SYS_PATH_UIFormConfigJson);

            if(_DicUIFormsPaths != null)

            {

                _DicUIFormsPaths =configMgr.AppSetting;

            }

        }

 

        ///<summary>

        ///清空“棧”結構體集合

        ///</summary>

        ///<returns></returns>

        privatebool ClearStackArray()

        {

            if(_StaCurrentUIForms != null&& _StaCurrentUIForms.Count >= 1)

            {

                _StaCurrentUIForms.Clear();

                returntrue;

            }

            returnfalse;

        }

 

        #endregion

 

   }//Class_end

}


以上代碼解釋:

    1: UIManager.cs  中定義的新的字段 ,“_StaCurrentUIForms” 就是一個“棧”數據類型,用于維護一種后進先出的數據結構。常見的方法如下:

      C#語言中提供 Stack<T> 泛型集合,來直接實現這種結構。
常用屬性與方法:

  •  Count 屬性  查詢棧內元素數量

  •  Push()      壓棧

  •  Pop()       出棧

  •  Peek()      查詢棧頂元素

  •  GetEnumerator() 遍歷棧中所有元素


   2: UIManager.cs 中的“ShowUIForms()”方法中的PushUIForms()與EnterUIFormstToCacheHideOther() 方法,就是專門處理“反向切換”與“隱藏其他”窗體特性的實現方法。


    好了時間不早了就先寫到這吧,大家有什么疑問可以討論,這里筆者也主要是想起到“拋磚引玉”的作用。


本篇就先寫到這,下篇 "游戲UI框架設計(4)_模態窗體管理" 繼續。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

唐河县| 松滋市| 东丰县| 高安市| 渝中区| 遂川县| 迁西县| 伽师县| 赤壁市| 赤峰市| 桐梓县| 斗六市| 上栗县| 石阡县| 深水埗区| 游戏| 杭锦后旗| 东兴市| 通渭县| 万全县| 广饶县| 揭东县| 渝北区| 菏泽市| 靖西县| 济阳县| 抚顺市| 高碑店市| 荃湾区| 边坝县| 咸丰县| 舟山市| 昌黎县| 靖边县| 石门县| 鄂托克前旗| 奉贤区| 华亭县| 岳西县| 永胜县| 手游|