UnityVR--UIManager--UI管理2

目录

前言

 UIManger的实现

  1.  需要用到的变量和数据

  2. 在构造中的工作

  3. 初始化面板

  4. 显示面板

5. 隐藏面板和隐藏所有面板

  6. 其他小工具 

在场景中实现

  1.  不同面板的类型设置

  2.  场景中的设置


前言

  接前篇,上一篇已经有了UITools.cs其中定义了UI面板需要使用的基本工具,如:初始化UI节点、遍历所有节点、在按键上添加EventTrigger等,以及各种类型UI面板继承UITools的个性化工具,比如MainUI.cs。本篇要实现一个简单的管理工具UIManager,并使用它的工具实现面板的初始化、显示、隐藏等。功能比较简单,最终效果如下(这里的动画效果是原文件中的动画):

UnityVR--UIManager--UI管理2_第1张图片

 UIManger的实现

  作为一个管理器类,UIManager也需要继承单例,关于单例的内容详见():

public class UIManager : Single
{

}

  在UIManager中要实现的功能有:1. 初始化时在场景中载入UI预制体;2. 获取UI节点上的重要组件(如Canvas),以备后用;3. 初始化面板,加载UI预制体到相应节点下,并放置到合理的屏幕位置;4. 显示/隐藏/消除面板等工具;5. 根据项目设置其他实用工具。以下为具体代码:

  1.  需要用到的变量和数据

    public enum PanelType  //面板的类型:主面板、副面板、弹窗
    {
        Main,Extra,UP
    }

    private string uiPath = "UI/";  //加载UI预制体的路径,“Resource/UI”
    private Transform UI;    //获取场景中的UI根节点
    private Transform Canvas_Main;  //获取UI的各个节点,以便于控制位置等
    private Transform Canvas_Extra;
    private Transform Canvas_UP;

    private Camera uiCamera;   //获取UI相机
    private Canvas Cvs_Main;   //获取主面板上的Canvas组件(其他面板本例中暂不需要)
    private RectTransform rectTransform_Main;  //获取主面板RectTransform组件,为了安排位置

    Dictionary UIList;  //管理所有的面板的字典

  以上的变量均可以封装使用,且将改为只读属性。

  2. 在构造中的工作

  其中的UI、Canvas_Main等节点设置见上一篇(UI管理1):

public UIManager()
    {
        UIList= new Dictionary(); //实例化字典
        UI = Resload.Instance.LoadPrefab(uiPath + "UI").transform;//加载根节点的Prefab
        Canvas_Main = UI.Find("Canvas_Main");//找到三个主要节点,以备之后放入相应的Prefab
        Canvas_Extra = UI.Find("Canvas_Extra");
        Canvas_UP = UI.Find("Canvas_UP");
        Cvs_Main = Canvas_Main.GetComponent();//载入主节点上的几个重要组件
        rectTransform_Main = Canvas_Main.GetComponent();
        uiCamera= UI.Find("UICamera").GetComponent();
        Object.DontDestroyOnLoad(UI.gameObject);  //设置在场景切换时,UI节点不消除
    }

  3. 初始化面板

  ——将面板的预制体载入UI的相应节点中,并设置位置

    //初始化面板
    public T InitPanel(string panelName,string prefabName,UnityAction action=null,
        PanelType type=PanelType.Extra) where T : UITools
    {
        UITools panel;  
        if (!IsHavePanel(panelName))  //使用小工具判断字典中是否有该面板
        {//没有该面板,那么再加载预制体
            GameObject GO = Resload.Instance.LoadPrefab(uiPath + prefabName);
            GO.name = panelName;       //让场内的节点取名为自定义的名字
            RectTransform rectTransform =GO.GetComponent();
            //获取面板上的RectTransform,以便于安排位置

            //设置不同的类型的面板对应地显示在哪个节点下面:
            switch (type)
            {
                case PanelType.Main: rectTransform.SetParent(Canvas_Main); break;  
                case PanelType.Extra: rectTransform.SetParent(Canvas_Extra); break;
                case PanelType.UP: rectTransform.SetParent(Canvas_UP); break;
            }

            //设置面板位置,可以根据不同情况调整
            rectTransform.localPosition = Vector3.zero; //对应节点的Transform.position
            rectTransform.localScale = Vector3.one;     //对应节点的Scale
            rectTransform.offsetMax = Vector2.zero;     //对应Right和Bottom
            rectTransform.offsetMin = Vector2.zero;     //对应Left和Top
            panel = GO.GetComponent() ?? GO.AddComponent();
            //检测本脚本挂载的GameObject上是否有挂载相应的工具类,
            //比如MainUI就要挂载MainUi.cs,没有就加载一个

            //赋值完成后,将这个Panel加到字典中
            UIList.Add(panelName, panel);   //panelName:名字;panel:比如MainUI类
            panel.Init(action);         //初始化,这个Init是在UITools中定义的Init
        }
        else  //如果字典里已有
        {
            panel = UIList[panelName];      //那就先取得这个panel
            panel.transform.SetAsLastSibling(); //然后加载到UI节点的最后面(显示在最前面)
        }
        return panel as T;  
    }

  其中,判断面板是否存在于字典的小工具:

    bool IsHavePanel(string panelName)
    {
        return UIList.ContainsKey(panelName);
    }

  4. 显示面板

    public T ShowPanel(string panelName, string prefabName, UnityAction action = null,
        PanelType type = PanelType.Extra) where T : UITools
    {
        UITools panel;  
        if(!IsHavePanel(panelName))
        {//先判断字典里是否有这个面板,没有的话先初始化
            panel = InitPanel(panelName, prefabName, action, type);
        }
        else
        {//如果字典里已经有该面板了,就从字典中查找
            panel = UIList[panelName];
            if(panel!=null)
            {//找到了,就将它显示在最前面
                panel.transform.SetAsLastSibling();
            }
            else
            {
                foreach(var panelTemp in UIList)  //panel已经在场景中显示,但字典中没有获取到
                {
                    Debug.Log(panelTemp.Key+"不存在字典中");
                    Debug.Log(panelTemp.Value + "不存在字典中");
                }
            }
        }
        panel.Show(action);
        return panel as T;
    }

5. 隐藏面板和隐藏所有面板

    public void HidePanel(string panelName)
    {
        if(IsHavePanel(panelName))
        {
            UIList[panelName].Hide();
        }
    }

    public void HideAllPanel()
    {
        //使用字典迭代器遍历所有面板,也可以用foreach
        Dictionary.Enumerator enumerator= UIList.GetEnumerator();
        while(enumerator.MoveNext())
        {
            UIList[enumerator.Current.Key].Hide();
        }
    }

  6. 其他小工具 

  ——比如获取组件,这个组件是挂载在每个面板上的继承UITools的类型,比如MainUi.cs;比如加载UI预制体工具:

    public T GetPanel(string panelName) where T: UITools
    {//获取面板的类型(继承UITools)
        if (IsHavePanel(panelName))
            return UIList[panelName] as T;
        return null;
    }

    public GameObject LoadUIPrefab(string prefabName,Transform parent, string name=null)
    {//从预制体文件夹中加载UI预制体
        GameObject gameObject = Resload.Instance.LoadPrefab(uiPath + prefabName);
        gameObject.name=name!=string.Empty?name:prefabName;  //传入的名字是否为空,空就用prefabName
        //之后就如初始化时一样,调整位置、缩放等
        RectTransform rectTransform=gameObject.transform as RectTransform;
        rectTransform.SetParent(parent);  //将
        rectTransform.localPosition = Vector3.zero;
        rectTransform.localScale = Vector3.one;
        rectTransform.offsetMax = Vector3.zero;
        rectTransform.offsetMin = Vector3.zero;
        return gameObject;
    }

  以上是本次UI管理中需要用到的对面板操作的工具,当然这次使用的面板都比较简单,在复杂项目中需要用到的管理方法更多。

在场景中实现

  1.  不同面板的类型设置

  场景中需要加载3个面板:MAIN、EXTRAS、EXIT,每一个面板都有各自的管理类,继承UITools,主面板MAIN的管理器上一篇中已经定义,并且将它挂载在MAIN面板上,另外需要控制EXTRAS和EXIT的,实现的功能少,因此都挺简单:

  (1)ExtraUi.cs挂载在EXTRAS面板上:

public class ExtraUi :UITools
{
    public override void Init(UnityAction action = null)
    {//初始化EXTRA面板
        base.Init(action);
        TMP_Text text = GetComponent("TextTooltip");
        text.text = "Extra面板初始化成功";
        //给每一个图片按钮加上事件,用于打开链接
        AddEventTrigger("Btn_CCP", EventTriggerType.PointerClick, CCP);
        AddEventTrigger("Btn_Clean1", EventTriggerType.PointerClick, Clean1);
        AddEventTrigger("Btn_Essence", EventTriggerType.PointerClick, Essence);
        AddEventTrigger("Btn_SciFi", EventTriggerType.PointerClick, SciFi);

    }
    private void CCP(BaseEventData data)
    {
        Application.OpenURL("http://u3d.as/1JZG");
    }

    private void SciFi(BaseEventData data)
    {
        Application.OpenURL("http://u3d.as/1AaR");
    }

    private void Clean1(BaseEventData data)
    {
        Application.OpenURL("http://u3d.as/1hTi");
    }

    private void Essence(BaseEventData data)
    {
        Application.OpenURL("http://u3d.as/1t11");
    }

}

  (2)ExitUi.cs挂载在EXIT预设体面板上

public class ExitUi :UITools
{
    public override void Init(UnityAction action = null)
    {
        base.Init(action);
        AddEventTrigger("Btn_No", EventTriggerType.PointerClick, OnEventBack);
        AddEventTrigger("Btn_Yes", EventTriggerType.PointerClick, OnEventBye);
    }
    private void OnEventBack(BaseEventData data)
    {//如果选择NO按钮,隐藏Exit面板
        UIManager.Instance.HidePanel("ExitPanel");
    }
    private void OnEventBye(BaseEventData data)
    {//如果选择Yes按钮,把所有面板都关了
        UIManager.Instance.DestroyAllPanel();
    }
}

  (3)建立一个Test.cs作为控制文件,随意挂在场景内的节点。作用是在场景初始化时调用UIManager并使用ShowPanel工具加载一个预制体MAIN,在场景中命名为MainPanel,由于这个面板的类型是Main,所以将它加载到Canvas_Main节点下:

public class Test : MonoBehaviour
{
    void Start()
    {
        UIManager.Instance.ShowPanel("MainPanel", "MAIN",null, UIManager.PanelType.Main);  
    }

  2.  场景中的设置

  (1) 预制体文件夹和每个预制体的节点结构,上一篇中已经介绍过了。

  (2)场景中只要有一个Test.cs,另外还需要一个Resload工具,加载时需要使用(详见ResourceManager)

UnityVR--UIManager--UI管理2_第2张图片

   (3)场景运行时,所有节点自动加载到相应的节点下(如果没有明确设置,默认是在Canvas_Extra节点下的),加载后的名字按照上面初始化工具中设置的名字:

UnityVR--UIManager--UI管理2_第3张图片

   效果就是本文一开始的效果。

你可能感兴趣的:(unity,vr)