From 1f712c1ec06c052c821386255bd9f1238996d546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dino=20Fejzagi=C4=87?= Date: Thu, 9 Nov 2023 23:20:56 +0100 Subject: [PATCH] Implement input down tracking --- .../Interactors/BaseControllerInteractor.cs | 53 +++++++++++++++++++ .../Input/Interactors/BaseDirectInteractor.cs | 1 + 2 files changed, 54 insertions(+) diff --git a/Runtime/Input/Interactors/BaseControllerInteractor.cs b/Runtime/Input/Interactors/BaseControllerInteractor.cs index dcbb1f72..e0cfabf2 100644 --- a/Runtime/Input/Interactors/BaseControllerInteractor.cs +++ b/Runtime/Input/Interactors/BaseControllerInteractor.cs @@ -14,6 +14,7 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +using UnityEvents = UnityEngine.EventSystems; namespace RealityToolkit.Input.Interactors { @@ -76,6 +77,7 @@ public abstract class BaseControllerInteractor : ControllerPoseSynchronizer, ICo private GameObject cursorInstance = null; private Vector3 lastPointerPosition = Vector3.zero; private readonly List inputDownActions = new List(); + private readonly Dictionary> inputDownTrackingDictionary = new Dictionary>(); /// public bool IsOverUI => Result != null && @@ -621,6 +623,7 @@ protected virtual void OnRaisePointerClicked(InputAction inputAction) /// The about to be raised. protected virtual void OnRaisePointerUp(InputAction inputAction) { + ResolveInputDown(inputAction); InputService.RaisePointerUp(this, inputAction); } @@ -634,10 +637,60 @@ protected virtual void OnRaisePointerDown(InputAction inputAction) { if (Result.CurrentTarget.IsNotNull() && IsInteractionEnabled) { + TrackInputDown(inputAction, Result.CurrentTarget); InputService.RaisePointerDown(this, inputAction); } } + /// + /// Records the input down on the with , + /// so that we can ensure input up is raised on the even without focus. + /// + /// The . + /// The input down target . + protected void TrackInputDown(InputAction inputAction, GameObject target) + { + if (inputDownTrackingDictionary.TryGetValue(inputAction.Id, out var targets)) + { + targets.EnsureListItem(target); + return; + } + + inputDownTrackingDictionary.Add(inputAction.Id, new List { target }); + } + + /// + /// Raises input up for on any previously tracked + /// s using . + /// + /// The to resolve. + protected void ResolveInputDown(InputAction inputAction) + { + if (!inputDownTrackingDictionary.TryGetValue(inputAction.Id, out var targets)) + { + return; + } + + for (var i = 0; i < targets.Count; i++) + { + var target = targets[i]; + var handlers = target.GetComponents(); + + if (handlers != null) + { + var eventData = new PointerEventData(UnityEvents.EventSystem.current); + eventData.Initialize(this, inputAction); + + for (var j = 0; j < handlers.Length; j++) + { + handlers[j].OnPointerUp(eventData); + } + } + } + + inputDownTrackingDictionary.Remove(inputAction.Id); + } + /// bool IEqualityComparer.Equals(object left, object right) { diff --git a/Runtime/Input/Interactors/BaseDirectInteractor.cs b/Runtime/Input/Interactors/BaseDirectInteractor.cs index 95cc7fa2..71bfb89e 100644 --- a/Runtime/Input/Interactors/BaseDirectInteractor.cs +++ b/Runtime/Input/Interactors/BaseDirectInteractor.cs @@ -56,6 +56,7 @@ protected override void OnRaisePointerDown(InputAction inputAction) { if (DirectResult.CurrentTarget.IsNotNull() && IsInteractionEnabled) { + TrackInputDown(inputAction, DirectResult.CurrentTarget); InputService.RaisePointerDown(this, inputAction); } }