UGUI 进阶

news2024/11/25 4:36:38

UI事件监听接口

目前所有的控件都只提供了常用的事件监听列表
如果想做一些类似长按,双击,拖拽等功能是无法制作的
或者想让Image和Text,RawImage三大基础控件能够响应玩家输入也是无法制作的

而事件接口就是用来处理类似问题
让所有控件都能够添加更多的事件监听来处理对应的逻辑

事件接口

常用的:

IPointerEnterHandler-OnPeterEnter  当指针进入对象时调用(鼠标进入)

IPointerExitHandler-OnPointerExit当指针退出对象时调用(鼠标离开)

IPointerDownHandler-OnPointerDown-在对象上按下指针时调用(按下)

IPointerUpHandler - OnPointerup - 松开指针时调用(在指针正在点击的游戏对象上调用)(抬起)

IPointerClickHandler -OnPointerclick-在同一对象上按下再松开指针时调用 (点击)


IBeginDragHandler-OnBeginDrag-即将开始拖动时在拖动对象上调用(开始拖拽)

IDragHandler-OnDrag-发生拖动时在拖动对象上调用(拖中)

IEndDragHandler-OnEndDrag-拖动完成时在拖动对象上调用(结束拖)

不常用:

InitializePotentialDragHandler - OnInitializePotentialDrag - 在找到拖动目标时调用,可用于初始化值

IDropHandler-OnDrop-在拖动目标对象上调用

IScrollHandler-OnScroll-当鼠标滚轮滚动时调用

IUpdateSelectedHandler -OnUpdateSelected-每次勾选时在选定对象上调用

ISelectHandler-Onselect-当对象成为选定对象时调用

IDeselectHandler-OnDeselect-取消选择选定对象时调用


导航相关
IMoveHandler-OnMove-发生移动事件(上、下、左、右等)时调用

ISubmitHandler-OnSubmit-按下 Submit 按钮时调用、

ICancelHandler-OnCancel-按下 Cancel 按钮时调用

使用

需要命名空间using UnityEngine.EventSystems;

继承需要的接口并实现

注意需要勾选挂载对象的 Raycast Target

using UnityEngine;
using UnityEngine.EventSystems;

//要继承,继承就得实现
public class Lesson18 : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler,IPointerUpHandler,IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        print("鼠标点击");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        print("鼠标按下");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        //移动设备上不存在,因为只有点击、按下、抬起,没有进入的概念
        print("鼠标进入");
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        //移动设备上不存在,因为只有点击、按下、抬起,没有离开的概念
        print("鼠标离开");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        print("鼠标抬起");
    }
}

PointerEventData参数的关键内容

父类:  BaseEventData

pointerId: 鼠标左右中键点击鼠标的ID 通过它可以判断石键点击
position:当前指针位置(屏幕坐标系)
pressPosition:按下的时候指针的位置
delta:指针移动增量
clickCount:连击次数
clickTime:点击时间

pressEventCamera:最后一个OnPointerPress按下事件关联的摄像机

enterEvetnCamera:最后一个OnPointerEnter进入事件关联的摄像机

    public void OnDrag(PointerEventData eventData)
    {
       print(eventData.position);
       print(eventData.delta);
    }

总结

好处:
需要监听自定义事件的控件挂载继承实现了接口的脚本就可以监听到一些特殊事件

可以通过它实现一些长按,双击拖拽等功能
坏处:
不方便管理,需要自己写脚本继承接口挂载到对应控件上,比较麻烦

EventTrigger事件触发器

事件触发器是EventTrigger组件
它是一个集成了上节所有事件接口的脚本
它可以让我们更方便的为控件添加事件监听

使用

1.拖曳脚本进行关联
2.代码添加

要求参数是BaseEventData类型(是PointerEventData这些的父类,需要using UnityEngine.EventSystems).

拖曳

   public void TestPointerEnter(BaseEventData baseEventData)
    {
        print("enter");
    }
    public void TestPointerEnter(BaseEventData data)
    {
        PointerEventData eventData = data as PointerEventData;
        print("enter " + eventData.position);
    }

代码添加

   //将控件的EventTrigger拖到这
    public EventTrigger et;
    // Start is called before the first frame update
    void Start()
    {
        //代码添加
        //声明一个希望监听的事件对象
        EventTrigger.Entry entry = new EventTrigger.Entry();
        //声明 事件的类型
        entry.eventID = EventTriggerType.PointerUp;
        //监听函数关联
        entry.callback.AddListener((data) =>
        {
            print("抬起");
        });
        //声明好的事件加入到EventTrigger中
        et.triggers.Add(entry);
    }

运行结果如图

面板上没有添加,但实际有,控制面板上显示

加入多个同种类型的eventID也不会报错,不想这样可以遍历et.triggers的对象,看有没有相同ID。

总结

EventTrigger可以让我们写更少的代码
可以在面板类中处理面板控件的事件逻辑,更加的面向对象,便于管理

屏幕坐标转UI相对坐标

RectTransformUtility类

RectTransformUtility公共类是RectTransform的]辅助类
主要用于进行一些 坐标的转换等等操作
其中对于我们目前来说 最重要的函数是 将屏幕空间上的点,转换成UI本地坐标下的点

将屏幕坐标转换UI本地坐标

方法:
RectTransformUtility.ScreenPointToLocalPointInRectangle
参数一:相对父对象
参数二:屏幕点
参数三:摄像机
参数四:最终得到的点
一般配合拖拽事件使用

public class Lesson20 : MonoBehaviour,IDragHandler
{
    public void OnDrag(PointerEventData eventData)
    {
        //参数一:相对父对象
        //参数二:屏幕点
        //参数三:摄像机
        //参数四:最终得到的点
        //该例子是遥感,类似王者荣耀的控制
         Vector2 nowPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            //相对父对象的位置
            this.transform.parent as RectTransform,
            eventData.position,
            eventData.enterEventCamera,
            out nowPos
            );
        this.transform.localPosition = nowPos;
    }

}

Mask遮罩

在不改变图片的情况下让图片在游戏中只显示其中的一部分

Scroll View的Viewport中就包含遮罩Mask组件

使用

实现遮罩效果的关键组件时Mask组件
通过在父对象上添加Mask组件即可遮罩其子对象

注意:
1.想要被遮罩的Image需要勾选Maskable
2.只要父对象添加了Mask组件,那么所有的UI子对象(包括子对象的子对象)都会被遮罩
3.遮罩父对象图片的制作,不透明的地方显示,透明的地方被遮罩

如图创建一个父对象为红色,加上Mask脚本

再创建一个子对象,如图所示

可以发现子对象好像也是圆形的,

实际子对象是方形。

参考注意第三条,父对象透明的地方被遮罩了,子对象显示不了。

要想子对象被父对象遮罩,要勾选Maskable

对于安装了Mask脚本的父对象,取消勾选Show Mask Graphic,则看不到父对象(但仍有遮罩效果)

模型和粒子显示在UI之前

模型显示在UI之前

方法一: 直接用摄像机渲染3D物体

canvas的渲染模式要不是覆盖模式
摄像机模式 和 世界(3D)模式都可以让模型显示在UI之前(z轴在UI元素之前即可)

注意:
1.摄像机模式时建议用专门的摄像机渲染UI相关
2.面板上的3D物体建议也用UI摄像机进行渲染

新建摄像机如图,并将Canvas的摄像机改为该摄像机

导入3D模型到UI前要记得把层级改为UI层,以及记得改成合适的缩放大小

如上图方块在图片前面,我们可以改变各物体z轴,来实现前后显示的效果,如下图

方法二 将3D物体渲染在图片上,通过图片显示

该方法适用于一个模型的显示(因为渲染物体需要额外的摄像机)

专门使用一个摄像机渲染3D模型,将其渲染内容输出到RenderTexture上
类似小地图的制作方式
再将渲染的图显示在UI上

该方式 不管canvas的渲染模式是哪种都可以使用

新建camera如图(Model是自己新建的层级)

新建一个方块,设置为Model层,适当调整方块位置让camera能看到

然后新建Render Texture

更改camera的Target Texture,让画面输出到图Mode上面

接着可以在Canvas中新建Raw Image(因为Mode不是Spirit,而Raw Image可以放任何图片)

则Raw Image显示的内容就是我们新建camera看到的画面

改变方块,则Raw Image画面也会改变

如图是方块移动造成的画面,但Raw Image出现了画面残影一样的拖曳效果,这需要更改摄像机

更改为 Solid Color的渲染模式就好了

粒子特效显示在UI之前

粒子特效的显示和3D物体类似

注意点:
在摄像机模式下时
可以在粒子组件的Renderer相关参数中改变排序层 让粒子特效始终显示在其之前不受z轴影响

一般方式如3D物体,这里讲修改层级

如图修改Order in Layer 如1,Canvas中也有Order in Layer,则只要粒子的Layer值大于Canvas,就会一直显示在UI前面。

异形按钮

图片形状不是传统矩形的按钮是异形按钮

如图将按钮改为了非传统矩形

发现点击Button周围透明区域仍然有效果(即点击范围仍为矩形)

但只希望点击图片显示范围

方法一 通过添加子对象的形式

内存消耗不大

按钮之所以能够响应点击,主要是根据图片矩形范围进行判断的
它的范围判断是自下而上的,意思是如果有子对象图片,子对象图片的范围也会算为可点击范围
那么我们就可以用多个透明图拼凑不规则图形作为按钮子对象用于进行射线检测

如图创建了一个透明矩形图片,作为Button的子对象,则发现点击子对象的区域也会判定为点击按钮。

但如果创建一个删除Image组件,只有Rect Transform的Image,

则发现点击这范围没效果

也就是说,必须要有元素(如图,文字等)才可以响应点击。

我们可以利用这个性质来实现异形按钮的点击

可以将按钮作为Image的子对象,异形按钮可以把Button的文字删掉,并更改透明度让Button看不到,但记得更改如下图的Target Graphic为Image,这样才能显示父对象被点击的效果。

因此可以用Button的子对象拼出异形按钮的点击范围。

方法二 通过代码改变图片的透明度响应阈值

消耗内存

第一步:修改图片参数 开启Read/Write Enabled开关
第二步:通过代码修改图片的响应阈值

该参数含义:指定一个像素必须具有的最小alpha值,以便能够认为射线命中了图片
说人话:当像素点alpha值小于了 该值 就不会被射线检测了

如图开启Read/Write


    public Image img;
    // Start is called before the first frame update 
    void Start()
    {
        //alpha 0.1f以下不响应
        img.alphaHitTestMinimumThreshold = 0.1f;
    }

给按钮挂载该脚本后,则边缘透明部分点击不响应。

自动布局组件

虽然UGUI的RectTransform已经非常方便的可以帮助我们快速布局
但UGUI中还提供了很多可以帮助我们对UI控件进行自动布局的组件
他们可以帮助我们自动的设置UI控件的位置和大小等

自动布局的工作方式一般是
自动布局控制组件 + 布局元素 = 自动布局


自动布局控制组件:Unity提供了很多用于自动布局的管理性质的组件用于布局
布局元素:具备布局属性的对象们,这里主要是指具备RectTransform的UI组件

布局元素的布局属性

如图为Image的布局属性 Layout Properties

水平垂直布局组件

水平垂直布局组件
将子对象并排或者竖直的放在一起

组件名:Horizontal Layout Group和Vertical Layout Group
参数相关:
Padding:左右上下边缘偏移位置
Spacing:子对象之间的间距

ChildAlignment:九宫格对齐方式
Control Child Size:是否控制子对象的宽高
Use Child Scale:在设置子对象大小和布局时,是否考虑子对象的缩放
Child Force Expand:是否强制子对象拓展以填充额外可用空间

如图创建一个蓝色父对象和绿,红,黑3个子对象,子对象现在重叠。

给父对象添加改组件

则显示如图

父对象大小变化时,它们位置也会变化,大小好像不变(唐老狮说变,但是我测试没有变化)

这里就是参数

勾选Control Child Size时 父对象大小变化,子对象也变化

Use Child Scale:在设置子对象大小和布局时,是否考虑子对象的缩放,勾选后会根据缩放后的结果重新布局位置。

Child Force Expand:是否强制子对象拓展以填充额外可用空间,没勾选就会紧靠着布局,勾选后会均匀布局

当勾选Control Child Size 而不勾选 Child Force Expand时,子对象会消失,因为默认的布局属性最小为0,0.

想要改变最小宽高,可以添加Layout Element组件

我将红色改为

则哪怕勾选了Control Child Size和Child Force Expand,改变父对象的大小,红色子对象最小也被限定在了50,50

而如果设置了Preferred 宽高(我认为是倾向宽高,当能往这值靠近时,他就会扩大靠近这个值),勾选Control Child Size而不勾选Child Force Expand,则最大为设置的值,但如果勾选了Child Force Expand,仍会扩大

相应的有垂直布局组件

网格布局组件

Grid Layout Group

内容大小适配器

Content Size Fitter

宽高比适配器

Aspect Ratio Fitter

Canvas Group

如何整体控制一个面板的淡入淡出等

如果我们想要整体控制一个面板的淡入淡出 或者 整体禁用
使用目前学习的知识点 是无法方便快捷的设置的

解决方案:Canvas Group

为面板父对象添加
CanvasGroup组件 即可整体控制

参数相关:
Alpha:整体透明度控制
Interactable:整体启用禁用设置
Blocks Raycasts:整体射线检测设置


Ignore Parent Groups:是否忽略父级CanvasGroup的作用

总结

UGUI源码位置

Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui

其它知识

1.DoTween-缓动插件,可以制作一些缓动效果
2.TextMeshPro一文本网格插件,可以制作更多的特效文字
 

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

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

相关文章

RT-Thread(RTT)如何添加静态库.a文件

一、在libraries目录下新建文件夹 二、名字根据要添加的静态库文件而定,我这里叫做AGMAlgo,这是一个算法库 三、在文件里再新建两个文件夹,一个叫做inc用来存放静态库的头文件,另一个叫做libs用来存放静态库的.a文件 四、就像这样…

因子数据预处理-去极值和标准化

一. 去极值 因子数据中过大或过小的值会影响分析结果,特别是在回归时,离群值会严重影响因子和收益率之间的相关性估计结果。 因子去极值的处理方法: 确定上下限将上下限外的数据修改为上下限值 常见的去极值方法有三种,分别是…

QT使用数据库

数据库就是保存数据的文件。可以存储大量数据,包括插入数据、更新数据、截取数据等。用专业术语来说,数据库是“按照数据结构来组织、存储和管理数据的仓库”。 什么时候需要数据库?在嵌入式里,存储大量数据,或者记录数…

【已解决】Out of memory interning an attribute name

问题描述:pycharm运行程序时报错 Out of memory interning an attribute name 原因分析:pycharm预设内存不足 解决办法:打开pycharm文件所在位置,打开pycharm64.exe.vmoptions配置文件,调整Xmx的大小。

关系(二)利用python绘制热图

关系(二)利用python绘制热图 热图 (Heatmap)简介 热图适用于显示多个变量之间的差异,通过颜色判断彼此之间是否存在相关性。 快速绘制 基于seaborn import seaborn as sns import pandas as pd import numpy as np i…

【JavaSE】解密 继承和多态(下)

前言 紧接着上篇 解密继承和多态(上)~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 protected关键字 在同一包下同一类可以访问 代码理解 在同一包下不同类可以访问 代码理解 …

【性能测试】接口测试各知识第1篇:接口测试,学习目标【附代码文档】

接口测试完整教程(附代码资料)主要内容讲述:接口测试,学习目标学习目标,2. 接口测试课程大纲,3. 接口学完样品,4. 学完课程,学到什么,5. 参考:,1. 理解接口的概念。学习目标,RESTFUL1. 理解接口的概念,2.什么是接口测试…

ZYNQ学习之Ubuntu下Linux文件系统、用户权限与磁盘管理

基本都是摘抄正点原子的文章&#xff1a;<领航者 ZYNQ 之嵌入式Linux 开发指南 V3.2.pdf&#xff0c;因初次学习&#xff0c;仅作学习摘录之用&#xff0c;有不懂之处后续会继续更新~ 一、Linux 文件系统 1.1 Linux 文件系统简介以及类型 操作系统的基本功能之一就是文件管…

JS详解-fetch核心语法

document.querySelector(.btn).addEventListener(click,async () > {const p new URLSearchParams({pname:浙江省,cname:杭州市})//1、如何请求&#xff1f;默认为get&#xff0c;参数1 url地址&#xff0c;返回promiseconst res await fetch(http://hmajax.itheima.net/…

AI提速 OpenAI 新模型GPT-5今年上线?

这两天&#xff0c;有关OpenAI新模型 GPT-5的消息又多了起来。有知情人士称&#xff0c;OpenAI将在今年年中的某个时候发布GPT-5&#xff0c;很可能是在今年夏天期间。OpenAI CEO 萨姆奥特曼在一次播客采访中透露“GPT-5的智能水平得到提升”。 有趣的是&#xff0c;播客的主理…

JavaScript库,编写$()和getElementsByClassName()方法

背景: JavaScript库是一组预先编写好的JavaScript代码集合&#xff0c;旨在简化常见的网页开发任务。这些库通常包含了许多函数和方法&#xff0c;可以帮助开发人员处理各种任务&#xff0c;比如DOM操作、事件处理、动画效果、AJAX请求等等。使用JavaScript库可以节省开发时间…

如何借助AI工具轻松绘制思维导图

前言 思维导图是一种将思维可视化的工具&#xff0c;它可以帮助我们理清思路、提高效率、促进记忆。传统的思维导图绘制方法需要一定的时间和技巧&#xff0c;而借助AI工具&#xff0c;我们可以轻松绘制思维导图&#xff0c;并将更多时间和精力集中在内容本身。 借助AI工具把…

网络以太网之(2)VLAN协议

网络以太网之(1)VLAN协议 Author: Once Day Date: 2024年4月1日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day…

输出100~200之间的素数(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现素数判断函数&#xff1b; int Prime(int number) {//初始化变量值&#xff1b;int divided 2;int JudgementCondition 0;//循环判断素数&#xff1b;wh…

基于SpringBoot+微信小程序的外卖跑腿点餐(订餐)系统设计与实现+毕业论文(12000字)

介绍 Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff0c;Spring Boot致力于在蓬勃发展的快速应…

美联储,非必要,不降息

美联储“没必要、没空间、没动力”降息&#xff0c;也会尽量避免货币政策干扰大选&#xff0c;用“口头降息”代替实际调整是现实选择&#xff0c;市场降息预期将继续推迟和下调。 前言&#xff1a; 当前美国经济从各个方面看均并未表现出疲态——新增就业持续修复&#xff0c;…

俄罗斯Yandex广告推广如何开户及费用?

作为俄罗斯首屈一指的搜索引擎&#xff0c;Yandex凭借其超过60%的市场份额&#xff0c;成为企业进入俄罗斯、触及俄语消费者的关键入口。然而&#xff0c;对于不熟悉当地市场环境与网络营销规则的企业而言&#xff0c;成功开户并高效运营Yandex广告并非易事。云衔科技凭借专业的…

大模型量化技术-AWQ

大模型量化技术-AWQ 在2023年6月,Ji Lin等人发表了论文AWQ:Activation-aware Weight Quantization for LLM Compression and Acceleration。 这篇论文详细介绍了一种激活感知权重量化算法,可以用于压缩任何基于 Transformer 的语言模型,同时只有微小的性能下降。关于 AWQ 算…

2024 年云繁荣:驾驭人工智能驱动转型浪潮

在人工智能革命的核心&#xff0c;2024 年见证了云计算应用的空前激增。云计算的繁荣不仅仅是异地存储数据&#xff0c;而是创建动态的智能基础设施&#xff0c;推动人工智能的指数级增长。让我们深入探讨推动这一现象的关键因素和趋势。 01 人工智能和云&#xff1a;共生关系…

Mac上怎么合并多张图片?

Mac上怎么合并多张图片&#xff1f;上班过的小伙伴都应该知道&#xff0c;合并拼接图片是一件非常重要且经常需要使用到的图片处理技术&#xff0c;将多张图片合并拼成一张之后能够展现出更多的图片内容。在Mac电脑上&#xff0c;合并多张图片是一项常见的任务&#xff0c;无论…