UnityVR--UIManager--UI管理2

news/2024/10/20 13:52:23/

目录

前言

 UIManger的实现

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

  2. 在构造中的工作

  3. 初始化面板

  4. 显示面板

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

  6. 其他小工具 

在场景中实现

  1.  不同面板的类型设置

  2.  场景中的设置


前言

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

 UIManger的实现

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

public class UIManager : Single<UIManager>
{}

  在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<string, UITools> UIList;  //管理所有的面板的字典

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

  2. 在构造中的工作

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

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

  3. 初始化面板

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

    //初始化面板public T InitPanel<T>(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>();//获取面板上的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.positionrectTransform.localScale = Vector3.one;     //对应节点的ScalerectTransform.offsetMax = Vector2.zero;     //对应Right和BottomrectTransform.offsetMin = Vector2.zero;     //对应Left和Toppanel = GO.GetComponent<T>() ?? GO.AddComponent<T>();//检测本脚本挂载的GameObject上是否有挂载相应的工具类,//比如MainUI就要挂载MainUi.cs,没有就加载一个//赋值完成后,将这个Panel加到字典中UIList.Add(panelName, panel);   //panelName:名字;panel:比如MainUI类panel.Init(action);         //初始化,这个Init是在UITools中定义的Init}else  //如果字典里已有{panel = UIList[panelName];      //那就先取得这个panelpanel.transform.SetAsLastSibling(); //然后加载到UI节点的最后面(显示在最前面)}return panel as T;  }

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

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

  4. 显示面板

    public T ShowPanel<T>(string panelName, string prefabName, UnityAction action = null,PanelType type = PanelType.Extra) where T : UITools{UITools panel;  if(!IsHavePanel(panelName)){//先判断字典里是否有这个面板,没有的话先初始化panel = InitPanel<T>(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(){//使用字典迭代器遍历所有面板,也可以用foreachDictionary<string,UITools>.Enumerator enumerator= UIList.GetEnumerator();while(enumerator.MoveNext()){UIList[enumerator.Current.Key].Hide();}}

  6. 其他小工具 

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

    public T GetPanel<T>(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<TMP_Text>("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<MainUi>("MainPanel", "MAIN",null, UIManager.PanelType.Main);  }

  2.  场景中的设置

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

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

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

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


http://www.ppmy.cn/news/439873.html

相关文章

中年“难”人

对于每个打工人而言&#xff0c;人生无外乎两种状态&#xff0c;要么已是中年人&#xff0c;要么走在成为中年人的路上&#xff0c;可是当下横空出世的中产作死三件套&#xff0c;让每个打工人都不寒而栗 - 房贷近千万&#xff1b; 配偶不上班&#xff1b; 两娃上国际。 这个…

快速注释码或解除注释(C++)

https://download.csdn.net/download/asuf1364/87921629?spm1001.2014.3001.5503

PoseiSwap IDO 即将开启,一览 $POSE 经济模型

以太坊创始人 Vitalik Buterin 曾在今年以太坊黑山大会上&#xff0c;进行了以“以太坊的三个技术挑战&#xff1a;扩容、隐私和用户安全”为主题的演讲&#xff0c;阐明了具有隐私性、可扩展性和安全性的且易访问的区块链生态将是行业发展趋势&#xff0c;或许重复造轮子正在变…

联想710s设置cpu虚拟化的时候狂按F2进不了bios

联想710s在耳机插孔下面有热键&#xff0c;用卡针戳一下就可以了。

联想710s更换nvme协议固态后重装系统后启动出现Boot Menu界面无法进入系统

联想710s更换nvme协议固态&#xff08;金士顿1T m.2nvme&#xff09;,重装系统&#xff0c;能正常重装&#xff0c;在PE界面可以看到已安装&#xff0c;但是不能正常进入系统&#xff0c;可以按FNF2进入BIOS界面&#xff0c;各位大神怎么解决。

联想电脑关闭HotKey (热键模式),使用快捷功能时才需按Fn

在联想小新笔记本使用中发现&#xff0c;直接按F1-F12出现的都是快捷功能&#xff0c;而想使用F1-F12需要按Fn。我们在BIOS里关闭hotkey即可恢复。 传统功能键设计 媒体功能键设计 关闭步骤 方法1&#xff1a; 按fnesc esc上的指示灯亮起&#xff0c;则表示切换回了Fn在上方…

解决联想710s更换nvme协议固态后重装系统出现蓝屏代码inaccessible_boot_device无限重启问题

问题描述 更换固态后用pe安装win10&#xff0c;开机后蓝屏&#xff0c;出现 inaccessible_boot_device代码&#xff0c;此时电脑可以打开bios界面。 解决方法 1&#xff1a;下载对应的RAID驱动程序 联想710S是Intel的:“Intel快速存储技术(IntelRST)RAID驱动程序 下载地址&…

联想IdeaPad710s进入bios界面的详细步骤

1. 首先&#xff0c;我们需要知道BIOS是英文"Basic Input Output System"的缩略语&#xff0c;直译过来后中文名称就是"基本输入输出系统"。其实&#xff0c;它是一组固化到计算机内主板上一个ROM芯片上的程序&#xff0c;它保存着计算机最重要的基本输入输…