当前位置:   article > 正文

Unity 中 UGUI 事件顺序_unity ui 层级 响应 事件 顺序

unity ui 层级 响应 事件 顺序

//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中

射线处理,是把所有的装到链表里.然后排序. 

  1. public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)
  2. {
  3. raycastResults.Clear();
  4. var modules = RaycasterManager.GetRaycasters();
  5. for (int i = 0; i < modules.Count; ++i)
  6. {
  7. var module = modules[i];
  8. if (module == null || !module.IsActive())
  9. continue;
  10. module.Raycast(eventData, raycastResults);
  11. }
  12. raycastResults.Sort(s_RaycastComparer);
  13. }

 

排序规则函数  RaycastComparer

  1. private static readonly Comparison<RaycastResult> s_RaycastComparer = RaycastComparer;
  2. private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
  3. {
  4. if (lhs.module != rhs.module)
  5. {...}
  6. if (lhs.sortingLayer != rhs.sortingLayer)
  7. return rhs.sortingLayer.CompareTo(lhs.sortingLayer);
  8. if (lhs.sortingOrder != rhs.sortingOrder)
  9. return rhs.sortingOrder.CompareTo(lhs.sortingOrder);
  10. if (lhs.depth != rhs.depth)
  11. return rhs.depth.CompareTo(lhs.depth);
  12. if (lhs.distance != rhs.distance)
  13. return lhs.distance.CompareTo(rhs.distance);
  14. return lhs.index.CompareTo(rhs.index);
  15. }

射线穿透排序

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 (...)从筛选出的第一个物体自身开始,一级一级往上获取父物体.直到有组件(实现了该事件接口的组件)接受事件为止.

  1. protected static RaycastResult FindFirstRaycast(List<RaycastResult> candidates)
  2. {
  3. for (var i = 0; i < candidates.Count; ++i)
  4. {
  5. if (candidates[i].gameObject == null)
  6. continue;
  7. return candidates[i];
  8. }
  9. return new RaycastResult();
  10. }
  11. public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler
  12. {
  13. GetEventChain(root, s_InternalTransformList);
  14. for (var i = 0; i < s_InternalTransformList.Count; i++)
  15. {
  16. var transform = s_InternalTransformList[i];
  17. if (Execute(transform.gameObject, eventData, callbackFunction))
  18. return transform.gameObject;
  19. }
  20. return null;
  21. }

 

测试:

//脚本  rayTest.cs


 

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.EventSystems;
  4. public class rayTest : MonoBehaviour ,IPointerClickHandler
  5. {
  6. public void OnPointerClick (PointerEventData eventData)
  7. {
  8. Debug.Log (name);
  9. Debug.Log (eventData.pointerCurrentRaycast.gameObject);
  10. }
  11. }

 

射线第一个扫到的是Text1物体但是他上面没有实现点击事件接口.

所以从Text1开始一级一级找父物体看看父物体祖宗物体上有没有实现这个事件

找到Button上面rayTest脚本中有实现 IPointerClickHandler点击事件接口.

所以就调用这个事件的响应函数OnPointerClick (...)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/101017
推荐阅读
相关标签
  

闽ICP备14008679号