一、IPointerClickHandler接口
通过为 UI 元素添加自定义脚本,实现IPointerClickHandle接口,在点击事件发生时进行处理。
这种方式适用于对特定 UI 元素的点击检测。
cs
using UnityEngine;
using UnityEngine.EventSystems;
public class UIClickHandler : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked on UI element: " + gameObject.name);
}
}
二、IsPointerOverGameObject()方法
这是EventSystem类的一个方法。
这种方法比较简单,适用于只需要知道鼠标或触摸点是否在 UI 上的场景。
鼠标下有UI,则返回true;鼠标下面没有UI,则返回false;
cs
//只需要知道鼠标指针是否在 UI 元素上的场景。
EventSystem.current.IsPointOverGameObject();
//需要同时处理触摸输入时,参数 -1 表示不忽略触摸输入
EventSystem.current.IsPointOverGameObject(-1);
使用场景:
1、简单的 UI 遮挡判断
在一些简单的 UI 逻辑中,只需要知道当前指针是否被 UI 遮挡,而不需要具体知道是哪个 UI 元素。
如在游戏中,当玩家在屏幕上进行滑动操作时,如果指针在 UI 上,可能需要忽略这个滑动操作。
2、场景交互屏蔽
在游戏开发中,当玩家的鼠标指针或触摸点位于 UI 元素之上时,其他交互不希望被触发,可用该方法进行判断鼠标是否UI上。
如鼠标在UI上时,不能点击地面移动角色、选择场景中的物体等;
3、对性能要求高,开销小的场景
IsPointerOverGameObject方法性能开销较小,只返回一个布尔值。
如在一些需要频繁进行指针位置判断的场景中,使用该方法可以减少不必要的性能消耗。
示例:
cs
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Audio;
public class UISoundControl : MonoBehaviour
{
public AudioSource sceneClickSound;
void Update()
{
if (Input.GetMouseButtonDown(0))// 检测鼠标左键点击
{
// 判断指针是否不在 UI 元素上
if (!EventSystem.current.IsPointerOverGameObject(-1))
{
sceneClickSound.Play();// 播放点击音效
}
}
}
}
三、RaycastAll()方法
适用于需要对整个场景(包括 UI 和 3D 物体)进行射线检测的场景,也适用于需要对命中的 UI 元素进行进一步判断处理的场景。
可一次性获取所有被射线命中的对象,无论它们是 UI 元素还是 3D 物体时,并且这种方法可以获取到所有被命中的 UI 元素的详细信息。
1、GraphicRaycaster.Raycast()方法
GraphicRaycaster一个组件,专门用于在 UI 系统中进行射线检测。
GraphicRaycaster的Raycast()方法主要用于针对特定 Canvas 下的 UI 元素进行射线检测。
对当前GraphicRaycaster所在 Canvas 下的 UI 元素进行射线检测。
当你只关心某个 Canvas 内的 UI 交互,并且希望精确控制射线检测范围时,使用GraphicRaycaster更合适。
如,在一个复杂的 UI 界面中,有多个 Canvas 分别管理不同的功能模块,你可以为每个 Canvas 单独添加GraphicRaycaster组件,分别处理它们的射线检测。
cs
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections.Generic;
public class GraphicRaycastExample : MonoBehaviour
{
public GraphicRaycaster graphicRaycaster;
public EventSystem eventSystem;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
PointerEventData eventData = new PointerEventData(eventSystem);
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
graphicRaycaster.Raycast(eventData, results);
foreach (RaycastResult result in results)
{
Debug.Log("Hit UI element: " + result.gameObject.name);
}
}
}
}
2、EventSystem.current.RaycastAll()
这是EventSystem类的一个方法。
主要用于检测鼠标或触摸点是否命中 UI 元素,适用于处理 UI 交互场景。
cs
//创建一个PointerEventData对象,模拟指针事件
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = Input.mousePosition;
//使用RaycastAll方法对整个 UI 层进行射线检测,返回一个RaycastResult列表
//包含了所有被射线命中的 UI 元素的信息,包括元素本身、命中点、距离等
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
//通过遍历这个列表来获取每个命中元素的具体信息
foreach (RaycastResult result in results)
{
Debug.Log("Hit UI element: " + result.gameObject.name);
}
使用场景:
1、多个UI 交互逻辑
当需要根据不同的 UI 元素执行不同的操作时,使用RaycastAll方法可以获取到所有被命中的 UI 元素,然后根据元素的类型或其他属性进行不同的处理。
如在一个包含多个按钮和文本框的界面中,点击不同的元素需要执行不同的逻辑。
2、多层 UI 元素处理
在一些复杂的 UI 布局中,可能存在多层 UI 元素重叠的情况,使用RaycastAll方法可以获取到所有被命中的 UI 元素,然后对这些元素进行逐层处理。
如在一个弹出窗口中,可能有背景遮罩、内容面板和关闭按钮等多层元素,点击时需要依次处理这些元素的逻辑。
3、 对射线检测结果的深度处理
在某些情况下,需要获取射线检测的详细信息,如命中点、距离等。RaycastAll方法返回的RaycastResult列表中包含了这些信息。
如在实现一个 UI 元素的拖拽功能时,可以根据命中点的位置来确定元素的拖拽偏移量。
示例:
cs
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections.Generic;
public class UIRaycastAndGetProperties : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
foreach (RaycastResult result in results)// 遍历检测结果列表
{
GameObject hitObject = result.gameObject;
Text txt = hitObject.GetComponent<Text>();
if (txt != null)
{
Debug.Log($"Text content: {txt.text}");
}
}
}
}
}
3、Physics.RaycastAll()
是Physics类的静态方法,作为静态方法,直接通过Physics.RaycastAll调用,不依赖与EventSystem,开发者可以在任何需要进行射线检测的地方调用该方法。
适用于纯粹的无论场景射线检测,它不依赖于 UI 事件系统,更专注于物理世界中的射线交互。
该方法用于在物理场景中进行射线检测,可检测射线命中的所有 3D 物体;
常用于处理游戏中的射击、碰撞检测等进行各种物理相关的射线检测;
比如射击游戏中检测子弹是否击中目标、角色是否能看到特定物体等。
cs
using UnityEngine;
public class PhysicsRaycastAllExample : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// 从主摄像机的位置向鼠标点击位置发射一条射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// 进行射线检测,获取所有命中的物体信息
RaycastHit[] hits = Physics.RaycastAll(ray);
foreach (RaycastHit hit in hits)// 遍历所有命中的物体
{
Debug.Log("Hit object: " + hit.collider.gameObject.name);
}
}
}
}
4、 PhysicsRaycaster
和GraphicRaycaster一样,作为组件使用,需要挂载到摄像机上,是MonoBehaviour的派生类。
和纯物理的不依赖EventSystem,可直接调用的Physics.RaycastAll射线检测不同;
PhysicsRaycast主要用于UI事件和3d物理对象的交互,通常结合 EventSystem 使用;
用于处理基于指针输入(如鼠标点击、触摸)与场景中 3D 物理对象的交互,更侧重于将物理射线检测集成到 UI 事件处理流程中。
如当你希望在点击屏幕时,通过 UI 事件系统触发对 3D 物体的选中操作,就可以使用 PhysicsRaycaster。
cs
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class PhysicsRaycasterExample : MonoBehaviour
{
public PhysicsRaycaster physicsRaycaster;
public EventSystem eventSystem;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
PointerEventData eventData = new PointerEventData(eventSystem);
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
physicsRaycaster.Raycast(eventData, results);
foreach (RaycastResult result in results)
{
Debug.Log("Hit object via PhysicsRaycaster: " + result.gameObject.name);
}
}
}
}
四、EventTrigger组件
EventTrigger组件是 Unity 提供的一种可视化配置 UI 事件的方式,无需编写复杂的脚本即可实现点击检测。
操作步骤:
1、在需要检测点击事件的UI元素身上,添加EventTrigger组件。
2、在EventTrigger组件种,点击AddNewEventType,选择需要的Pointer事件

3、在选择的Pointer事件里,点击"+"添加点击事件。
4、将需要执行点击事件的对象拖入RuntimeOnly字段,并选择相应的方法。
