UGUI进阶

事件监听接口

之前基础里学的控件都只提供了常用的事件监听列表
如果想做一些类似长按,双击,拖拽等功能无法实现
或者想让三大基础控件(Image、Text、RawImage)能够响应玩家输入也无法实现

事件监听接口可以处理类似问题
让所有空间都能够添加更多的事件监听来处理对应的逻辑

事件接口
 

常用的:

不常用的:

使用事件接口

引用命名空间using UnityEngine.EventSystems;

继承需要的接口并实现

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

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

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

总结

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

EventTrigger事件触发器

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

使用方法

直接拖曳脚本进行关联(需要是public函数)
下图是关联了Panel对象上的Lesson19脚本上的TestPointEnter函数

代码添加

    public EventTrigger eg;
    void Start()
    {
        //申明一个监听事件对象
        EventTrigger.Entry entry = new EventTrigger.Entry();
        //申明事件类型,在这个类中的表现是枚举
        entry.eventID = EventTriggerType.PointerUp;
        //添加具体函数
        entry.callback.AddListener((data) =>
        {
            print("抬起");
        });
        //将事件对象添加进EventTrigger中
        eg.triggers.Add(entry);
    }

总结

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

屏幕坐标转UI相对坐标

RectTransformUtility类

用于坐标转换等操作,最重要的是将屏幕空间上的点转换成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.position = nowPos;
        //同样也能通过this.transform.position += new Vector3(eventData.delta.x,eventData.delta.y,0);来实现,但是上面第一种方法表现形式更好
    }
}

Mask遮罩

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

在父对象上添加Mask组件即可遮罩其子对象

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

模型和粒子显示在UI之前

模型

摄像机直接渲染

见这篇文章

https://blog.csdn.net/qq_62622514/article/details/137178941

将3D物体渲染在图片上通过图片显示

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

这种方法不管Canvas的渲染模式是哪一种都可以使用

创建camera,model层级为要显示的3D物体层级

创建要显示的3D物体,并改成model层

创建一个Render Texture,将其托入camera的target texture中,再将该render texture通过RawImage渲染在UI上

这种方法建议在场景上只有一个3D物体需要渲染时使用

粒子

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

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

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

异形按钮

非传统矩形的按钮

正常情况下只改变Button的图片,方框内透明区域仍然有效

希望只在图片显示范围内有效有两种方法

方法一

消耗内存不大

添加子对象
按钮的范围判断自下而上,如果按钮有含有元素的子对象(image、text等),子对象也可视为可点击范围(如果imageUI删除了image组件则不会相应)

故而我们可以通过多个子对象来拼出不规则图形

可以通过将按钮设置为不规则图像的子对象,再在按钮底下创建子对象填满不规则图片即可(按钮要设置成透明,并且Target Graphic为父对象Image,这样才能让父对象显示点击效果)

方法二

消耗内存大

第一步:修改图片参数 开启Read/Write Enabled开关

第二步:通过代码修改图片的响应阈值

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

勾选Read/Write

    public Image img;
    // Start is called before the first frame update
    void Start()
    {
        img.alphaHitTestMinimumThreshold = 0.1f;
    }

自动布局组件

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

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

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

布局元素的布局属性

水平垂直布局组件

原本四个子对象重合,在父对象上添加水平布局组件后变为下图

Control Child Size若勾选则可以控制子对象宽高

Use Child Scale:勾选后会根据缩放后的结果重新布局位置。

Child Force Expand:没勾选就会紧靠着布局,勾选后会均匀布局(例子中就是将父对象均分成四块,子对象在各自块中布局)

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

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

将四个子对象设置成如下

则若将父对象缩足够小后子对象大小仍然不变,即使勾选了Control Child Size

若设置了Preferred width/height后,则子对象会在父对象给的空间中尽可能靠近设置的值,但不会超出父对象范围

若没有勾选Child Force Expand子对象达到了该值之后也不会再随着父对象变大而变大
若勾选了则会无限放大,相当于没有设置

相应有垂直布局组件

网格布局组件

内容大小适配器

写背包UI时可以在content上添加该组件并选择preferred来自动改变content的大小,再直接加上网格布局组件就能实现添加后自动布局扩充了

宽高比适配器

Aspect Ratio Fitter

Canvas Group画布组

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

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

解决方案:Canvas Group

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

参数相关:
Alpha:整体透明度控制
Interactable:整体启用禁用设置
Blocks Raycasts:整体射线检测设置
Ignore Parent Groups:是否忽略父级CanvasGroup的作用

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值