UnityVR--UIManager--UI管理2

这篇具有很好参考价值的文章主要介绍了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,UnityVR-管理阶层Managers,unity,vr

 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)

UnityVR--UIManager--UI管理2,UnityVR-管理阶层Managers,unity,vr

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

UnityVR--UIManager--UI管理2,UnityVR-管理阶层Managers,unity,vr

   效果就是本文一开始的效果。文章来源地址https://www.toymoban.com/news/detail-538186.html

到了这里,关于UnityVR--UIManager--UI管理2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity之VR如何实现跟随视角的UI

    我们在制作VR项目的时候,大部分时候,是把UI固定到一个位置,比如桌子或者空中,这么做固然稳定,但是当我们有以下需求的时候,固定位置的UI可能会不适用: 1.场景较小,操作物体占用了很大体积,没有固定的可以清晰显示完整UI的位置。 2.需要频繁的前后左右,更换

    2024年02月08日
    浏览(41)
  • 【VRTK】【VR开发】【Unity】18-VRTK与Unity UI控制的融合使用

    课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 VRTK和Unity自身的UI控制包可以配合使用发挥效果。本篇就讨论这方面的实战内容。 之前可以互动的立体UI并不是传统的2D UI对象,在实际使用中,还是会希望在VR游戏中也与World Sp

    2024年02月04日
    浏览(45)
  • Unity VR 开发教程 OpenXR+XR Interaction Toolkit (五) UI

    此教程相关的详细教案,文档,思维导图和工程文件会放入 Spatial XR 社区 。这是一个高质量知识星球 XR 社区,博主目前在内担任 XR 开发的讲师。此外,该社区提供教程答疑、及时交流、进阶教程、外包、行业动态等服务。 社区链接: Spatial XR 高级社区(知识星球) Spatial

    2024年02月11日
    浏览(40)
  • Unity之XR Interaction Toolkit如何在VR中实现一个可以拖拽的UI

    普通的VR项目中,我们常见的UI都是一个3D的UI,放置在场景中的某个位置,方便我们使用射线点击。但是为了更好的体验,我们可能会有跟随头显的UI,或者可拖拽的UI,这样更方便用户去操作。 所以我们今天的需求就是:如何基于XR Interaction Toolkit 插件 在VR中使用手柄射线来

    2024年02月19日
    浏览(41)
  • UnityVR--AudioManager--音频管理中心

    目录 前言 建立音频配置文件AudioConfig 建立音频管理AudioManager 使用AudioManager播放音效 前言   关于音频组件的简单使用请详见VideoPlayerAudioSource,不过在一个工程项目中,会有很多的声音文件,播放的时间和条件也不相同,因此在实际制作中,需要集中管理,这就是建立AudioM

    2024年02月09日
    浏览(37)
  • Unity 简易UI管理器

    首先我们需要先定义这么一个UIManager类。 public class UIManager { } UI管理器嘛,顾名思义肯定是用来管理我们游戏中的UI的,而我们游戏当中的UI呢一般是以面板为单位来进行划分的。所以我们还需要一个UI面板类。然后通过我们的UI管理器来管理我们的UI面板。 public class UIPanel {

    2024年02月09日
    浏览(32)
  • Unity的UI管理器

    1、代码  2、如何使用 创建一个测试的UI面板(随便乱拼),将他作为预设体 创建一个测试类 启动发现已经动态创建了Canvas和对应面板

    2024年02月09日
    浏览(37)
  • Unity 3D 开发--UI管理框架

    一、UI基类 一般情况下都是用Panel做容器来放各种控件的,一个Panle相当一个UI小界面,然后做成Prefab进行加载,所有界面都有载入载出功能,有的可能还有等待和恢复的,适合建立一个UI基类,然后各个子界面继承。 二、UI子类 每个UI子界面都继承基类,然后实现各个方法,

    2024年02月13日
    浏览(47)
  • Unity组件开发--UI管理器

    1.Canvas组件: 注意属性: (1)渲染模式是:屏幕空间相机 (2)创建一个UICamera节点,管理相机 (3)屏幕画布缩放模式 (4)画布下挂载两个脚本:UIRoot和UIManager (5)事件系统管理节点必须有: 2.画布下其他节点类型:用于不同界面类型的管理归类window类型 3.先看UIRoot脚本

    2024年01月16日
    浏览(34)
  • Unity UI -- (3)管理屏幕大小和锚点

            在前面我们探索了一些基本的文本格式。我们需要考虑一个问题,这个文本在屏幕大小发生变化时该如何适应呢?         在Unity中,我们可以使用Canvas和Anchor Point(锚点)系统来确保UI元素总是出现在正确的位置,不管它们在哪种屏幕上出现。         在编辑修改

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包