Unity 3D UGUI游戏界面 事件系统
程序员文章站
2022-07-12 23:33:46
...
UGUI 所有的事件系统都是依赖 EventSystem 组件完成的,全面取代之前的SendMessage 系统了。
这是运行状态下的EventSystem。
//--UI事件
UI事件依赖于 Graphic Raycaster 组件,它必须绑定在Canvas 组件上,表示这个Canvas 下的所有UI元素支持的事件。
若有多个Canvas ,想让某个Canvas 下的UI不接受点击事件,可以把这个Canvas 的Graphic Raycaster 组件干掉。
Unity3D UGUI 利用EventTrigger实现按钮事件注册等相关
//--RaycastTarget优化
UGUI的点击事件也是基于射线的,如果不需要响应事件,千万不要在Image或 Text 等组件上勾选RaycastTarget。
UI事件会在EventSystem 的Update()方法中调用Process时触发。UGUI会遍历屏幕中所有的RaycastTarget是True的UI,接着就会发射线,并且排序找到玩家最先接触的那个UI,再抛出事件给逻辑层去响应,这样无形中就会带来很多开销。
拓展一下Scene视图,将所有勾选RaycastTarget的UI用线框显示出来。
using UnityEngine;
using UnityEngine.UI;
public class DrawLineRaycastTargetMyTools : MonoBehaviour
{
#if UNITY_EDITOR
static Vector3[] fourCorners = new Vector3[4];
private void OnDrawGizmos()
{
foreach (MaskableGraphic g in FindObjectsOfType<MaskableGraphic>())
{
if (g.raycastTarget)
{
RectTransform rectTransform = g.transform as RectTransform;
rectTransform.GetWorldCorners(fourCorners);
Gizmos.color = Color.blue;
for (int i = 0; i < 4; i++)
{
Gizmos.DrawLine(fourCorners[i], fourCorners[(i + 1) % 4]);
}
}
}
}
#endif
}
//-渗透UI事件
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIEventPassMyTools : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
//--do
PassEvent(eventData, ExecuteEvents.pointerClickHandler);
}
public void PassEvent<T>(PointerEventData data, ExecuteEvents.EventFunction<T> eventFunction) where T : IEventSystemHandler
{
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(data, results);
GameObject go = data.pointerCurrentRaycast.gameObject;
for (int i = 0; i < results.Count; i++)
{
if (go != results[i].gameObject)
{
ExecuteEvents.Execute(results[i].gameObject, data, eventFunction);
break;//--渗透一次
}
}
}
}