Unity3d Ugui 24 EventSystem事件机制

2023-11-05 02:10

本文主要是介绍Unity3d Ugui 24 EventSystem事件机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一:使用

1:实现IEventSystemHandler接口

2:添加组件EventTrigger

3:使用Ugui封装好的组件

4:3D物体相应事件

二:源码分析

1:源码地址

2:关键脚本介绍

3:执行流程

三:按照特殊需求定义自己的事件

1:制作一个2D和3D物体可以同时生效的事件。

2:响应本身的事件并且可以穿透响应下面物体的事件。


​​​​​​​

一:使用

下面几种方式都可以添加一个事件,根据实际情况选择就行,如果需要点击的详细参数,可以选择带有BaseEventData参数的方式。

1:实现IEventSystemHandler接口

ugui提供了很多接口可以直接实现对应的接口来处理对应的事件

Pointer鼠标事件:

IPointerEnterHandler- OnPointerEnter - 当光标进入对象时调用
IPointerExitHandler - OnPointerExit - 当光标退出对象时调用
IPointerDownHandler - OnPointerDown - 按下时调用
IPointerUpHandler - OnPointerUp - 抬起时调用
IPointerClickHandler - OnPointerClick - 点击时调用

Drag拖拽事件:
IInitializePotentialDragHandler - OnInitializePotentialDrag - 在找到拖动目标时调用,可用于初始化值
IBeginDragHandler - OnBeginDrag - 拖动即将开始时在拖动对象上调用
IDragHandler - OnDrag - 发生拖动时在拖动对象上调用
IEndDragHandler - OnEndDrag - 拖动完成时在拖动对象上调用
IDropHandler - OnDrop - 在拖动完成的对象上调用,在拖拉开始的地方必须先实现IDragHandler。

在实现IBeginDragHandler、IEndDragHandler、IDropHandler 这几个接口的时候,必须先实现IDragHandler接口,不然不会响应。

滚轮滚动事件:

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

选择事件:
IUpdateSelectedHandler - OnUpdateSelected - 选中的物体每帧触发
ISelectHandler - OnSelect -选择时调用
IDeselectHandler - OnDeselect -取消选择时调用

InputManager关联组事件(同选择组要求):
IMoveHandler - OnMove - 发生移动事件(向左、向右、向上、向下)时调用
ISubmitHandler - OnSubmit - 按下提交按钮时调用
ICancelHandler - OnCancel - 按下取消按钮时调用

下面使用点击事件来演示如何使用,其他事件一样

新建一个脚本,实现IPointerClickHandler接口然后把脚本挂在UI物体上,在点击物体时就会触发。

using UnityEngine;
using UnityEngine.EventSystems;public class ClickTest : MonoBehaviour, IPointerClickHandler
{public void OnPointerClick(PointerEventData eventData){Debug.Log("IPointerClickHandler点击了" + this.name);}
}

2:添加组件EventTrigger

a:在物体上添加EventTrigger组件,点击AddNewEventType,然后选择需要的事件类型,然后点击加号,把带有自己写的脚本的物体拖入Object,选择自己定义的函数,然后点击时就会触发。

b:可以通过代码动态绑定事件

using UnityEngine;
using UnityEngine.EventSystems;
using static UnityEngine.EventSystems.EventTrigger;public class ClickTest : MonoBehaviour
{void Start(){var tri = transform.GetComponent<EventTrigger>();if (!tri){tri= transform.gameObject.AddComponent<EventTrigger>();}TriggerEvent triEvent = new TriggerEvent();triEvent.AddListener(CustomEventTriggerAddClick);tri.triggers.Add(new EventTrigger.Entry() { eventID = EventTriggerType.PointerClick, callback = triEvent });}/// <summary>/// 代码通过EventTrigger添加事件/// </summary>/// <param name="eventData"></param>public void CustomEventTriggerAddClick(BaseEventData eventData){Debug.Log("代码通过EventTrigger添加事件点击了" + this.name);}
}

3:使用Ugui封装好的组件

a:ugui有一些组件自带了事件,例如常用的Button就有Click事件,添加一个Button,在Click点击加号添加,把带有自己写的脚本的物体拖入Object,选择自己定义的函数,然后点击时就会触发。

b:通过代码动态添加

using UnityEngine;
using UnityEngine.UI;public class ClickTest : MonoBehaviour
{void Start(){var btn = transform.GetComponent<Button>();btn.onClick.AddListener(BtnCustomClick);}public void BtnCustomClick(){Debug.Log("代码绑定Button绑定" + this.name);}
}

4:3D物体相应事件

上面是在UI物体上添加事件,3D物体可以使用吗,如果事件按照上面的流程是没有任何效果的,需要给MainCamera添加PhysicsRaycaster组件,3d物体上必须有collider。然后再按照上面的流程就可以触发对应的事件了。

二:源码分析

1:源码地址

ugui的源码已经公开,需要看源码的可以自行下载,地址:https://github.com/Unity-Technologies/uGUI

当我们在场景中创建任一UI对象后,系统都会自动创建对象EventSystem,并且该对象下有两个组件:EventSystem、StandaloneInputModule。如果是旧版的Unity还有TouchInputModule组件,两个InputModule组件都继承自BaseInputModule。

2:关键脚本介绍

Event System:事件管理器,主要负责处理输入、射线投射以及发送事件,一个场景中只能有一个EventSystem组件。获取当前最新可用的InputModule模块,每个Update通过接口UpdateModules接口调用这些基本输入模块的UpdateModule接口,然后BaseInputModule会在UpdateModule接口中将自己的状态修改成'Updated',之后BaseInputModule的Process接口才会被调用。

Standalone Inout Module:标准接收器

Touch Input Module:触屏接收器

Event Trigger:事件触发器

Graphic Raycaster:界面组件的射线检测(Canvas)

Physics/Physics2D Raycaster:场景物体的射线检测。

BaseInputModule:负责发送输入事件(点击、拖拽、选中等)到具体对象,OnEnable和OnDisable方法中,会更新EventSystem的InputModule。

BaseRaycaster:射线投射

  1. GraphicRaycaster:必须挂在Canvas上,它重写了三个属性sortOrderPriority、renderOrderPriority(获取Canvas的sortingOrder和renderOrder,这在EventSystem里会作为排序依据)和eventCamera(获取canvas.worldCamera,为null则返回Camera.main),使用EventSystem.current.RaycastAll获取被照射到的对象。
  2. PhysicsRaycaster:必须挂在相机上,检查带碰撞的3d物体。使用Physics.RaycastAll来获取所有被照射到的对象。根据距离进行排序,然后包装成RaycastResult结构,加入到resultAppendList里面。EventSystem会将所有的Raycast的照射结果合在一起并排序,然后输入模块取到第一个结果的对象(距离最短)作为受输入事件影响的对象。
  3. Physics2DRaycaster:必须挂在相机上,检查带碰撞的2d物体。使用Physics2D.RaycastAll来照射对象,并且根据SpriteRenderer组件设置结果变量作为排序依据。

RaycasterManager:是一个静态类,维护了一个BaseRaycaster类型的List,BaseRaycaster的OnEnabled与OnDisabled里将自己注册到RaycasterManager。EventSystem里也通过这个类来管理所有的射线照射器。

EventData:存储事件信息

  • BaseEventData:基础的事件信息
  • PointerEventData: 存储 触摸/点击/鼠标操作 事件信息
  • AxisEventData:移动相关的事件信息,注:拖动的操作属于PointerEventData

3:执行流程

一个完整的事件流程:通过EventSystem管理,BaseInputModule输入,BaseRaycaster确定目标对象,目标对象负责接收事件并处理。

 

 

三:按照特殊需求定义自己的事件

1:制作一个2D和3D物体可以同时生效的事件。

在MainCamera上添加PhysicsRaycaster组件就可以。

2:响应本身的事件并且可以穿透响应下面物体的事件。

例如下面的效果,添加3张图片,一个立方体,点击输出点击物体的名称。所有物体都会输出Log。可以详细的控制那个物体可以穿透,那个物体不可以穿透

先自定义一个可以穿透的事件组件

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class AcrossClick : MonoBehaviour, IPointerClickHandler
{/// <summary>/// 是否可以穿透/// </summary>[SerializeField]bool canBreakThrough;/// <summary>/// 需要执行的事件/// </summary>public UnityEvent<GameObject, PointerEventData> click;public void OnPointerClick(PointerEventData eventData){click?.Invoke(this.gameObject, eventData);if (canBreakThrough){PassEvent(eventData, ExecuteEvents.pointerClickHandler);}}public void PassEvent<T>(PointerEventData eventData, ExecuteEvents.EventFunction<T> fun) where T : IEventSystemHandler{List<RaycastResult> rayResList = new List<RaycastResult>();EventSystem.current.RaycastAll(eventData, rayResList);var index = rayResList.FindIndex(r => r.gameObject == this.gameObject);//没有找到或者是点击到的最后一个物体,就不需要穿透if (index < 0 || index >= rayResList.Count - 1)return;//把事件传递给下一个物体ExecuteEvents.Execute(rayResList[index + 1].gameObject, eventData, fun);}
}

然后下一个点击以后执行的函数的脚本

using UnityEngine;
using UnityEngine.EventSystems;public class ClickTest : MonoBehaviour
{public void BtnClick(GameObject obj, PointerEventData e){Debug.Log("执行了" + obj.name);}
}

然后把ClickTest挂到一个任意物体上,把AcrossClick脚本挂在上面的3张图片一个一个立方体上。并且把canBreakThrough勾选上。把ClickTest里面的BtnClick

这篇关于Unity3d Ugui 24 EventSystem事件机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/346716

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

【Tools】大模型中的自注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 自注意力机制(Self-Attention)是一种在Transformer等大模型中经常使用的注意力机制。该机制通过对输入序列中的每个元素计算与其他元素之间的相似性,

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

【Tools】大模型中的注意力机制

摇来摇去摇碎点点的金黄 伸手牵来一片梦的霞光 南方的小巷推开多情的门窗 年轻和我们歌唱 摇来摇去摇着温柔的阳光 轻轻托起一件梦的衣裳 古老的都市每天都改变模样                      🎵 方芳《摇太阳》 在大模型中,注意力机制是一种重要的技术,它被广泛应用于自然语言处理领域,特别是在机器翻译和语言模型中。 注意力机制的基本思想是通过计算输入序列中各个位置的权重,以确

FreeRTOS内部机制学习03(事件组内部机制)

文章目录 事件组使用的场景事件组的核心以及Set事件API做的事情事件组的特殊之处事件组为什么不关闭中断xEventGroupSetBitsFromISR内部是怎么做的? 事件组使用的场景 学校组织秋游,组长在等待: 张三:我到了 李四:我到了 王五:我到了 组长说:好,大家都到齐了,出发! 秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to