当前位置:   article > 正文

UnityVR--UIManager--UI管理1_unity uimanager

unity uimanager

目录

前言

UI节点的结构

需要用到的组件

  1. CanvasGroup

  2. Button等控件的OnClick()监听

  3. EventTrigger

建立UI工具集

  1. 管理UI节点

  2.  UIBase包含了以下的工具

建立分面板的管理工具——以主面板MainUi为例


前言

  UI在项目中的重要性不言而喻,并且UI控件的种类繁多(UGUI简单介绍仅仅列举了常用控件和重要参数),不仅需要有一个统一的工具管理器来控制各个UI节点的初始化、排列、 组件等,还需要有一个UIManager在项目中统一控制。

  本篇主要介绍UI的工具集UITools,由于篇幅有限,UIManager放在下一篇。

  UITools提供了一系列的关于UI节点的操作工具,尤其是对于Button、Slider等交互性较强的UI控件来说,集中管理这些工具会使代码重用性大大提高,减少系统消耗。

  先从场景中的UI节点设置开始:

UI节点的结构

  UI面板的结构大致如下图,不同的面板使用Canvas作为载体,在场景显示中,先加载的节点(上面的节点)先显示,后加载的节点覆盖在最上面:

  比如,点击主界面中的Play按钮,显示其中一个EXTRAS面板,这个面板就要放在主面板节点的下面,显示时覆盖在主面板上。

  *注:在不少项目中,场景中没有任何UI节点,而UI都是作为预制体的形式存在于Resource资源文件夹中,如下图,制作成UI预制体放在Resource/UI文件夹内(这里用的例子是从AssetStore下载的,只保留了最基本的几个面板):

  每个预制体的结构如下:

   

  

需要用到的UI组件

  在之前的UGUI简单介绍中列举了一些UI控件,这些控件上并不一定默认就有我们需要用到的组件,比如:

  1. CanvasGroup

  

  这个组件可以放在Canvas上,通过对于Alpha值的控制,实现面板渐隐渐显的效果。如果安装了DoTween插件,可以实现一个简单的显示动画效果(缓动效果曲线可以参照:https://easings.net/) 

  1. canvasGroup = gameObject.AddComponent<CanvasGroup>();
  2. canvasGroup.interactable = false; //还没显示完全时不允许交互
  3. canvasGroup.DOFade(0f, 1f); //安装DoTween插件,控制Alfa值,1s内透明度变成0
  4. //1.5s内按照OutExpo动画曲线显现,完成后回调
  5. canvasGroup.DOFade(1f, 1.5f).SetEase(Ease.OutExpo).OnComplete(()=>
  6. {//完成显示之后的回调
  7. action?.Invoke(); //执行回调
  8. canvasGroup.interactable = true; // 面板可以交互
  9. });

  2. Button等控件的OnClick()监听

  Button按钮是交互性最强的按钮,其身上的OnClick(),作为按钮按下的监听,在场景中的使用非常频繁。绑定监听的方法可以按以下方式:

  方法一:直接在OnClick()面板添加脚本节点,并指定回调函数

   方法二:代码中动态设置:

  1. button = transform.GetComponent<Button>();
  2. button.onClick.AddListener(()=>
  3. {
  4. Debug.Log("没想好要干嘛");
  5. });

  3. EventTrigger

  Button中提供了按钮被按下的事件,而EventTrigger中提供了种类更加丰富的事件

  1. public enum EventTriggerType
  2. {
  3. PointerEnter, //鼠标进入
  4. PointerExit, //鼠标离开
  5. PointerDown, //鼠标按下
  6. PointerUp, //鼠标抬起
  7. PointerClick, //鼠标点击(鼠标抬起时已不在原UI上时不会触发,在PointerUp之后调用)
  8. Drag, //鼠标拖拽
  9. Drop, //拖拽结束时鼠标不在被拖拽UI上并且在另外一个UI上时触发(在PointerUp之后)
  10. Scroll, //滑轮滚动时
  11. UpdateSelected, //被选中后的每一帧
  12. Select, //在被选中时
  13. Deselect, //结束选中时
  14. Move, //按方向键时
  15. InitializePotentialDrag, //初始化拖拽(在PointerDown之后,PoinerUp之前调用,点击就会调用)
  16. BeginDrag, //拖拽开始(鼠标按下不移动不会触发)
  17. EndDrag, //拖拽结束
  18. Submit, //默认为Enter键
  19. Cancel //默认为Enter键
  20. }

  添加监听及回调的方式和OnClick()一样,也可以在面板中添加,或者在脚本中动态添加。

  方法一:点击"AddNewEventType"->找到需要绑定的事件,点击“+”号键,并添加回调函数

 

   方法二:代码中添加

  1. EventTrigger.Entry entry = new EventTrigger.Entry();
  2. entry.callback = new EventTrigger.TriggerEvent();
  3. entry.callback.AddListener(callBack);
  4. entry.eventID = EventTriggerType.PointerClick; //添加PointerClick类型的事件
  5. transform.GetComponent<EventTrigger>().triggers.Add(entry);

建立UI工具集

   建立一个基类UIBase.cs,管理所有的UI节点,并且设置一些工具控制面板的初始化、显示、隐藏、添加事件等,之后在场景中可以方便地调用。

  1. 管理UI节点

 首先,我们需要获取并管理所有的UI节点。不过从上面的UI结构图中可以看到,UI的层级结构和节点非常多,不能每次使用时都遍历一遍。因此,在管理这些数据之前,先要使用Tag标签把UI控件分类,需要经常交互的控件使用“UIEvent”标签,仅需控制显示的使用“UIGO”标签,其他一些完全不需要操控的UI节点就不使用标签。

  接着,可以使用以下两种方式管理所有节点:

  方法1:建立字典

  1. //存储一下需要用到的UIGO,以防止每次都去所有节点查找一遍
  2. private Dictionary<string, GameObject> uiItem;

  然后在面板初始化的时候,把所有的节点都加入到字典中去。(详见下面的初始化工具代码)

  方法2:直接拖进面板

    如果节点不多的话,可以建立一批public的GameObject,简单粗暴地将相应的UI节点直接拖进面板,例如:

  1. [Header("MENUS")]
  2. [Tooltip("The Menu for when the MAIN menu buttons")]
  3. public GameObject mainMenu;
  4. [Tooltip("THe first list of buttons")]
  5. public GameObject firstMenu;
  6. [Tooltip("The Menu for when the PLAY button is clicked")]
  7. public GameObject playMenu;
  8. [Tooltip("The Menu for when the EXIT button is clicked")]
  9. public GameObject exitMenu;
  10. [Tooltip("Optional 4th Menu")]
  11. public GameObject extrasMenu;

  然后一个一个对应拖进去

以下详细介绍一下UIBase.cs实现的过程:

  2.  UIBase包含了以下的工具

  (1)初始化——需要实现的工作有:遍历UI节点并将它们放入字典管理、给“UIGO”标签的节点挂上EventTrigger组件、给根节点(Canvas)挂上CanvasGroup组件。

  1. private Dictionary<string, GameObject> uiItem; //字典用于存储UI节点
  2. public virtual void InitPanel(UnityAction action=null)
  3. {
  4. uiItem= new Dictionary<string, GameObject>();//实例化字典对象
  5. List<Transform> list= new List<Transform>(); //建立一个列表用于存储节点
  6. FindChild(transform,list);
  7. //使用自定义的FindChild方法遍历当前节点以下的所有子节点,并存入list
  8. foreach (var item in list)
  9. {
  10. if(!uiItem.ContainsKey(item.name))
  11. uiItem.Add(item.name, item.gameObject);//把这个节点放进字典
  12. //判断如果是按钮组件,就添加EventTrigger
  13. if(item.CompareTag("UIEvent"))
  14. {
  15. var trigger=item.gameObject.AddComponent<EventTrigger>();
  16. if (trigger.triggers.Count== 0)
  17. trigger.triggers=new List<EventTrigger.Entry>();
  18. }
  19. }
  20. canvasGroup = gameObject.GetComponent<CanvasGroup>();
  21. //获取UI根节点的CanvasGroup,以便于控制实现面板慢慢显现的特效
  22. action?.Invoke(); //如果有回调的话回调
  23. }

  其中,遍历子节点的方法可以归纳称为一个小工具:

  1. //一个查找子物体的工具,从当前节点开始找
  2. private void FindChild(Transform father,List<Transform> list)
  3. {
  4. if(father.childCount> 0)
  5. {
  6. for(int i=0;i<father.childCount;i++)
  7. {
  8. list.Add(father.GetChild(i));
  9. FindChild(father.GetChild(i),list);
  10. }
  11. }
  12. return;
  13. }

  (2)显示面板——如果不使用DoTween,而是直接显示出来

  1. //显示面板
  2. public virtual void Show(UnityAction action=null)
  3. {
  4. gameObject.SetActive(true); //节点激活
  5. action?.Invoke();
  6. }

    如果使用DoTween做一个渐显的小动画,那么Show工具写成下面:

  1. //显示面板
  2. public virtual void Show(UnityAction action=null)
  3. {
  4. gameObject.SetActive(true); //节点激活
  5. switch(showType) //显示的方式ShowType定义为一个枚举数据
  6. {
  7. case ShowType.Normal:
  8. action?.Invoke();
  9. break;
  10. case ShowType.Fade:
  11. {
  12. if (canvasGroup == null)
  13. { canvasGroup = gameObject.AddComponent<CanvasGroup>(); }
  14. canvasGroup.interactable = false; //还没显示完全时不允许交互
  15. canvasGroup.DOFade(0f, 0f); //DoTween插件,控制Alfa值,透明度变成0,1s时间
  16. canvasGroup.DOFade(1f, 1.5f).SetEase(Ease.OutExpo).OnComplete(()=>
  17. {
  18. action?.Invoke();
  19. canvasGroup.interactable = true; // 可以交互
  20. }); //1.5s内按照OutExpo动画曲线显现,完成后回调
  21. }
  22. break;
  23. }
  24. }

 其中显示方式ShowType,归纳成一个枚举数:

  1. public enum ShowType
  2. {
  3. Normal, Fade, Mask //直接显示,渐显效果,遮罩
  4. }

  (3)隐藏面板——结构与显示面板相似,为了节省篇幅,这里就不使用DoTween了,如果需要使用DoTween,可以把上面的显示面板代码复制修改一下

  1. //隐藏
  2. public virtual void Hide(UnityAction action=null)
  3. {
  4. action?.Invoke();
  5. gameObject.SetActive(false);
  6. }

  (4)获取组件——UI组件类型繁多,所以使用泛型方法来获取组件

  1. protected T GetComponent<T>(string name) where T : MonoBehaviour
  2. {
  3. if (!uiItem.ContainsKey(name)) return null; //如果没有这个组件就返回空
  4. return uiItem[name].GetComponent<T>();
  5. }

  (5)给控件添加EventTrigger组件、注册事件——在上面已经说明过方法了

  1. public void AddEventTrigger(string controlName,EventTriggerType type,
  2. UnityAction<BaseEventData> callBack)
  3. {
  4. //从字典中获取控件,并添加EventTrigger组件
  5. if(!uiItem.ContainsKey(controlName)) return;
  6. if (uiItem[controlName].gameObject.GetComponent<EventTrigger>()==null)
  7. uiItem[controlName].AddComponent<EventTrigger>();
  8. //添加Entry、监听、回调
  9. EventTrigger.Entry entry = new EventTrigger.Entry();
  10. entry.callback = new EventTrigger.TriggerEvent();
  11. entry.callback.AddListener(callBack);
  12. entry.eventID = type;
  13. uiItem[controlName].GetComponent<EventTrigger>().triggers.Add(entry);
  14. }

  以上这是总的UI面板管理工具,具体到每个UI面板,如主面板Canvas_Main、退出面板Canv_EXIT,有些游戏项目中还有背包面板、排行榜面板等等,是需要根据不同情况重写上面这些工具。下面就以主面板为例,写一下主面板管理的脚本MainUi.cs

建立分面板的管理工具——以主面板MainUi为例

  对于一个分面板来说,需要做的工作有:重写初始化工具、显示工具等;在关键节点上添加组件、事件和回调;获取重要节点的组件,比如图片、文字等组件,以备后续控制等等。

  1. public class MainUI : UITools
  2. {//针对MainUI节点的工具,之后会使用UIManager动态挂在主面板上,提前挂好也可以
  3. public override void Init(UnityAction action = null) //重写UITools的Init()
  4. {
  5. base.Init(action);
  6. //给Button_Play按钮添加一个PointerClick事件和回调
  7. AddEventTrigger("Button_Play", EventTriggerType.PointerClick, OnEventStart);
  8. //给Button_Extras按钮添加一个PointerClick事件和回调
  9. AddEventTrigger("Button_Extras", EventTriggerType.PointerClick, OnEventEnd);
  10. //给Button_Exit按钮添加一个PointerClick事件和回调
  11. AddEventTrigger("Button_Exit", EventTriggerType.PointerClick, OnEventExit);
  12. }
  13. private void OnEventStart(BaseEventData data)
  14. {
  15. UIManager.Instance.ShowPanel<ExtraUi>("ExtraPanel", "EXTRAS", null, UIManager.PanelType.Extra); //点Button_Play按钮显示EXTRAS面板
  16. }
  17. private void OnEventEnd(BaseEventData data)
  18. {
  19. UIManager.Instance.HidePanel("ExtraPanel"); //点Button_Extras按钮隐藏EXTRAS面板
  20. }
  21. private void OnEventExit(BaseEventData data)
  22. {
  23. UIManager.Instance.ShowPanel<ExitUi>("ExitPanel", "EXIT", null, UIManager.PanelType.UP); //点Button_Exit按钮弹出询问是否退出面板
  24. }
  25. }

  以上就是主面板MainUi需要用到的工具,其他面板的工具类也可以参照它来写。其中,在2个回调方法中,用到了UIManager,它将总体管理整个UI节点的初始化、布局等,可以参照下一篇的UIManager的定义。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号