UI框架(UGUI)

发表于2018-03-21
评论0 1.22w浏览
本篇文章是通过Demo来和大家介绍UI框架,希望这样可以更方便大家学习掌握,主要也是考虑到了有些细节在文章中很难都全部介绍到。

工具:VS2010、Unity5.2.3f

先介绍整个Demo的主面板
其中任务、技能、符文等等都是按钮,点击按钮会生成相应面板

【Protobuf的生成与解析】

要使得框架的可扩展性与自适应性,我把各个面板的名字与路径配置到protobuf文件
在VS中我们把代码编写完成后生成protobuf文件,在Unity中解析。
如何生成与解析可以参考:

【UIManager】

在Unity工程中,使用UIManager这个类对整个UI框架进行管理
UIManager.cs
using UnityEngine;  
using System.Collections;  
using UIFrameworkForProtobuf;  
using System.Collections.Generic;  
public class UIManager   
{  
    private  Dictionary<UIPanelTypeEnum, string> dicPanelPath;//存储面板路径  
    private Dictionary<UIPanelTypeEnum, BaseManager> dicPanelBase;//存储面板BaseManager组件  
    private Stack<BaseManager> panelStack;  
    //单例模式  
    private static UIManager manager;  
    public static UIManager GetInstance  
    {  
        get  
        {  
            if (manager == null)  
            {  
                manager = new UIManager();  
            }  
            return manager;  
        }  
    }  
    private UIManager()  
    {  
        Dederializer();  
    }  
    private Transform canvasTransform;  
    private Transform CanvasTransform  
    {  
        get  
        {  
            if (canvasTransform == null)  
            {  
                canvasTransform = GameObject.Find("Canvas").transform;  
            }  
            return canvasTransform;  
        }  
    }  
<span style="white-space:pre;"> </span>  
<span style="white-space:pre;"> </span>//面板入栈  
    public void PushPanel(UIPanelTypeEnum panelType)  
    {  
        if (panelStack == null)  
        {  
            panelStack = new Stack<BaseManager>();  
        }  
        //判断栈里面是否有页面,如果有,将栈中top对象取出  
        if (panelStack.Count > 0)  
        {  
            BaseManager top = panelStack.Peek();  
            top.OnPause();  
        }  
        BaseManager bm = GetPanel(panelType);  
        panelStack.Push(bm);  
        bm.OnEnter();  
    }  
<span style="white-space:pre;"> </span>  
<span style="white-space:pre;"> </span>//面板出栈  
    public void PopPanel()  
    {  
        if (panelStack == null)  
        {  
            panelStack = new Stack<BaseManager>();  
        }  
        if (panelStack.Count <= 0)  
        {  
            return;  
        }  
        //关闭栈顶的页面显示  
        BaseManager bm = panelStack.Pop();  
        bm.OnExit();  
        if (panelStack.Count <= 0)  
        {  
            return;  
        }  
        BaseManager top = panelStack.Peek();  
        top.OnResume();  
    }  
    private BaseManager GetPanel(UIPanelTypeEnum panelType)  
    {  
        if (dicPanelBase == null)  
        {  
            dicPanelBase = new Dictionary<UIPanelTypeEnum, BaseManager>();  
        }  
        BaseManager bm;  
        dicPanelBase.TryGetValue(panelType,out bm);  
        if (bm == null)  
        {  
            string panelPath;  
            dicPanelPath.TryGetValue(panelType, out panelPath);  
            GameObject objPanel = GameObject.Instantiate(Resources.Load(panelPath)) as GameObject;  
            objPanel.transform.SetParent(CanvasTransform, false);//参数二:是否保留世界坐标信息,由于要将对象存放在Canvase下,所以为false  
            dicPanelBase.Add(panelType, objPanel.GetComponent<BaseManager>());  
            return objPanel.GetComponent<BaseManager>();  
        }  
        else  
        {  
            return bm;  
        }  
    }  
    //将protobuf文件反序列化为对象  
    private void Dederializer()  
    {  
        dicPanelPath = new Dictionary<UIPanelTypeEnum, string>();  
        UIPanelTypeList panelTypes = ProtobufHelper.DederializerFromFile<UIPanelTypeList>(Application.streamingAssetsPath + "/UIPanelType.bin");  
        foreach (UIPanelType type in panelTypes.uiPanelTypes)  
        {  
            UIPanelTypeEnum enumType = (UIPanelTypeEnum)System.Enum.Parse(typeof(UIPanelTypeEnum), type.panelName);  
            dicPanelPath.Add(enumType, type.panelPath);  
            Debug.Log(type.panelName);  
            Debug.Log(type.panelPath);  
        }  
    }  
}  

【面板状态组件】

我们为每个面板添加一个C#脚本组件,分别命名为TaskPanel、SkillPanel……
他们分别继承自BaseManager类
BaseManager.cs
using UnityEngine;  
using System.Collections;  
public class BaseManager :MonoBehaviour  
{  
    /// <summary>  
    /// 界面显示  
    /// </summary>  
    public virtual void OnEnter()  
    {  
    }  
    /// <summary>  
    /// 界面暂停  
    /// </summary>  
    public virtual void OnPause()  
    {  
    }  
    /// <summary>  
    /// 界面继续  
    /// </summary>  
    public virtual void OnResume()  
    {  
    }  
    /// <summary>  
    /// 界面不显示,退出这个界面,界面被关闭  
    /// </summary>  
    public virtual void OnExit()  
    {  
    }  
}  

这里介绍主面板的MainPanel组件
MainPanel.cs
using UnityEngine;  
using System.Collections;  
public class MainPanel : BaseManager  
{  
    private CanvasGroup canvasGroup;  
    void Start()  
    {  
        canvasGroup = GetComponent<CanvasGroup>();  
    }  
    public override void OnPause()  
    {  
        canvasGroup.blocksRaycasts = false;//当弹出新的面板的时候,让主菜单面板 不再和鼠标交互  
    }  
    public override void OnResume()  
    {  
        canvasGroup.blocksRaycasts = true;  
    }  
    public void OnPushPanel(string panelTypeString)  
    {  
        UIPanelTypeEnum panelType = (UIPanelTypeEnum)System.Enum.Parse(typeof(UIPanelTypeEnum), panelTypeString);  
        UIManager.GetInstance.PushPanel(panelType);  
    }  
}  
主面板的各个按钮中,将按钮点击事件注册到OnPushPanel函数中,并传入一个面板名

【检测】

将主面板添加到游戏对象上
ManagerRoot.cs
using UnityEngine;  
using System.Collections;  
public class ManagerRoot : MonoBehaviour   
{  
    // Use this for initialization  
    void Start ()   
    {  
        UIManager.GetInstance.PushPanel(UIPanelTypeEnum.Main);  
    }  
}  
整个游戏的工程源码下载链接:打开链接
来自:http://blog.csdn.net/qq_33747722/article/details/66967632

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引