/// <summary> /// Sorts the available Raycasts in to a priority order for query. /// </summary> /// <param name="priority">The layer mask priority.</param> /// <returns><see cref="RaycastResult"/></returns> private static RaycastResult PrioritizeRaycastResult(LayerMask[] priority, RaycastResultComparer raycastResultComparer) { // If not specified, default to the in-box RaycastResultComparer. if (raycastResultComparer == null) { raycastResultComparer = RaycastResultComparer; } ComparableRaycastResult maxResult = default(ComparableRaycastResult); for (var i = 0; i < RaycastResults.Count; i++) { if (RaycastResults[i].gameObject == null) { continue; } var layerMaskIndex = RaycastResults[i].gameObject.layer.FindLayerListIndex(priority); if (layerMaskIndex == -1) { continue; } var result = new ComparableRaycastResult(RaycastResults[i], layerMaskIndex); if (maxResult.RaycastResult.module == null || raycastResultComparer.Compare(maxResult, result) < 0) { maxResult = result; } } return(maxResult.RaycastResult); }
/// <summary> /// Executes a raycast all and returns the closest element. /// Fixes the current issue with Unity's raycast sorting which does not consider separate canvases. /// </summary> /// <remarks> /// Takes an optional RaycastResultComparer, which will be used to select the highest priority /// raycast result. /// </remarks> /// <returns>RaycastResult if hit, or an empty RaycastResult if nothing was hit</returns> public static RaycastResult Raycast(this EventSystem eventSystem, PointerEventData pointerEventData, LayerMask[] layerMasks, RaycastResultComparer raycastResultComparer = null) { using (RaycastPerfMarker.Auto()) { eventSystem.RaycastAll(pointerEventData, RaycastResults); return(PrioritizeRaycastResult(layerMasks, raycastResultComparer)); } }