Unity 中 UGUI 事件顺序
//15.输入处理---------------------------------------------------------------------------------------------
继承关系:
BaseInputModule<---PointerInputModule<----TouchInputModule
BaseInputModule<---PointerInputModule<----StandaloneInputModule
函数调用关系:
EventSystem.Update()---子类.Process()---子类.ProcessMouseEvent()或 子类.ProcessMouseEvents()---子类.GetMousePointerEventData()
EventSystem.Process() 多态.
输入管理: EventSystem物体上的Standalone Input Module,TouchInputModule组件
//16. 射线检测-------------------------------------------------------------------------------------------
继承关系:
BaseRaycaster<---PhysicsRaycaster<---Physics2DRaycaster
BaseRaycaster<---GraphicRaycaster
函数调用关系:
EventSystem.RaycastAll()---子类.Raycast()---EventSystem.RaycastComparer()
EventSystem.Raycast() 多态. 进行射线检测.
射线管理: Canvas画布上的Graphic Raycaster组件
[RequireComponent(typeof(Canvas))]
public class GraphicRaycaster : BaseRaycaster
{...}
这个脚本必须挂在Canvas上.UI元素必须具有继承自Graphic的组件.也就是可视的UI元素.
GraphicRaycaster组件的成员属性:
Ignore Reversed Graphic 忽略反方向图形. 即.图形面对前方时.才参与射线检测.
Blocking Objects 屏蔽对象
渲染模式不为ScreenSpaceOverlay时起作用.屏蔽指定类型的对象.使他们不参与射线检测.
None 不屏蔽任何物理对象
TwoD 屏蔽2d物理对象.(具有2d碰撞体的对象)
ThreeD 屏蔽3d物理对象.(具有3d碰撞体的对象)
All 屏蔽所有物理对象
Blocking Mask 屏蔽层(layer)
渲染模式不为ScreenSpaceOverlay,且locking objects不为None时起作用.
使屏蔽对象(Blocking objects)的物体,不参与射线检测.
注意:添加的碰撞器大小要和物体一样大.或者比物体本身大.创建的碰撞体默认是长宽都是1.狠小狠难点中.
射线穿透的顺序:
EventSystem.cs中
射线处理,是把所有的装到链表里.然后排序.
public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)
{
raycastResults.Clear();
var modules = RaycasterManager.GetRaycasters();
for (int i = 0; i < modules.Count; ++i)
{
var module = modules[i];
if (module == null || !module.IsActive())
continue;
module.Raycast(eventData, raycastResults);
}
raycastResults.Sort(s_RaycastComparer);
}
排序规则函数 RaycastComparer
private static readonly Comparison<RaycastResult> s_RaycastComparer = RaycastComparer;
private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
{
if (lhs.module != rhs.module)
{...}
if (lhs.sortingLayer != rhs.sortingLayer)
return rhs.sortingLayer.CompareTo(lhs.sortingLayer);
if (lhs.sortingOrder != rhs.sortingOrder)
return rhs.sortingOrder.CompareTo(lhs.sortingOrder);
if (lhs.depth != rhs.depth)
return rhs.depth.CompareTo(lhs.depth);
if (lhs.distance != rhs.distance)
return lhs.distance.CompareTo(rhs.distance);
return lhs.index.CompareTo(rhs.index);
}
射线穿透排序
EventSystem.RaycastComparer
对射线穿透的所有未屏蔽的物体进行排序
1. 如果Canvas指定了不同摄像机,则按摄像机深度排序.
2. 按sortOrder顺序排序
3. 按renderOrder顺序排序.
4. 按depth排序.凡是继承自Graphic的类都有depth属性.在PhysicsRaycaster,Physic2DRaycaster两种射线模式下,该值为0.
5. 按distance顺序排序.射线发出点到物体的具体.
6. 按index顺序排序. 不管是哪种射线模式,或者是混合射线模式,都会将射线碰撞到的UI物体放入一个链表或者数组,这里的index就是他的下标索引值.
组件Canvas Group. 可以管理Canvas.也可以控制Canvas内UI元素.
属性:
alpha 透明度
interactable 是否可交互
Blocks Raycasts 控制是否穿透
Ignore parent group是否忽略父物体的Canvas Group组件效果.
//17. 事件分发-------------------------------------------------------------------------------------------
函数调用关系:
BaseInputModule.FindFirstRaycast (...)取出射线碰撞到的第一个物体,进行事件处理.
ExecuteEvents.ExecuteHierarchy (...)从筛选出的第一个物体自身开始,一级一级往上获取父物体.直到有组件(实现了该事件接口的组件)接受事件为止.
protected static RaycastResult FindFirstRaycast(List<RaycastResult> candidates)
{
for (var i = 0; i < candidates.Count; ++i)
{
if (candidates[i].gameObject == null)
continue;
return candidates[i];
}
return new RaycastResult();
}
public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler
{
GetEventChain(root, s_InternalTransformList);
for (var i = 0; i < s_InternalTransformList.Count; i++)
{
var transform = s_InternalTransformList[i];
if (Execute(transform.gameObject, eventData, callbackFunction))
return transform.gameObject;
}
return null;
}
测试:
//脚本 rayTest.cs
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class rayTest : MonoBehaviour ,IPointerClickHandler
{
public void OnPointerClick (PointerEventData eventData)
{
Debug.Log (name);
Debug.Log (eventData.pointerCurrentRaycast.gameObject);
}
}
射线第一个扫到的是Text1物体但是他上面没有实现点击事件接口.
所以从Text1开始一级一级找父物体看看父物体祖宗物体上有没有实现这个事件
找到Button上面rayTest脚本中有实现 IPointerClickHandler点击事件接口.
所以就调用这个事件的响应函数OnPointerClick (...)
相关文章
- 项目属性-->生成事件-->后期生成事件命令行
- Windows窗体应用程序常用的几个类的属性、方法以及事件
- 【Serilog】具有完全结构化事件的简单.NET日志记录
- 【Vue】利用Vue绑定Html元素事件(如:click)综合示例
- QT中事件发送函数sendEvent()、postEvent()详解
- Javascript 笔记与总结(2-17)事件委托
- C#-创建自定义双击事件
- SwiftUI 高级用法之如何捕获截取事件实现隐藏收起展开PreferenceKey(教程含源码)
- 通俗解释什么是响应式编程?-响应式编程就是因为我们得“响应”这些事件而得以命名
- JS高阶---线程与事件机制(小结)
- jQuery的on绑定事件在mobile safari(iphone / ipad / ipod)上无法使用的解决方案
- 二季度八大热点网络安全事件出炉 台湾ATM遭黑客攻击被窃取7000万上榜
- Unity事件的高级监听与广播系统
- Unity-MonoBehaviour下的七种事件
- 【Unity3D日常开发】Unity循环里面给按钮添加绑定事件
- Unity框架学习_EventManager,简单的事件管理,轻松实现全局的事件系统
- Unity UIWidgets 之 UIWidgets 简单入门使用之 简单点击事件的数据交互使用
- Unity 基础 之 实现简单监听晃动(摇一摇)手机设备震动手机设备的事件的功能
- Unity Android 之 AndroidJavaProxy 交互,实现 Unity 委托事件到 Android 端(aar包形式)
- Swift - 点击事件奇偶次判断