在游戏中,当Overlay的Canvas和Camera 或World Space的Canvas点击范围有重合的时候,总会响应Overlay Canvas的点击事件而忽略其他。
原因是在EventSystem.RaycastComparer中:
if (lhs.module.eventCamera != null && rhs.module.eventCamera != null && lhs.module.eventCamera.depth != rhs.module.eventCamera.depth) { // need to reverse the standard compareTo if (lhs.module.eventCamera.depth < rhs.module.eventCamera.depth) return 1; if (lhs.module.eventCamera.depth == rhs.module.eventCamera.depth) return 0; return -1; } if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority) return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority);
如果比较中有一个Canvas不带Camera,就会比较sortOrderPriority。
GraphicRayCaster里:
public override int sortOrderPriority { get { // We need to return the sorting order here as distance will all be 0 for overlay. if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) return canvas.sortingOrder; return base.sortOrderPriority; } }
BaseRaycaster里:
public virtual int sortOrderPriority { get { return int.MinValue; } }
就是说如果renderMode不是Overlay,就会排在Overlay的下面。
解决方法是自己写一个Raycaster:
using UnityEngine; using UnityEngine.UI; public class UIRaycaster : GraphicRaycaster { public override int sortOrderPriority { get { Canvas canvas = GetComponent<Canvas> (); return canvas.sortingOrder; } } }
不管是不是Overlay,全都按照这个值来排序。