【Unity3D小技巧】Unity3D中UI控制解决方案

推荐阅读

  • 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<Button>();BtnSure.onClick.AddListener(BtnSureEvent);}/// <summary>/// 显示隐藏面板/// </summary>/// <param name="ison"></param>void ShowInfo(bool ison){currentObj.SetActive(ison);}/// <summary>/// 设置委托函数/// </summary>/// <param name="ison"></param>/// <param name="endAction"></param>void ShowInfo(bool ison, Action endAction){currentObj.SetActive(ison);this.endAction = endAction;}/// <summary>/// 点击确定的时候,关闭面板,并且执行委托函数/// </summary>void BtnSureEvent(){currentObj.SetActive(false);endAction?.Invoke();}
}

2-3、延展内容

这一节就将UI控制解决方案再做一下延展,包括:

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

新建一个UI基类UIBase.cs,双击编辑代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class UIBase : MonoBehaviour
{/// <summary>/// 初始化顺序/// </summary>public int StartOrder;/// <summary>/// 层级顺序/// </summary>public int LayerOrder;/// <summary>/// 唯一标识符/// </summary>[HideInInspector]public int UniqueID;public virtual void OnStart() { }public virtual void ShowInfo(bool ison) { }
}

UI界面控制UI继承与这个基类,比如说Panel1Logic.cs,编辑代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Panel1Logic : MonoBehaviour
{GameObject currentObj;Button BtnSure;Action endAction;/// <summary>/// 初始化顺序/// </summary>public int StartOrder;/// <summary>/// 层级顺序/// </summary>public int LayerOrder;/// <summary>/// 唯一标识符/// </summary>public int UniqueID;public void OnStart(){currentObj = transform.Find("UIControl").gameObject;currentObj.SetActive(false);BtnSure = currentObj.transform.Find("BtnSure").GetComponent<Button>();BtnSure.onClick.AddListener(BtnSureEvent);}/// <summary>/// 显示隐藏面板/// </summary>/// <param name="ison"></param>public void ShowInfo(bool ison){currentObj.SetActive(ison);}/// <summary>/// 设置委托函数/// </summary>/// <param name="ison"></param>/// <param name="endAction"></param>public void ShowInfo(bool ison, Action endAction){currentObj.SetActive(ison);this.endAction = endAction;}/// <summary>/// 点击确定的时候,关闭面板,并且执行委托函数/// </summary>void BtnSureEvent(){currentObj.SetActive(false);endAction?.Invoke();}
}

UI控制脚本UIControl.cs,编辑代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class UIControl : MonoBehaviour
{public List<UIBase> UIList;// 使用栈的后进先出的特性,实现UI的后显示先隐藏的功能Stack<GameObject> uiQueue;void Start(){// 初始化UIUIInit();// 初始化参数uiQueue = new Stack<GameObject>();}void UIInit(){// 排序UIList.Sort((x, y) => x.StartOrder.CompareTo(y.StartOrder));// 设置初始化顺序for (int i = 0; i < UIList.Count; i++){Debug.Log(UIList[i].StartOrder);UIList[i].OnStart();UIList[i].UniqueID = 1000 + i;}// 排序UIList.Sort((x, y) => x.LayerOrder.CompareTo(y.LayerOrder));// 设置层级顺序for (int i = 0; i < UIList.Count; i++){Debug.Log(UIList[i].LayerOrder);UIList[i].transform.SetSiblingIndex(UIList[i].LayerOrder);}}/// <summary>/// 显示UI/// </summary>/// <param name="UniqueID"></param>public void ShowPanel(int UniqueID){UIBase uiObj = UIList.Find(value => value.UniqueID == UniqueID);if (uiObj != null){uiObj.ShowInfo(true);uiQueue.Push(uiObj.gameObject);}}/// <summary>/// 隐藏UI 适用于多个UI重叠 点击任意位置关闭UI的情况/// </summary>public void HidePanel(){GameObject ui = uiQueue.Pop();ui.GetComponent<UIBase>().ShowInfo(false);}
}

三、后记

如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


你的点赞就是对博主的支持,有问题记得留言:

博主主页有联系方式。

博主还有跟多宝藏文章等待你的发掘哦:

专栏方向简介
Unity3D开发小游戏小游戏开发教程分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶入门从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUIUGUIUnity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据文件读取使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合数据集合数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件插件主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发日常记录主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG日常记录记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/252275.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.0 Zookeeper linux 服务端集群搭建步骤

本章节将示范三台 zookeeper 服务端集群搭建步骤。 所需准备工作&#xff0c;创建三台虚拟机环境并安装好 java 开发工具包 JDK&#xff0c;可以使用 VM 或者 vagrantvirtualbox 搭建 centos/ubuntu 环境&#xff0c;本案例基于宿主机 windows10 系统同时使用 vagrantvirtualb…

centos 7.6 安装 openldap 2.5.17

centos 7.6 安装ldap 1、下载ldap2、安装ldap2.1、官方参考文档2.2、安装前准备2.2.1、安装gcc2.2.2、安装Cyrus SASL 2.1.272.2.3、安装OpenSSL 1.1.12.2.3.1、下载openssl 3.02.2.3.2、安装依赖包2.2.3.3、编译安装openssl 3.0 2.2.3、安装libevent 2.1.82.2.4、安装libargon…

小程序支付类型接入京东支付

一、情景描述 当前项目想在微信小程序付款时添加上京东支付支付类型&#xff0c;效果如下 普通的付款方式可以直接付款就能完成支付&#xff0c;但京东支付无法在小程序上直接付款&#xff0c;他需要复制生成的链接&#xff0c;然后打开京东app然后在京东平台上付款。 所以&…

网络安全大赛

网络安全大赛 网络安全大赛的类型有很多&#xff0c;比赛类型也参差不齐&#xff0c;这里以国内的CTF网络安全大赛里面著名的的XCTF和强国杯来介绍&#xff0c;国外的话用DenCon CTF和Pwn2Own来举例 CTF CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相…

【开源】JAVA+Vue+SpringBoot实现二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…

第7节、双电机直线运动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;前面章节主要介绍单个电机控制&#xff0c;本节内容介绍两个电机完成Bresenham直线运动 一、Bresenham直线算法介绍 Bresenham直线算法由Jack Elton Bresenham于1962年在IBM开发&#xff0c;最初用于计…

python创建pdf文件

目录 一&#xff1a;使用reportlab库 二&#xff1a;使用使pdf库 在Python中生成PDF文件可以使用多种库&#xff0c;其中最常用的是reportlab和fpdf。以下是使用这两个库生成PDF文件的示例代码&#xff1a; 一&#xff1a;使用reportlab库 1&#xff1a;写入文字信息 from r…

使用Pycharm在本地调用chatgpt的接口

目录 1.安装环境 2.建立多轮对话的完整代码&#xff08;根据自己使用的不同代理需要修改端口&#xff08;port&#xff09;&#xff09; 3.修改代码在自己的Pycharm上访问chagpt的api并实现多轮对话&#xff0c;如果不修改是无法成功运行的。需要确定秘钥和端口以保证正常访…

Kafka 使用手册

kafka3.0 文章目录 kafka3.01. 什么是kafka&#xff1f;2. kafka基础架构3. kafka集群搭建4. kafka命令行操作主题命令行【topic】生产者命令行【producer】消费者命令行【consumer】 5. kafka生产者生产者消息发送流程Producer 发送原理普通的异步发送带回调函数的异步发送同步…

【VUE】UniAPP之uview组件库,自定义tag封装,支持添加u-icon图标

组件代码 <template><view class"tag" :class"[props.mode, props.shape]"><slot name"left"><!-- icon图标 没有传入图标时不显示 --><u-icon v-if"props.icon ! " :name"props.icon" :color&…

基于单片机的智能燃气灶控制系统设计

摘要&#xff1a;针对传统燃气灶存在不能防干烧、不能进行温度检测、不能进行火力自动调节等问题&#xff0c;设计了一种基于单片机控制的智能燃气灶&#xff0c;它通过单片机进行控制&#xff0c;由开关模块、测温模块、语音播报模块、火力控制模块和防空烧模块五个模块组成&a…

目标检测:3采用YOLOv8 API训练自己的模型

​ 目录 ​1.YOLOv8 的新特性 2.如何使用 YOLOv8? 3使用YOLOv8训练模型 4.验证训练集 5.测试训练集 6.测验其他图片 7 其他问题 参考: 1.YOLOv8 的新特性 Ultralytics 为 YOLO 模型发布了一个全新的存储库。它被构建为 用于训练对象检测、实例分割和图像分类模型的统…

JVM工作原理与实战(三十六):GraalVM虚拟机

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、GraalVM介绍 二、GraalVM的两种运行模式 三、GraalVM应用场景 1.GraalVM存在的问题 2.GraalVM企业级应用-Serverless架构 3.Serverless架构-函数计算 4.Serverless架构-Serve…

正点原子-STM32定时器学习笔记(1)未完待续

1. 通用定时器简介&#xff08;F1为例&#xff09; F1系列通用定时器有4个&#xff0c;TIM2/TIM3/TIM4/TIM5 主要特性&#xff1a; 16位递增、递减、中心对齐计数器&#xff08;计数值&#xff1a;0~65535&#xff09;&#xff1b; 16位预分频器&#xff08;分频系数&#xff…

视频业务像素、带宽、存储空间计算

一、像素和分辨率 分辨率的单位通常是像素&#xff08;或点&#xff09;&#xff0c;用水平像素数乘以垂直像素数来表示。例如&#xff0c;一个分辨率为1920 x 1080的屏幕有1920个水平像素和1080个垂直像素。 总像素分辨率公式运算 例如 1920 x 10802073600总约200万 500W≈…

get通过发送Body传参-工具类

1、调用方式 String url "http://ip/xxx/zh/xxxxx/xxxx/userCode"; //进行url中的对应的参数 url2 url2.replace("ip",bancirili); url2 url2.replace("zh",zh); url2 url2.replace("userCode",userCode);String dateTime xxxx; //组…

【51单片机】开发板&开发软件(Keil5&STC-ISP)简介&下载安装破译传送门(1)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

Android配置GitLab CI/CD持续集成,Shell版本的gitlab-runner,FastLane执行,上传蒲公英

mac环境下&#xff0c; 首选需要安装gitlab-runner和fastlane brew install gitlab-runner brew install fastlane 安装完成&#xff0c;来到我们在gitlab下新建的Android项目&#xff0c;我们开始创建gitlab-runner 1、创建runner 点开runner&#xff0c;点击新建runner …

【C/C++】C/C++编程——整型(二)

在 C 中&#xff0c;整型数据可以分为有符号数&#xff08;Signed&#xff09;和无符号数&#xff08;Unsigned&#xff09;&#xff0c;这两种类型主要用于表示整数值&#xff0c;但它们在表示范围和用途方面有所不同。默认情况下&#xff0c;整数类型如 int、short、long 都是…

时序预测 | MATLAB实现基于CNN-GRU-AdaBoost卷积门控循环单元结合AdaBoost时间序列预测

时序预测 | MATLAB实现基于CNN-GRU-AdaBoost卷积门控循环单元结合AdaBoost时间序列预测 目录 时序预测 | MATLAB实现基于CNN-GRU-AdaBoost卷积门控循环单元结合AdaBoost时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于CNN-GRU-AdaBo…