//[Pure] protected virtual void Raycast(Canvas canvas, Camera eventCamera, PointerEventData eventData, Ray ray, ref List <RaycastResult> results) { float hitDistance = GetHitDistance(ray, VRTK_UIPointer.GetPointerLength(eventData.pointerId)); IList <Graphic> canvasGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas); for (int i = 0; i < canvasGraphics.Count; ++i) { Graphic graphic = canvasGraphics[i]; if (graphic.depth == -1 || !graphic.raycastTarget) { continue; } Transform graphicTransform = graphic.transform; Vector3 graphicForward = graphicTransform.forward; float distance = Vector3.Dot(graphicForward, graphicTransform.position - ray.origin) / Vector3.Dot(graphicForward, ray.direction); if (distance < 0) { continue; } //Prevents "flickering hover" on items near canvas center. if ((distance - UI_CONTROL_OFFSET) > hitDistance) { continue; } Vector3 position = ray.GetPoint(distance); Vector2 pointerPosition = eventCamera.WorldToScreenPoint(position); if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera)) { continue; } if (graphic.Raycast(pointerPosition, eventCamera)) { RaycastResult result = new RaycastResult() { gameObject = graphic.gameObject, module = this, distance = distance, screenPosition = pointerPosition, worldPosition = position, depth = graphic.depth, sortingLayer = canvas.sortingLayerID, sortingOrder = canvas.sortingOrder, }; VRTK_SharedMethods.AddListValue(results, result); } } results.Sort((g1, g2) => g2.depth.CompareTo(g1.depth)); }