UI框架-UIManager

目錄

  1. UI框架介紹
  2. 保存面板信息
  3. 解析面板信息,開發(fā)配套數(shù)據(jù)模型
  4. 開發(fā)公共面板類BasePanel
  5. 開發(fā)UIManager核心管理類
  6. 開發(fā)菜單面板類和背包類使用UIManager
  7. 結(jié)束

一,UI框架介紹

為什么要使用UI框架

我們在開發(fā)項(xiàng)目中會有許多面板后德,比如背包面板,技能面板脐往,設(shè)置面板等新博。如此多的面板我們不好統(tǒng)一進(jìn)行管理语稠,當(dāng)需求發(fā)生更變我們需要快速的做出調(diào)整漆弄,UI框架就很好的能改善這一點(diǎn)睦裳,并且使代碼結(jié)構(gòu)更加清晰。

UI框架如何管理

UI框架通過核心類UIManager 1. 解析本地文檔 2. 用棧統(tǒng)一控制面板的顯示和隱藏撼唾。

UI框架UML架構(gòu)圖
UI框架.png

二廉邑, 保存面板信息

1. 將面板做成預(yù)制體保存在本地Resources文件夾下
預(yù)制體.png
2. 將面板類型及路徑寫入Json文件
{
"infoList":
[
{"panelTypeString":"ItemMessage",
"path":"UIPanel/ItemMessagePanel"},

{"panelTypeString":"Knapsack",
"path":"UIPanel/KnapsackPanel"},

{"panelTypeString":"MainMenu",
"path":"UIPanel/MainMenuPanel"},

{"panelTypeString":"Shop",
"path":"UIPanel/ShopPanel"},

{"panelTypeString":"Skill",
"path":"UIPanel/SkillPanel"},

{"panelTypeString":"System",
"path":"UIPanel/SystemPanel"},

{"panelTypeString":"Task",
"path":"UIPanel/TaskPanel"}

]
}

三, 解析面板信息倒谷,開發(fā)配套數(shù)據(jù)模型

通過上面操作我們已經(jīng)將我們的面板保存到本地了蛛蒙,當(dāng)我們使用的時候只需要解析本地文件并做數(shù)據(jù)存儲即可。
  1. 準(zhǔn)備我們的數(shù)據(jù)模型類UIPanelInfo,一定要標(biāo)注可序列化特性哦渤愁。
[Serializable]
public class UIPanelInfo : ISerializationCallbackReceiver
{
    [NonSerialized]
    //面板類型
    public UIPanelType panelType;
    public string panelTypeString;
    //面板路徑
    public string path;

    //字符串轉(zhuǎn)化枚舉類型
    public void OnAfterDeserialize()
    {
        UIPanelType type = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
        panelType = type;
    }

    public void OnBeforeSerialize()
    {

    }
}
  1. 解析本地文件牵祟,并存入字典方便加載,這里我將其寫入核心類UIManager中抖格。
    [Serializable]
    class UIPanelTypeJson
    {
        public List<UIPanelInfo> infoList;
    }
    //解析Json
    private void ParseUIPanelTypeJson()
    {
        panelPathDict = new Dictionary<UIPanelType, string>();

        TextAsset ta = Resources.Load<TextAsset>("UIPanelType");

        UIPanelTypeJson jsonObject = JsonUtility.FromJson<UIPanelTypeJson>(ta.text);

        foreach (UIPanelInfo info in jsonObject.infoList)
        {
            //Debug.Log(info.panelType);
            panelPathDict.Add(info.panelType, info.path);
        }
    }
小提示:在Unity 5.3中Unity開放了一個JsonUnility序列化類詳情請自查API诺苹。
                    作用:    1. 目前支持Json轉(zhuǎn)化為對象咕晋。
                              2. 對象轉(zhuǎn)化為Json格式字符。

四筝尾,開發(fā)公共面板類BasePanel

所有面板都有界面的顯示,暫停办桨。像我們的菜單面板還需要有暫停和繼續(xù)筹淫,當(dāng)其他面板顯示我們可以防止用戶與其他面板繼續(xù)交互。當(dāng)當(dāng)前面板處于隱藏我們才允許菜單面板與用戶繼續(xù)交互呢撞。所以我們將面板都具有的共性做成一個公共的基類损姜。

public class BasePanel : MonoBehaviour
{
    /// <summary>
    /// 界面被顯示出來
    /// </summary>
    public virtual void OnEnter()
    {

    }

    /// <summary>
    /// 界面暫停
    /// </summary>
    public virtual void OnPause()
    {

    }

    /// <summary>
    /// 界面繼續(xù)
    /// </summary>
    public virtual void OnResume()
    {

    }

    /// <summary>
    /// 界面不顯示,退出這個界面,界面被關(guān)閉
    /// </summary>
    public virtual void OnExit()
    {

    }
}

五殊霞,開發(fā)UIManager核心管理類

當(dāng)你看到這里摧阅,恭喜你到了最核心的一部分了。
  1. 擴(kuò)展Dictionary類獲取Value绷蹲,如果取不到則返回空棒卷。
  2. 準(zhǔn)備一個字典成員用來存儲路徑和面板實(shí)例,方便獲取面板祝钢。
  3. 準(zhǔn)備一個數(shù)據(jù)結(jié)構(gòu)棻裙妫控制面板的顯示和隱藏。
  4. 書寫實(shí)例化面板邏輯的成員函數(shù)拦英。
定義一個根據(jù)面板類型得到實(shí)例化面板
  /// <summary>
    /// 根據(jù)面板類型 得到實(shí)例化的面板
    /// </summary>
    /// <returns></returns>
    private BasePanel GetPanel(UIPanelType panelType)
    {
        if (panelDict == null)
        {
            panelDict = new Dictionary<UIPanelType, BasePanel>();
        }

        BasePanel panel = panelDict.TryGet(panelType);

        if (panel == null)
        {
            //如果找不到蜒什,那么就找這個面板的prefab的路徑,然后去根據(jù)prefab去實(shí)例化面板          
            string path = panelPathDict.TryGet(panelType);
            GameObject instPanel = GameObject.Instantiate(Resources.Load(path)) as GameObject;
            instPanel.transform.SetParent(CanvasTransform, false);
            panelDict.Add(panelType, instPanel.GetComponent<BasePanel>());
            return instPanel.GetComponent<BasePanel>();
        }
        else
        {
            return panel;
        }

    }
將頁面入棧疤估,顯示面板
  /// <summary>
    /// 把某個頁面入棧灾常,  把某個頁面顯示在界面上
    /// </summary>
    public void PushPanel(UIPanelType panelType)
    {
        if (panelStack == null)
            panelStack = new Stack<BasePanel>();

        //判斷一下棧里面是否有頁面
        if (panelStack.Count > 0)
        {
            BasePanel topPanel = panelStack.Peek();
            topPanel.OnPause();
        }

        BasePanel panel = GetPanel(panelType);
        Debug.Log(panel == null);
        panel.OnEnter();
        panelStack.Push(panel);
    }
出棧,隱藏面板
/// <summary>
    /// 出棧 铃拇,把頁面從界面上移除
    /// </summary>
    public void PopPanel()
    {
        if (panelStack == null)
            panelStack = new Stack<BasePanel>();

        if (panelStack.Count <= 0) return;

        //關(guān)閉棧頂頁面的顯示
        BasePanel topPanel = panelStack.Pop();
        topPanel.OnExit();

        if (panelStack.Count <= 0) return;
        BasePanel topPanel2 = panelStack.Peek();
        topPanel2.OnResume();

    }

六钞瀑,開發(fā)菜單面板類和背包類使用UIManager

上面所述我們已經(jīng)完成大部分UI框架的核心架構(gòu)了,接下來根據(jù)個人項(xiàng)目來使用該框架慷荔,這里我將舉個例子來使用UI框架仔戈。

開發(fā)菜單面板類

我們先將我們的面板繼承公共基類BasePanel,其次這里我將介紹在菜單面板類重寫暫停拧廊,重啟监徘,以及Button監(jiān)聽事件邏輯。

 /// <summary>
    /// 界面暫停
    /// </summary>
    public override void OnPause()
    {
        canvasGroup.blocksRaycasts = false;//當(dāng)彈出新的面板的時候吧碾,讓主菜單面板 不再和鼠標(biāo)交互
    }

    /// <summary>
    /// 界面重啟
    /// </summary>
    public override void OnResume()
    {
        canvasGroup.blocksRaycasts = true;
    }

    /// <summary>
    /// 啟動對應(yīng)面板主要用于監(jiān)聽事件
    /// </summary>
    /// <param name="panelTypeString"></param>
    public void OnPushPanel(string panelTypeString)
    {
        UIPanelType panelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString);
        UIManager.Instance.PushPanel(panelType);
    }

接下來我們再開發(fā)一個背包面板凰盔,來測試UI框架,這里背包面板主要重寫顯示和隱藏邏輯倦春,暫停和重啟邏輯與菜單面板相似户敬。


    /// <summary>
    /// 顯示背包
    /// </summary>
    public override void OnEnter()
    {
        if (canvasGroup == null) canvasGroup = GetComponent<CanvasGroup>();
        canvasGroup.alpha = 1;
        canvasGroup.blocksRaycasts = true;

        Vector3 temp = transform.localPosition;
        temp.x = 600;
        transform.localPosition = temp;
        transform.DOLocalMoveX(0, .5f);
    }

    /// <summary>
    /// 隱藏背包
    /// </summary>
    public override void OnExit()
    {
        //canvasGroup.alpha = 0;
        canvasGroup.blocksRaycasts = false;

        transform.DOLocalMoveX(600, .5f).OnComplete(() => canvasGroup.alpha = 0);
    }
最后我們將菜單面板的Button注冊監(jiān)聽事件OnPushPanel落剪,分配面板類型字符串,即可開啟測試尿庐。

七. 結(jié)束

感謝觀看忠怖,希望這篇文章對你真正有所感悟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抄瑟,一起剝皮案震驚了整個濱河市凡泣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌皮假,老刑警劉巖鞋拟,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惹资,居然都是意外死亡贺纲,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門褪测,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猴誊,“玉大人,你說我怎么就攤上這事侮措〕碇猓” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵萝毛,是天一觀的道長项阴。 經(jīng)常有香客問我,道長笆包,這世上最難降的妖魔是什么环揽? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮庵佣,結(jié)果婚禮上歉胶,老公的妹妹穿的比我還像新娘。我一直安慰自己巴粪,他們只是感情好通今,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肛根,像睡著了一般辫塌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上派哲,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天臼氨,我揣著相機(jī)與錄音,去河邊找鬼芭届。 笑死储矩,一個胖子當(dāng)著我的面吹牛感耙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播持隧,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼即硼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屡拨?” 一聲冷哼從身側(cè)響起只酥,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洁仗,沒想到半個月后层皱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體性锭,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赠潦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了草冈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片她奥。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖怎棱,靈堂內(nèi)的尸體忽然破棺而出哩俭,到底是詐尸還是另有隱情,我是刑警寧澤拳恋,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布凡资,位于F島的核電站,受9級特大地震影響谬运,放射性物質(zhì)發(fā)生泄漏隙赁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一梆暖、第九天 我趴在偏房一處隱蔽的房頂上張望伞访。 院中可真熱鬧,春花似錦轰驳、人聲如沸厚掷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冒黑。三九已至,卻和暖如春勤哗,著一層夾襖步出監(jiān)牢的瞬間薛闪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工俺陋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留豁延,地道東北人昙篙。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像诱咏,于是被迫代替她去往敵國和親苔可。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容