推荐阅读

CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

在开发中总是会控制UI界面,如何优雅的控制UI界面是每一个Unity3D程序员的必修课。

这篇文章就总结了一下博主在实际开发中用到的几种控制UI的方式,分享出来以供批评指正。

在文章的最后,也根据UI控制做了一些延展,比如说:

控制UI顺序控制UI层级控制初始化的先后顺序显示隐藏的堆栈

二、正文

2-1、讨论UI控制的解决方案

先说一下痛点吧,隐藏UI面板很简单,xx.SetActive(false);就行,但是这个管理的脚本放在哪里是个问题。

因为这个挂载的对象一旦隐藏,那么这个脚本就失灵了,所以一般不能挂载在UI面板自己身上,因为一旦隐藏就不管用了。

但是UI统一管理耦合性太高,不适合组件开发,但是也是一种控制方法。

挂载在UI面板自己身上,就需要一些技巧,避开隐藏自身这种行为。

由此为基础,有下面几种方案的讨论。

2-1-1、用一个脚本统一管理脚本的方式

实现方式 先搭建UI,然后新建一个对象挂载控制UI的脚本,然后这个脚本里面控制所有的UI事件。

例子 效果图:

代码参考:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class UIControl : MonoBehaviour

{

public GameObject Panel1;

public Button Btn1;

public GameObject Panel2;

public Text TextTitle;

public Text TextContent;

public GameObject Panel3;

public GameObject Panel4;

void Start()

{

// 按钮绑定

Btn1.onClick.AddListener(ClickSure);

}

void ClickSure()

{

}

public void ShowPanel()

{

Panel1.SetActive(true);

}

}

用这个脚本去控制所有的对象,保存隐藏显示、文字赋值、按钮绑定事件等。

优缺点 优点: 脚本一般都在一个独立对象上,脚本容易找。控制显示隐藏不容易报NULL对象错误。

缺点: 耦合性太高,所有的UI对象都在一个脚本中,脚本代码比较拥杂,并且无法独立出来形成组件进行复用。

2-1-2、面板自身挂载脚本,通过控制所有子对象来隐藏面板

实现方式 UI自身带有控制的脚本,通过控制所有子对象来实现隐藏或显示。

例子 效果图:

优缺点

优点:组件化开发,可以形成预制体复用,不必隐藏面板。

缺点:需要获取所有子对象,并且父节点身上不能添加Image,不然隐藏所有子对象也不行。

2-1-3、面板自身挂载脚本,通过控制UI界面缩放来隐藏面板

实现方式 UI界面挂载脚本,控制UI界面的缩放为0即可隐藏脚本,算是视觉隐藏,但是实际没有隐藏。

例子 效果图:

优缺点 优点:不必获取子对象,使用缩放控制。

缺点:不确定面板是否要显示,没法控制显示顺序。

2-1-4、面板自身挂载脚本,通过控制UI子节点来隐藏面板

实现方式 算是第一种和第二种方法的一种优化和升级。

在UI界面下面再设置一个节点用来控制所有的UI对象,随意控制隐藏和显示都没有问题,也不用获取所有的子对象,非常好用。

例子 效果图:

优缺点 优点:控制子对象,不用直接控制UI界面,避免脚本禁用情况,方便管理,也可以默认隐藏,更加灵活。

缺点:搭建UI的时候需要按照一定的规则搭建。比如UI界面是根节点,下一个节点是控制UI界面隐藏和显示的节点,再下面才是真正的UI搭建。

2-2、方法改良及可行性演示

2-1小结分析的几种解决方案都有优点和缺点,再次基础上,总结了一个比较完善的改良型方案。

UI面板自身挂载脚本,下面一个子节点是所有UI的父节点,也就是:

这样的话,一个UI界面的父节点是固定的,然后子节点用同一个名字方便脚本控制。

代码参考:

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.Diagnostics;

using UnityEngine.UI;

public class Panel3Logic : MonoBehaviour

{

GameObject currentObj;

Button BtnSure;

Action endAction;

void Start()

{

currentObj = transform.Find("UIControl").gameObject;

currentObj.SetActive(false);

BtnSure = currentObj.transform.Find("BtnSure").GetComponent