UnityVR--UIManager--UI管理2

news2024/9/26 3:30:47

目录

前言

 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;//加载根节点的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<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.position
            rectTransform.localScale = Vector3.one;     //对应节点的Scale
            rectTransform.offsetMax = Vector2.zero;     //对应Right和Bottom
            rectTransform.offsetMin = Vector2.zero;     //对应Left和Top
            panel = 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];      //那就先取得这个panel
            panel.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()
    {
        //使用字典迭代器遍历所有面板,也可以用foreach
        Dictionary<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.coloradmin.cn/o/657294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web服务器群集:部署LAMP平台

目录 一、理论 1.LAMP平台 2.Apache网址服务基础 2.httpd服务器的基本配置 3.构建虚拟Web主机 4.MySQL服务 5.构建PHP运行环境 二、实验 1.LAMP架构DISCUZ论坛应用 三、问题 1.虚拟机内存分配上限问题&#xff0c;内存上限只能加到3G。 2.虚拟机CPU如何设置才更加合…

RISC-V 函数调用约定和Stack使用

RISC-V 函数调用约定和Stack使用 引言RISC-V vs x86RISC-V寄存器StackStruct补充函数调用约定寄存器约定函数跳转和返回指令的编程约定被调用函数的编程约定 RISC-V 汇编与 C 混合编程RISC-V 汇编调用 C 函数C 函数中嵌入 RISC-V 汇编 引言 MIT 6.S081 2020 操作系统 本文为M…

1744_Perl获取文件属性参数

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 前阵子写通过Perl执行判断调用ImageMagick实现图像的批量压缩功能脚本时用到过这个功能&#xff0c;只是当时仅仅看了一个获取文件大小的功能。 今天看第六版的小骆驼书又看到了…

一篇十分硬核的QT开发经验文章!送给正在做QT开发或想从事QT开发的你

当编译发现大量错误的时候&#xff0c;从第一个看起&#xff0c;一个一个的解决&#xff0c;不要急着去看下一个错误&#xff0c;往往后面的错误都是由于前面的错误引起的&#xff0c;第一个解决后很可能都解决了。 定时器是个好东西&#xff0c;学会好使用它&#xff0c;有时…

别再为缓慢启动而失去用户! 让你的Android应用体验绝佳性能

为什么要启动优化&#xff1f; 启动优化是为了提升应用程序的启动性能&#xff0c;即减少应用程序从启动到可交互状态所需要的时间。以下是一些关键原因&#xff0c;解释了为什么启动优化是重要的&#xff1a; 用户体验&#xff1a; 启动时间是用户与应用程序互动的第一个体验…

常用API

文章目录 1、String类String概述创建对象的两种方式字符串的内容比较String常用APIString类开发验证码功能手机号码屏蔽功能 2、Object类Object类的作用Object类的常用方法**Object的toString方法**Object的equals方法 3、Objects类4、StringBuilder类5、Math类6、System类7、B…

2023-06-17:说一说redis中渐进式rehash?

2023-06-17&#xff1a;说一说redis中渐进式rehash&#xff1f; 答案2023-06-17&#xff1a; 在Redis中&#xff0c;如果哈希表的数组一直保持不变&#xff0c;就会增加哈希冲突的可能性&#xff0c;从而降低检索效率。为了解决这个问题&#xff0c;Redis会对数组进行扩容&am…

基于Spark的气象数据分析

研究背景与方案 1.1.研究背景 在大数据时代背景下&#xff0c;各行业数据的规模大幅度增加&#xff0c;数据类别日益复杂&#xff0c;给数据分析工作带来极大挑战。气象行业和人们的生活息息相关&#xff0c;随着信息时代的发展&#xff0c;大数据技术的出现为气象数据的发展…

第九章 形态学图像处理

文章目录 9形态学图像处理9.2腐蚀与膨胀9.2.1腐蚀9.2.2膨胀 9.3开操作和闭操作9.5一些基本形态学方法9.3.1边界提取 9.6灰度级形态学9.6.3一些基本的形态学算法 9形态学图像处理 9.2腐蚀与膨胀 9.2.1腐蚀 imgcv2.imread(dige.png,0) kernel np.ones((3,3),np.uint8) num[[…

第七章 原理篇:HOG特征提取

之前面试被问到了然后没有讲出来&#xff0c;所以今天复习一下&#xff01; 气死我了&#xff01; 参考教程&#xff1a; What Is a Feature Descriptor in Image Processing? https://medium.com/analytics-vidhya/a-gentle-introduction-into-the-histogram-of-oriented-…

scratch lenet(3): 直方图均衡化的C语言实现

文章目录 1. 目的2. 原理3. 实现3.1 获得直方图 int hist[256]3.2 获得累积分布 int cdf[256]3.3 均衡化公式3.4 遍历原图&#xff0c;逐点均衡化&#xff0c;得到结果 4. 完整代码和结果4.1 例子14.2 例子24.3 例子34.4 完整代码 5. References 1. 目的 用 C 语言实现直方图均…

低价618背后,看见品牌营销的「产业新洪流」

如今消费者对于低价与品质的兼得需求&#xff0c;正倒逼一个全新的产业经济模式出现&#xff0c;而企业恰是最直接承载者。只有具备真正“低价”的能力模型&#xff0c;企业才能参与到下一轮的产业经济&#xff0c;甚至是社会经济的发展浪潮中。 作者|皮爷 出品|产业家 成本不…

Elasticsearch设置密码

Elasticsearch设置密码 概述ES开启认证配置密码访问开启安全认证的EScurl浏览器直接访问Kibana 配置 es认证直接配置用户名密码到 kibana.yml以kibana密钥的形式使用命令行启动参数形式指定用户名密码 使用kibana 查看es用户 概述 ES默认没有开启安全组件&#xff0c;如果我们…

简单的Dubbo实验环境搭建

Dubbo-api中定义的UserQueryFacade接口可以发布在私服上&#xff0c;这样子dubbo-consumer和dubbo-provider就可以以maven依赖的形式导入使用。dubbo-provider需要提供接口的实现类&#xff0c;dubbo-consumer需要订阅该实现类&#xff0c;他们的元数据都通过zk进行记录。 许多…

Three.js学习项目--3D抗美援朝数据可视化

文章目录 部分场景体验地址操作说明 视频我做了哪些&#xff08;功能&#xff09;局限源代码地址部分逻辑按需渲染模型加载动画控制器模型纹理条件切换模型加载同时请求部分纹理 生成进度条模型缩放小动画 部分场景 体验地址 https://kmyc.hongbin.xyz/ 操作说明 视频 操作说…

LeetCode——查询后矩阵的和

目录 1、题目 2、题目解读 3、代码 1、题目 2718. 查询后矩阵的和 - 力扣&#xff08;Leetcode&#xff09; 给你一个整数 n 和一个下标从 0 开始的 二维数组 queries &#xff0c;其中 queries[i] [typei, indexi, vali] 。 一开始&#xff0c;给你一个下标从 0 开始的…

数学建模常用模型(一):灰色预测法

数学建模常用模型&#xff08;一&#xff09;&#xff1a;灰色预测法 灰色预测法是一种用于处理少量数据、数据质量较差或者缺乏历史数据的预测方法。它适用于一些非线性、非平稳的系统&#xff0c;尤其在短期预测和趋势分析方面有着广泛的应用。灰色预测法作为一种强大的数学…

基于STM32+OneNet设计的物联网智慧路灯

一、前言 近年来,构筑智慧城市、推动城镇发展被国家列入重要工作范畴。发布的《超级智慧城市报告》显示,全球已启动或在建的智慧城市有1000多个,中国在建500个,远超排名第二的欧洲(90个)。从在建智慧城市的分布来看,我国已初步形成环渤海、长三角、珠三角、中西部四大智…

FreeRTOS 任务优先级 【杂记】

FreeRTOS任务优先级 FreeRTOS任务优先级&#xff1a;任务优先级数值越小&#xff0c;任务优先级越低。 1、 FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h 文件中的configMAX_PRIORITIES 进行配置的&#xff0c;用户实际可以使用的优先级范围是 0 到 configMAX_PRIORIT…

python 第七章 字典dict {}

系列文章目录 第一章 初识python 第二章 变量 第三章 基础语句 第四章 字符串str 第五章 列表list [] 第六章 元组tuple ( ) 文章目录 字典的应用场景创建字典的语法字典常见操作增改删查 字典的循环遍历遍历字典的key遍历字典的value遍历字典的元素遍历字典的键值对&#xff0…