UI事件监听接口

目前所有的控件都只提供了常用的事件监听列表

如果想做一些类似长按,双击,拖拽等功能是无法制作的

或者想让 Image 和 Text,RawImage 三大基础控件能够响应玩家输入也是无法制作的

而事件接口就是用来处理类似问题

让所有控件都能够添加更多的事件监听来处理对应的逻辑

常用事件接口

//IPointerEnterHandler - OnPointerEnter - 当指针进入对象时调用(鼠标进入)
//IPointerExitHandler - OnPointerExit - 当指针退出对象时调用(鼠标离开)
//IPointerDownHandler - OnPointerDown - 在对象上按下指针时调用(按下)
//IPointerUpHandler - OnPointerUp - 松开指针时调用(在指针正在点击的游戏对象上调用)(抬起)
//IPointerClickHandler - OnPointerClick - 在同一对象上按下再松开指针时调用(点击)
//IBeginDragHandler - OnBeginDrag - 即将开始拖动时在拖动对象上调用(开始拖拽)
//IDragHandler - OnDrag - 发生拖动时在拖动对象上调用(拖拽中)
//IEndDragHandler - OnEndDrag - 拖动完成时在拖动对象上调用(结束拖拽)

不常用的接口

//IInitializePotentialDragHandler - OnInitializePotentialDrag - 在找到拖动目标时调用,可用于初始化值
//IDropHandler - OnDrop - 在拖动目标对象上调用
//IScrollHandler - OnScroll - 当鼠标滚轮滚动时调用
//IUpdateSelectedHandler - OnUpdateSelected - 每次勾选时在选定对象上调用

//ISelectHandler - OnSelect - 当对象成为选定对象时调用
//IDeselectHandler - OnDeselect - 取消选择选定对象时调用

// 导航相关
//IMoveHandler - OnMove - 发生移动事件(上、下、左、右等)时调用
//ISubmitHandler - OnSubmit - 按下 Submit 按钮时调用
//ICancelHandler - OnCancel - 按下 Cancel 按钮时调用

UI事件监听接口的使用

public class lesson3 : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
    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 eventData参数

父类: BaseEventData

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

pressEventCamera: 最后一个 OnPointerPress 按下事件关联的摄像机
enterEvtCamera: 最后一个 OnPointerEnter 进入事件关联的摄像机
*/

好处: 需要监听自定义事件的控件挂载继承实现了接口的脚本就可以监听到一些特殊事件 可以通过它实现一些长按,双击拖拽等功能

坏处: 不方便管理,需要自己写脚本继承接口挂载到对应控件上,比较麻烦

Eventtrigger事件触发器

事件触发器是 EventTrigger 组件

它是一个集成了UI事件监听接口的所有事件接口的脚本

它可以让我们更方便的为控件添加事件监听

我们可以给对象添加组件Event Trigger

点击Add New Event Type,选择我们需要执行的事件,这里的选项就是UI事件监听里的接口

首先我们先给脚本添加如下方法

    public void TestValueChange(BaseEventData data)
    {
        print("鼠标进入");
    }

并把脚本拖拽给UI对象

点击Event Trigger下的加号

将UI对象拖拽至RunTime On,并在No Function中选择刚刚添加的方法

效果:

如何通过代码添加

    void Start()
    {
        EventTrigger et = GetComponent<EventTrigger>();
        //申明一个希望监听的事件对象
        EventTrigger.Entry entry = new EventTrigger.Entry();
        //声明事件的类型
        entry.eventID = EventTriggerType.PointerDown;
        //监听函数关联
        entry.callback.AddListener((b) => {
            print("鼠标按下");

        });
        et.triggers.Add(entry);

        foreach (EventTrigger.Entry item in et.triggers)
        {
            if (item.eventID == EventTriggerType.PointerDown)
            {
                item.callback.AddListener((e) => {
                    print("鼠标按下2");
                });
            }
        }
    }

效果:

屏幕坐标转UI相对坐标

RectTransformUtility 公共类是一个 RectTransform 的辅助类

主要用于进行一些 坐标的转换等等操作

其中对于我们目前来说 最重要的函数是 将屏幕空间上的点,转换 UI 本地坐标下的点

    public void OnDrop(PointerEventData eventData)
    {
            //方法:
            //RectTransformUtility.ScreenPointToLocalPointInRectangle
            //参数一:相对父对象
            //参数二:屏幕点
            //参数三:摄像机
            //参数四:最终得到的点
            //一般配合拖拽事件使用
       
        Vector2 nowPos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            this.transform.parent as RectTransform,
            eventData.position,
            eventData.enterEventCamera,
            out nowPos
            );
        this.transform.localPosition = nowPos;
    }

Mask遮罩

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

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

注意:

  1. 想要被遮罩的 Image 需要勾选 Maskable

  2. 只要父对象添加了 Mask 组件,那么所有的 UI 子对象都会被遮罩

  3. 遮罩父对象图片的制作,不透明的地方显示,透明的地方被遮罩

模型和粒子显示在UI之前

方法一:直接用摄像机渲染 3D 物体 Canvas 的渲染模式要不是覆盖模式 摄像机模式 和 世界 (3D) 模式都可以让模型显示在 UI 之前(Z 轴在 UI 元素之前即可)

注意:

  1. 摄像机模式时建议用专门的摄像机渲染 UI 相关

  2. 面板上的 3D 物体建议也用 UI 摄像机进行渲染

Camera之渲染UI层,主相机取消渲染UI层

可以看到,两台相机的渲染效果均显示,并且Cube在UI之前,Sphere在UI之后

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

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

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

新建一个层级,相机只负责渲染这个mod层

创建RenderTexture,将相机渲染的结果映射在它的上面

创建RawImage将,Texture放在上面显示

粒子特效显示在 UI 之前

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

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

同上

我们可以改变粒子组件中的层级,使他大于UI的层级,让他可以一直显示在UI之前

异形按钮

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

如何让异形按钮能够准确点击

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

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

通过透明的image拼接出可以点击的范围,将button的点击效果反馈对象设置为父对象Image

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

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

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

   Image img = GetComponent<Image>();
        img.alphaHitTestMinimumThreshold = 0.1f;

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

自动布局组件

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

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

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

布局元素的布局属性

要参与自动布局的布局元素必须包含布局属性

布局属性主要有以下几条

Minmum width:该布局元素应具有的最小宽度

Minmum height:该布局元素应具有的最小高度

Preferred width:在分配额外可用宽度之前,此布局元素应具有的宽度

Preferred height:在分配额外可用高度之前,此布局元素应具有的高度。

Flexible width:此布局元素应相对于其同级而填充的额外可用宽度的相对量

Flexible height:此布局元素应相对于其同级而填充的额外可用高度的相对量

在进行自动布局时 都会通过计算布局元素中的这 6 个属性得到控件的大小位置

在布局时,布局元素大小设置的基本规则是

  1. 首先分配最小大小 Minmum width 和 Minmum height

  2. 如果父类容器中有足够的可用空间,则分配 Preferred width 和 Preferred height

  3. 如果上面两条分配完成后还有额外空间,则分配 Flexible width 和 Flexible height

一般情况下布局元素的这些属性都是 0 但是特定的 UI 组件依附的对象布局属性会被改变,比如 Image 和 Text

一般情况下我们不会去手动修改他们,但是如果你有这些需求 可以手动添加一个 LayoutElement 组件 可以修改这些布局属性

水平垂直布局组件

将子对象并排或者竖直的放在一起

组件名: Horizontal Layout Group 和 Vertical Layout Group

参数相关:

Padding: 左右上下边缘偏移位置

Spacing: 子对象之间的间距

ChildAlignment: 九宫格对其方式

Control Child Size: 是否控制子对象的宽高

Use Child Scale: 在设置子对象大小和布局时,是否考虑子对象的缩放

Child Force Expand: 是否强制子对象拓展以填充额外可用空间

网格布局组件

将子对象当成一个个的格子设置他们的大小和位置

组件名: Grid Layout Group

参数相关:

Padding: 左右上下边缘偏移位置

Cell Size: 每个格子的大小

Spacing: 格子间隔

Start Corner: 第一个元素所在位置 (4 个角)

Start Axis: 沿哪个轴放置元素;Horizontal 水平放置满换行,Vertical 竖直放置满换列

Child Alignment: 格子对其方式 (9 宫格)

Constraint: 行列约束约束: 行列约束

Flexible: 灵活模式,根据容器大小自动适应

Fixed Column Count: 固定列数

Fixed Row Count: 固定行数

内容大小适配器

它可以自动的调整 RectTransform 的长宽来让组件自动设置大小

一般在 Text 上使用 或者 配合其它布局组件一起使用

组件名: Content Size Fitter

参数相关

Horizontal Fit: 如何控制宽度

Vertical Fit: 如何控制高度

Unconstrained: 不根据布局元素伸展

Min Size: 根据布局元素的最小宽高度来伸展

Preferred Size: 根据布局元素的偏好宽度来伸展宽度。

宽高比适配器

  1. 让布局元素按照一定比例来调整自己的大小

  2. 使布局元素在父对象内部根据父对象大小进行适配

组件名: Aspect Ratio Fitter

参数相关:

Aspect Mode: 适配模式,如果调整矩形大小来实施宽高比

None: 不让矩形适应宽高比

Width Controls Height: 根据宽度自动调整高度

Height Controls Width: 根据高度自动调整宽度

Fit In Parent: 自动调整宽度、高度、位置和锚点,使矩形适应父项的矩形,同时保持宽高比,会出现 “黑边”

Envelope Parent: 自动调整宽度、高度、位置和锚点,使矩形覆盖父项的整个区域,同时保持宽高比,会出现 “裁剪”

Aspect Ratio: 宽高比;宽除以高的比值

Canvas Group画布组

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

参数相关:

Alpha: 整体透明度控制

Interactable: 整体启用禁用设置

Blocks Raycasts: 整体射线检测设置 I

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

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐