From d2ab30e7a69bfe7efda63ae75812207377917bd3 Mon Sep 17 00:00:00 2001
From: miepzerino <o.skotnik@gmail.com>
Date: Sun, 30 Mar 2025 18:50:27 +0000
Subject: [PATCH] Merge branch 'Flexalon-UI-Layouts' into develop
---
Assets/Flexalon/Runtime/Interaction/FlexalonRaycaster.cs | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 104 insertions(+), 0 deletions(-)
diff --git a/Assets/Flexalon/Runtime/Interaction/FlexalonRaycaster.cs b/Assets/Flexalon/Runtime/Interaction/FlexalonRaycaster.cs
new file mode 100644
index 0000000..8db4421
--- /dev/null
+++ b/Assets/Flexalon/Runtime/Interaction/FlexalonRaycaster.cs
@@ -0,0 +1,104 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Flexalon
+{
+ internal class FlexalonRaycaster
+ {
+ public Vector3 hitPosition;
+
+ private int _raycastFrame = 0;
+ private FlexalonInteractable _hitInteractable;
+ private readonly Dictionary<GameObject, FlexalonInteractable> _handles = new Dictionary<GameObject, FlexalonInteractable>();
+
+#if UNITY_UI
+ private List<UnityEngine.EventSystems.RaycastResult> _graphicRaycastResult = new List<UnityEngine.EventSystems.RaycastResult>();
+#endif
+
+#if UNITY_PHYSICS
+ private RaycastHit[] _raycastHits = new RaycastHit[10];
+#endif
+
+ public void Register(FlexalonInteractable interactable)
+ {
+ _handles.Add(interactable.Handle, interactable);
+ }
+
+ public void Unregister(FlexalonInteractable interactable)
+ {
+ _handles.Remove(interactable.Handle);
+ }
+
+ public bool IsHit(Vector3 uiPointer, Ray ray, FlexalonInteractable interactable)
+ {
+ // Check if we've already casted this frame.
+ if (_raycastFrame != Time.frameCount)
+ {
+ _hitInteractable = null;
+ _raycastFrame = Time.frameCount;
+ float minDistance = float.MaxValue;
+ RaycastUI(uiPointer, ref minDistance);
+ RaycastPhysics(ray, ref minDistance);
+ }
+
+ return _hitInteractable == interactable;
+ }
+
+ private void RaycastUI(Vector3 uiPointer, ref float minDistance)
+ {
+#if UNITY_UI
+ var eventSystem = UnityEngine.EventSystems.EventSystem.current;
+ if (eventSystem)
+ {
+ eventSystem.RaycastAll(new UnityEngine.EventSystems.PointerEventData(eventSystem)
+ {
+ position = uiPointer
+ }, _graphicRaycastResult);
+
+ for (int i = 0; i < _graphicRaycastResult.Count; i++)
+ {
+ var hit = _graphicRaycastResult[i];
+ if (hit.distance < minDistance)
+ {
+ if (_handles.TryGetValue(hit.gameObject, out var hitInteractable))
+ {
+ _hitInteractable = hitInteractable;
+ minDistance = hit.distance;
+
+ hitInteractable.UpdateCanvas();
+
+ if (hitInteractable.Canvas?.renderMode == UnityEngine.RenderMode.ScreenSpaceOverlay)
+ {
+ hitPosition = hit.screenPosition;
+ }
+ else
+ {
+ hitPosition = hit.worldPosition;
+ }
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ private void RaycastPhysics(Ray ray, ref float minDistance)
+ {
+#if UNITY_PHYSICS
+ int hits = Physics.RaycastNonAlloc(ray, _raycastHits, 1000);
+
+ // Find the nearest hit interactable.
+ for (int i = 0; i < hits; i++)
+ {
+ var hit = _raycastHits[i];
+ if (hit.distance < minDistance && _handles.TryGetValue(hit.collider.gameObject, out var hitInteractable))
+ {
+ _hitInteractable = hitInteractable;
+ minDistance = hit.distance;
+ hitPosition = hit.point;
+ }
+ }
+#endif
+ }
+ }
+}
\ No newline at end of file
--
Gitblit v1.10.0