AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
InputManager.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using System.Collections.Generic;
6 using UnityEngine;
7 using UnityEngine.EventSystems;
8 
9 #if UNITY_WSA || UNITY_STANDALONE_WIN
10 using UnityEngine.Windows.Speech;
11 #endif
12 
13 namespace HoloToolkit.Unity.InputModule
14 {
19  public class InputManager : Singleton<InputManager>
20  {
21  public event Action InputEnabled;
22  public event Action InputDisabled;
23 
27  private readonly List<GameObject> globalListeners = new List<GameObject>(0);
28  private readonly Stack<GameObject> modalInputStack = new Stack<GameObject>();
29  private readonly Stack<GameObject> fallbackInputStack = new Stack<GameObject>();
30 
36  public GameObject OverrideFocusedObject { get; set; }
37 
38  private int disabledRefCount;
39 
40  private InputEventData inputEventData;
41  private InputClickedEventData sourceClickedEventData;
42  private SourceStateEventData sourceStateEventData;
43  private ManipulationEventData manipulationEventData;
44  private HoldEventData holdEventData;
45  private NavigationEventData navigationEventData;
46  private XboxControllerEventData xboxControllerEventData;
47  private SourceRotationEventData sourceRotationEventData;
48  private SourcePositionEventData sourcePositionEventData;
49  private PointerSpecificEventData pointerSpecificEventData;
50  private InputPositionEventData inputPositionEventData;
51  private SelectPressedEventData selectPressedEventData;
52  private BoundingBoxEventData boundingBoxActivityEventData;
53 #if UNITY_WSA || UNITY_STANDALONE_WIN
54  private SpeechEventData speechEventData;
55  private DictationEventData dictationEventData;
56 #endif
57 
61  private static readonly List<InputSourceInfo> detectedInputSources = new List<InputSourceInfo>(0);
62 
66  public List<InputSourceInfo> DetectedInputSources { get { return detectedInputSources; } }
67 
71  public bool IsInputEnabled
72  {
73  get { return disabledRefCount <= 0; }
74  }
75 
79  [Obsolete("Will be removed in a future release. If you need to know if a specific pointer should send Unity UI Events use FocusManager.Instance.GetSpecificPointerEventData()!=null")]
80  public bool ShouldSendUnityUiEvents { get { return FocusManager.Instance.GetGazePointerEventData() != null && EventSystem.current != null; } }
81 
87  public void PushModalInputHandler(GameObject inputHandler)
88  {
89  modalInputStack.Push(inputHandler);
90  }
91 
95  public void PopModalInputHandler()
96  {
97  if (modalInputStack.Count > 0)
98  {
99  modalInputStack.Pop();
100 
101  }
102  }
103 
107  public void ClearModalInputStack()
108  {
109  modalInputStack.Clear();
110  }
111 
117  public void AddGlobalListener(GameObject listener)
118  {
119  globalListeners.Add(listener);
120  }
121 
126  public void RemoveGlobalListener(GameObject listener)
127  {
128  globalListeners.Remove(listener);
129  }
130 
136  public void PushFallbackInputHandler(GameObject inputHandler)
137  {
138  fallbackInputStack.Push(inputHandler);
139  }
140 
145  {
146  fallbackInputStack.Pop();
147  }
148 
153  {
154  fallbackInputStack.Clear();
155  }
156 
162  public void PushInputDisable()
163  {
164  ++disabledRefCount;
165 
166  if (disabledRefCount == 1)
167  {
168  InputDisabled.RaiseEvent();
169  }
170  }
171 
176  public void PopInputDisable()
177  {
178  --disabledRefCount;
179  Debug.Assert(disabledRefCount >= 0, "Tried to pop more input disable than the amount pushed.");
180 
181  if (disabledRefCount == 0)
182  {
183  InputEnabled.RaiseEvent();
184  }
185  }
186 
191  {
192  bool wasInputDisabled = disabledRefCount > 0;
193  disabledRefCount = 0;
194 
195  if (wasInputDisabled)
196  {
197  InputEnabled.RaiseEvent();
198  }
199  }
200 
201  private void InitializeEventDatas()
202  {
203  inputEventData = new InputEventData(EventSystem.current);
204  sourceClickedEventData = new InputClickedEventData(EventSystem.current);
205  sourceStateEventData = new SourceStateEventData(EventSystem.current);
206  manipulationEventData = new ManipulationEventData(EventSystem.current);
207  navigationEventData = new NavigationEventData(EventSystem.current);
208  holdEventData = new HoldEventData(EventSystem.current);
209  pointerSpecificEventData = new PointerSpecificEventData(EventSystem.current);
210  inputPositionEventData = new InputPositionEventData(EventSystem.current);
211  selectPressedEventData = new SelectPressedEventData(EventSystem.current);
212  sourceRotationEventData = new SourceRotationEventData(EventSystem.current);
213  sourcePositionEventData = new SourcePositionEventData(EventSystem.current);
214  xboxControllerEventData = new XboxControllerEventData(EventSystem.current);
215  boundingBoxActivityEventData = new BoundingBoxEventData(EventSystem.current);
216 #if UNITY_WSA || UNITY_STANDALONE_WIN
217  speechEventData = new SpeechEventData(EventSystem.current);
218  dictationEventData = new DictationEventData(EventSystem.current);
219 #endif
220  }
221 
222  #region Unity APIs
223 
224  protected override void Awake()
225  {
226  base.Awake();
227  InitializeEventDatas();
228  }
229 
230  private void Start()
231  {
233  {
234  Debug.LogError("InputManager requires an active FocusManager in the scene");
235  }
236  }
237 
238  #endregion // Unity APIs
239 
240  public void HandleEvent<T>(BaseEventData eventData, ExecuteEvents.EventFunction<T> eventHandler) where T : IEventSystemHandler
241  {
242  if (!Instance.enabled || disabledRefCount > 0)
243  {
244  return;
245  }
246 
247  Debug.Assert(!eventData.used);
248 
249  // Use focused object when OverrideFocusedObject is null.
250  GameObject focusedObject = (OverrideFocusedObject == null) ? FocusManager.Instance.TryGetFocusedObject(eventData) : OverrideFocusedObject;
251 
252  // Send the event to global listeners
253  for (int i = 0; i < globalListeners.Count; i++)
254  {
255  // Global listeners should only get events on themselves, as opposed to their hierarchy.
256  ExecuteEvents.Execute(globalListeners[i], eventData, eventHandler);
257  }
258 
259  if (eventData.used)
260  {
261  // All global listeners get a chance to see the event, but if any of them marked it used, we stop
262  // the event from going any further.
263  return;
264  }
265 
266  // TODO: robertes: consider whether modal and fallback input should flow to each handler until used
267  // or it should flow to just the topmost handler on the stack as it does today.
268 
269  // Handle modal input if one exists
270  if (modalInputStack.Count > 0)
271  {
272  GameObject modalInput = modalInputStack.Peek();
273 
274  // If there is a focused object in the hierarchy of the modal handler, start the event
275  // bubble there
276  if (focusedObject != null && modalInput != null && focusedObject.transform.IsChildOf(modalInput.transform))
277  {
278  if (ExecuteEvents.ExecuteHierarchy(focusedObject, eventData, eventHandler) && eventData.used)
279  {
280  return;
281  }
282  }
283  // Otherwise, just invoke the event on the modal handler itself
284  else
285  {
286  if (ExecuteEvents.ExecuteHierarchy(modalInput, eventData, eventHandler) && eventData.used)
287  {
288  return;
289  }
290  }
291  }
292 
293  // If event was not handled by modal, pass it on to the current focused object
294  if (focusedObject != null)
295  {
296  if (ExecuteEvents.ExecuteHierarchy(focusedObject, eventData, eventHandler) && eventData.used)
297  {
298  return;
299  }
300  }
301 
302  // If event was not handled by the focused object, pass it on to any fallback handlers
303  if (fallbackInputStack.Count > 0)
304  {
305  GameObject fallbackInput = fallbackInputStack.Peek();
306  if (ExecuteEvents.ExecuteHierarchy(fallbackInput, eventData, eventHandler) && eventData.used)
307  {
308  return;
309  }
310  }
311  }
312 
313  #region Focus Events
314 
315  private static readonly ExecuteEvents.EventFunction<IFocusable> OnFocusEnterEventHandler =
316  delegate (IFocusable handler, BaseEventData eventData)
317  {
318  handler.OnFocusEnter();
319  };
320 
325  public void RaiseFocusEnter(GameObject focusedObject)
326  {
327  ExecuteEvents.ExecuteHierarchy(focusedObject, null, OnFocusEnterEventHandler);
328 
329  PointerInputEventData pointerInputEventData = FocusManager.Instance.GetGazePointerEventData();
330 
331  if (pointerInputEventData != null)
332  {
333  ExecuteEvents.ExecuteHierarchy(focusedObject, pointerInputEventData, ExecuteEvents.pointerEnterHandler);
334  }
335  }
336 
337  private static readonly ExecuteEvents.EventFunction<IFocusable> OnFocusExitEventHandler =
338  delegate (IFocusable handler, BaseEventData eventData)
339  {
340  handler.OnFocusExit();
341  };
342 
347  public void RaiseFocusExit(GameObject deFocusedObject)
348  {
349  ExecuteEvents.ExecuteHierarchy(deFocusedObject, null, OnFocusExitEventHandler);
350 
351  PointerInputEventData pointerInputEventData = FocusManager.Instance.GetGazePointerEventData();
352 
353  if (pointerInputEventData != null)
354  {
355  ExecuteEvents.ExecuteHierarchy(deFocusedObject, pointerInputEventData, ExecuteEvents.pointerExitHandler);
356  }
357  }
358 
359  private static readonly ExecuteEvents.EventFunction<IPointerSpecificFocusable> OnPointerSpecificFocusEnterEventHandler =
360  delegate (IPointerSpecificFocusable handler, BaseEventData eventData)
361  {
362  PointerSpecificEventData casted = ExecuteEvents.ValidateEventData<PointerSpecificEventData>(eventData);
363  handler.OnFocusEnter(casted);
364  };
365 
366  private static readonly ExecuteEvents.EventFunction<IPointerSpecificFocusable> OnPointerSpecificFocusExitEventHandler =
367  delegate (IPointerSpecificFocusable handler, BaseEventData eventData)
368  {
369  PointerSpecificEventData casted = ExecuteEvents.ValidateEventData<PointerSpecificEventData>(eventData);
370  handler.OnFocusExit(casted);
371  };
372 
379  public void RaisePointerSpecificFocusChangedEvents(IPointingSource pointer, GameObject oldFocusedObject, GameObject newFocusedObject)
380  {
381  if (oldFocusedObject != null)
382  {
383  pointerSpecificEventData.Initialize(pointer);
384  ExecuteEvents.ExecuteHierarchy(oldFocusedObject, pointerSpecificEventData, OnPointerSpecificFocusExitEventHandler);
385  }
386 
387  if (newFocusedObject != null)
388  {
389  pointerSpecificEventData.Initialize(pointer);
390  ExecuteEvents.ExecuteHierarchy(newFocusedObject, pointerSpecificEventData, OnPointerSpecificFocusEnterEventHandler);
391  }
392  }
393 
394  #endregion // Focus Events
395 
396  #region Generic Input Events
397 
398  private static readonly ExecuteEvents.EventFunction<IInputClickHandler> OnInputClickedEventHandler =
399  delegate (IInputClickHandler handler, BaseEventData eventData)
400  {
401  var casted = ExecuteEvents.ValidateEventData<InputClickedEventData>(eventData);
402  handler.OnInputClicked(casted);
403  };
404 
405  public void RaiseInputClicked(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, int tapCount, object[] tags = null)
406  {
407  // Create input event
408  sourceClickedEventData.Initialize(source, sourceId, tags, pressType, tapCount);
409 
410  // Pass handler through HandleEvent to perform modal/fallback logic
411  HandleEvent(sourceClickedEventData, OnInputClickedEventHandler);
412 
413  // NOTE: In Unity UI, a "click" happens on every pointer up, so we have RaiseSourceUp call the pointerClickHandler.
414  }
415 
416  private static readonly ExecuteEvents.EventFunction<IInputHandler> OnSourceUpEventHandler =
417  delegate (IInputHandler handler, BaseEventData eventData)
418  {
419  var casted = ExecuteEvents.ValidateEventData<InputEventData>(eventData);
420  handler.OnInputUp(casted);
421  };
422 
423  public void RaiseSourceUp(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, object[] tags = null)
424  {
425  // Create input event
426  inputEventData.Initialize(source, sourceId, tags, pressType);
427 
428  // Pass handler through HandleEvent to perform modal/fallback logic
429  HandleEvent(inputEventData, OnSourceUpEventHandler);
430 
431  // UI events
432  IPointingSource pointingSource;
433  FocusManager.Instance.TryGetPointingSource(inputEventData, out pointingSource);
434  PointerInputEventData pointerInputEventData = FocusManager.Instance.GetSpecificPointerEventData(pointingSource);
435  if (pointerInputEventData != null && pressType == InteractionSourcePressInfo.Select)
436  {
437  pointerInputEventData.InputSource = source;
438  pointerInputEventData.SourceId = sourceId;
439 
440  if (pointerInputEventData.selectedObject != null)
441  {
442  ExecuteEvents.ExecuteHierarchy(pointerInputEventData.selectedObject, pointerInputEventData, ExecuteEvents.pointerUpHandler);
443  ExecuteEvents.ExecuteHierarchy(pointerInputEventData.selectedObject, pointerInputEventData, ExecuteEvents.pointerClickHandler);
444  }
445 
446  pointerInputEventData.Clear();
447  }
448  }
449 
450  private static readonly ExecuteEvents.EventFunction<IInputHandler> OnSourceDownEventHandler =
451  delegate (IInputHandler handler, BaseEventData eventData)
452  {
453  var casted = ExecuteEvents.ValidateEventData<InputEventData>(eventData);
454  handler.OnInputDown(casted);
455  };
456 
457  public void RaiseSourceDown(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, object[] tags = null)
458  {
459  // Create input event
460  inputEventData.Initialize(source, sourceId, tags, pressType);
461 
462  // Pass handler through HandleEvent to perform modal/fallback logic
463  HandleEvent(inputEventData, OnSourceDownEventHandler);
464 
465  // UI events
466  IPointingSource pointingSource;
467  FocusManager.Instance.TryGetPointingSource(inputEventData, out pointingSource);
468  PointerInputEventData pointerInputEventData = FocusManager.Instance.GetSpecificPointerEventData(pointingSource);
469  if (pointerInputEventData != null && pressType == InteractionSourcePressInfo.Select)
470  {
471  pointerInputEventData.InputSource = source;
472  pointerInputEventData.SourceId = sourceId;
473  pointerInputEventData.pointerId = (int)sourceId;
474 
475  pointerInputEventData.eligibleForClick = true;
476  pointerInputEventData.delta = Vector2.zero;
477  pointerInputEventData.dragging = false;
478  pointerInputEventData.useDragThreshold = true;
479  pointerInputEventData.pressPosition = pointerInputEventData.position;
480  pointerInputEventData.pointerPressRaycast = pointerInputEventData.pointerCurrentRaycast;
481 
482  if (pointerInputEventData.selectedObject != null)
483  {
484  ExecuteEvents.ExecuteHierarchy(pointerInputEventData.selectedObject, pointerInputEventData, ExecuteEvents.pointerDownHandler);
485  }
486  }
487  }
488 
489  #endregion // Generic Input Events
490 
491  #region Source State Events
492 
493  private static readonly ExecuteEvents.EventFunction<ISourceStateHandler> OnSourceDetectedEventHandler =
494  delegate (ISourceStateHandler handler, BaseEventData eventData)
495  {
496  var casted = ExecuteEvents.ValidateEventData<SourceStateEventData>(eventData);
497  handler.OnSourceDetected(casted);
498  };
499 
500  public void RaiseSourceDetected(IInputSource source, uint sourceId, object[] tags = null)
501  {
502  AddSource(source, sourceId);
503 
504  // Create input event
505  sourceStateEventData.Initialize(source, sourceId, tags);
506 
507  // Pass handler through HandleEvent to perform modal/fallback logic
508  HandleEvent(sourceStateEventData, OnSourceDetectedEventHandler);
509  }
510 
511  private static readonly ExecuteEvents.EventFunction<ISourceStateHandler> OnSourceLostEventHandler =
512  delegate (ISourceStateHandler handler, BaseEventData eventData)
513  {
514  var casted = ExecuteEvents.ValidateEventData<SourceStateEventData>(eventData);
515  handler.OnSourceLost(casted);
516  };
517 
518  public void RaiseSourceLost(IInputSource source, uint sourceId, object[] tags = null)
519  {
520  RemoveSource(source, sourceId);
521 
522  // Create input event
523  sourceStateEventData.Initialize(source, sourceId, tags);
524 
525  // Pass handler through HandleEvent to perform modal/fallback logic
526  HandleEvent(sourceStateEventData, OnSourceLostEventHandler);
527  }
528 
529  #endregion
530 
531  #region Manipulation Events
532 
533  private static readonly ExecuteEvents.EventFunction<IManipulationHandler> OnManipulationStartedEventHandler =
534  delegate (IManipulationHandler handler, BaseEventData eventData)
535  {
536  ManipulationEventData casted = ExecuteEvents.ValidateEventData<ManipulationEventData>(eventData);
537  handler.OnManipulationStarted(casted);
538  };
539 
540  public void RaiseManipulationStarted(IInputSource source, uint sourceId, object[] tags = null)
541  {
542  // Create input event
543  manipulationEventData.Initialize(source, sourceId, tags, Vector3.zero);
544 
545  // Pass handler through HandleEvent to perform modal/fallback logic
546  HandleEvent(manipulationEventData, OnManipulationStartedEventHandler);
547  }
548 
549  private static readonly ExecuteEvents.EventFunction<IManipulationHandler> OnManipulationUpdatedEventHandler =
550  delegate (IManipulationHandler handler, BaseEventData eventData)
551  {
552  ManipulationEventData casted = ExecuteEvents.ValidateEventData<ManipulationEventData>(eventData);
553  handler.OnManipulationUpdated(casted);
554  };
555 
556  public void RaiseManipulationUpdated(IInputSource source, uint sourceId, Vector3 cumulativeDelta, object[] tags = null)
557  {
558  // Create input event
559  manipulationEventData.Initialize(source, sourceId, tags, cumulativeDelta);
560 
561  // Pass handler through HandleEvent to perform modal/fallback logic
562  HandleEvent(manipulationEventData, OnManipulationUpdatedEventHandler);
563  }
564 
565  private static readonly ExecuteEvents.EventFunction<IManipulationHandler> OnManipulationCompletedEventHandler =
566  delegate (IManipulationHandler handler, BaseEventData eventData)
567  {
568  ManipulationEventData casted = ExecuteEvents.ValidateEventData<ManipulationEventData>(eventData);
569  handler.OnManipulationCompleted(casted);
570  };
571 
572  public void RaiseManipulationCompleted(IInputSource source, uint sourceId, Vector3 cumulativeDelta, object[] tags = null)
573  {
574  // Create input event
575  manipulationEventData.Initialize(source, sourceId, tags, cumulativeDelta);
576 
577  // Pass handler through HandleEvent to perform modal/fallback logic
578  HandleEvent(manipulationEventData, OnManipulationCompletedEventHandler);
579  }
580 
581  private static readonly ExecuteEvents.EventFunction<IManipulationHandler> OnManipulationCanceledEventHandler =
582  delegate (IManipulationHandler handler, BaseEventData eventData)
583  {
584  ManipulationEventData casted = ExecuteEvents.ValidateEventData<ManipulationEventData>(eventData);
585  handler.OnManipulationCanceled(casted);
586  };
587 
588  public void RaiseManipulationCanceled(IInputSource source, uint sourceId, object[] tags = null)
589  {
590  // Create input event
591  manipulationEventData.Initialize(source, sourceId, tags, Vector3.zero);
592 
593  // Pass handler through HandleEvent to perform modal/fallback logic
594  HandleEvent(manipulationEventData, OnManipulationCanceledEventHandler);
595  }
596 
597  #endregion // Manipulation Events
598 
599  #region Hold Events
600 
601  private static readonly ExecuteEvents.EventFunction<IHoldHandler> OnHoldStartedEventHandler =
602  delegate (IHoldHandler handler, BaseEventData eventData)
603  {
604  HoldEventData casted = ExecuteEvents.ValidateEventData<HoldEventData>(eventData);
605  handler.OnHoldStarted(casted);
606  };
607 
608  public void RaiseHoldStarted(IInputSource source, uint sourceId, object[] tags = null)
609  {
610  // Create input event
611  holdEventData.Initialize(source, sourceId, tags);
612 
613  // Pass handler through HandleEvent to perform modal/fallback logic
614  HandleEvent(holdEventData, OnHoldStartedEventHandler);
615  }
616 
617  private static readonly ExecuteEvents.EventFunction<IHoldHandler> OnHoldCompletedEventHandler =
618  delegate (IHoldHandler handler, BaseEventData eventData)
619  {
620  HoldEventData casted = ExecuteEvents.ValidateEventData<HoldEventData>(eventData);
621  handler.OnHoldCompleted(casted);
622  };
623 
624  public void RaiseHoldCompleted(IInputSource source, uint sourceId, object[] tags = null)
625  {
626  // Create input event
627  holdEventData.Initialize(source, sourceId, tags);
628 
629  // Pass handler through HandleEvent to perform modal/fallback logic
630  HandleEvent(holdEventData, OnHoldCompletedEventHandler);
631  }
632 
633  private static readonly ExecuteEvents.EventFunction<IHoldHandler> OnHoldCanceledEventHandler =
634  delegate (IHoldHandler handler, BaseEventData eventData)
635  {
636  HoldEventData casted = ExecuteEvents.ValidateEventData<HoldEventData>(eventData);
637  handler.OnHoldCanceled(casted);
638  };
639 
640  public void RaiseHoldCanceled(IInputSource source, uint sourceId, object[] tags = null)
641  {
642  // Create input event
643  holdEventData.Initialize(source, sourceId, tags);
644 
645  // Pass handler through HandleEvent to perform modal/fallback logic
646  HandleEvent(holdEventData, OnHoldCanceledEventHandler);
647  }
648 
649  #endregion // Hold Events
650 
651  #region Navigation Events
652 
653  private static readonly ExecuteEvents.EventFunction<INavigationHandler> OnNavigationStartedEventHandler =
654  delegate (INavigationHandler handler, BaseEventData eventData)
655  {
656  NavigationEventData casted = ExecuteEvents.ValidateEventData<NavigationEventData>(eventData);
657  handler.OnNavigationStarted(casted);
658  };
659 
660  public void RaiseNavigationStarted(IInputSource source, uint sourceId, object[] tags = null)
661  {
662  // Create input event
663  navigationEventData.Initialize(source, sourceId, tags, Vector3.zero);
664 
665  // Pass handler through HandleEvent to perform modal/fallback logic
666  HandleEvent(navigationEventData, OnNavigationStartedEventHandler);
667  }
668 
669  private static readonly ExecuteEvents.EventFunction<INavigationHandler> OnNavigationUpdatedEventHandler =
670  delegate (INavigationHandler handler, BaseEventData eventData)
671  {
672  NavigationEventData casted = ExecuteEvents.ValidateEventData<NavigationEventData>(eventData);
673  handler.OnNavigationUpdated(casted);
674  };
675 
676  public void RaiseNavigationUpdated(IInputSource source, uint sourceId, Vector3 normalizedOffset, object[] tags = null)
677  {
678  // Create input event
679  navigationEventData.Initialize(source, sourceId, tags, normalizedOffset);
680 
681  // Pass handler through HandleEvent to perform modal/fallback logic
682  HandleEvent(navigationEventData, OnNavigationUpdatedEventHandler);
683  }
684 
685  private static readonly ExecuteEvents.EventFunction<INavigationHandler> OnNavigationCompletedEventHandler =
686  delegate (INavigationHandler handler, BaseEventData eventData)
687  {
688  NavigationEventData casted = ExecuteEvents.ValidateEventData<NavigationEventData>(eventData);
689  handler.OnNavigationCompleted(casted);
690  };
691 
692  public void RaiseNavigationCompleted(IInputSource source, uint sourceId, Vector3 normalizedOffset, object[] tags = null)
693  {
694  // Create input event
695  navigationEventData.Initialize(source, sourceId, tags, normalizedOffset);
696 
697  // Pass handler through HandleEvent to perform modal/fallback logic
698  HandleEvent(navigationEventData, OnNavigationCompletedEventHandler);
699  }
700 
701  private static readonly ExecuteEvents.EventFunction<INavigationHandler> OnNavigationCanceledEventHandler =
702  delegate (INavigationHandler handler, BaseEventData eventData)
703  {
704  NavigationEventData casted = ExecuteEvents.ValidateEventData<NavigationEventData>(eventData);
705  handler.OnNavigationCanceled(casted);
706  };
707 
708  public void RaiseNavigationCanceled(IInputSource source, uint sourceId, object[] tags = null)
709  {
710  // Create input event
711  navigationEventData.Initialize(source, sourceId, tags, Vector3.zero);
712 
713  // Pass handler through HandleEvent to perform modal/fallback logic
714  HandleEvent(navigationEventData, OnNavigationCanceledEventHandler);
715  }
716 
717  #endregion // Navigation Events
718 
719  #region Controller Events
720 
721  private static readonly ExecuteEvents.EventFunction<IControllerInputHandler> OnInputPositionChangedEventHandler =
722  delegate (IControllerInputHandler handler, BaseEventData eventData)
723  {
724  InputPositionEventData casted = ExecuteEvents.ValidateEventData<InputPositionEventData>(eventData);
725  handler.OnInputPositionChanged(casted);
726  };
727 
728  public void RaiseInputPositionChanged(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, Vector2 position, object[] tags = null)
729  {
730  // Create input event
731  inputPositionEventData.Initialize(source, sourceId, tags, pressType, position);
732 
733  // Pass handler through HandleEvent to perform modal/fallback logic
734  HandleEvent(inputPositionEventData, OnInputPositionChangedEventHandler);
735  }
736 
737  private static readonly ExecuteEvents.EventFunction<ISelectHandler> OnSelectPressedAmountChangedEventHandler =
738  delegate (ISelectHandler handler, BaseEventData eventData)
739  {
740  SelectPressedEventData casted = ExecuteEvents.ValidateEventData<SelectPressedEventData>(eventData);
741  handler.OnSelectPressedAmountChanged(casted);
742  };
743 
744  public void RaiseSelectPressedAmountChanged(IInputSource source, uint sourceId, double pressedAmount, object[] tags = null)
745  {
746  // Create input event
747  selectPressedEventData.Initialize(source, sourceId, tags, pressedAmount);
748 
749  // Pass handler through HandleEvent to perform modal/fallback logic
750  HandleEvent(selectPressedEventData, OnSelectPressedAmountChangedEventHandler);
751  }
752 
753  private static readonly ExecuteEvents.EventFunction<IControllerTouchpadHandler> OnTouchpadTouchedEventHandler =
754  delegate (IControllerTouchpadHandler handler, BaseEventData eventData)
755  {
756  InputEventData casted = ExecuteEvents.ValidateEventData<InputEventData>(eventData);
757  handler.OnTouchpadTouched(casted);
758  };
759 
760  public void RaiseTouchpadTouched(IInputSource source, uint sourceId, object[] tags = null)
761  {
762  // Create input event
763  inputEventData.Initialize(source, sourceId, tags, InteractionSourcePressInfo.Touchpad);
764 
765  // Pass handler through HandleEvent to perform modal/fallback logic
766  HandleEvent(inputEventData, OnTouchpadTouchedEventHandler);
767  }
768 
769  private static readonly ExecuteEvents.EventFunction<IControllerTouchpadHandler> OnTouchpadReleasedEventHandler =
770  delegate (IControllerTouchpadHandler handler, BaseEventData eventData)
771  {
772  InputEventData casted = ExecuteEvents.ValidateEventData<InputEventData>(eventData);
773  handler.OnTouchpadReleased(casted);
774  };
775 
776  public void RaiseTouchpadReleased(IInputSource source, uint sourceId, object[] tags = null)
777  {
778  // Create input event
779  inputEventData.Initialize(source, sourceId, tags, InteractionSourcePressInfo.Touchpad);
780 
781  // Pass handler through HandleEvent to perform modal/fallback logic
782  HandleEvent(inputEventData, OnTouchpadReleasedEventHandler);
783  }
784 
785  private static readonly ExecuteEvents.EventFunction<ISourcePositionHandler> OnSourcePositionChangedEventHandler =
786  delegate (ISourcePositionHandler handler, BaseEventData eventData)
787  {
788  SourcePositionEventData casted = ExecuteEvents.ValidateEventData<SourcePositionEventData>(eventData);
789  handler.OnPositionChanged(casted);
790  };
791 
792  public void RaiseSourcePositionChanged(IInputSource source, uint sourceId, Vector3 pointerPosition, Vector3 gripPosition, object[] tags = null)
793  {
794  // Create input event
795  sourcePositionEventData.Initialize(source, sourceId, tags, pointerPosition, gripPosition);
796 
797  // Pass handler through HandleEvent to perform modal/fallback logic
798  HandleEvent(sourcePositionEventData, OnSourcePositionChangedEventHandler);
799  }
800 
801  private static readonly ExecuteEvents.EventFunction<ISourceRotationHandler> OnSourceRotationChangedEventHandler =
802  delegate (ISourceRotationHandler handler, BaseEventData eventData)
803  {
804  SourceRotationEventData casted = ExecuteEvents.ValidateEventData<SourceRotationEventData>(eventData);
805  handler.OnRotationChanged(casted);
806  };
807 
808  public void RaiseSourceRotationChanged(IInputSource source, uint sourceId, Quaternion pointerRotation, Quaternion gripRotation, object[] tags = null)
809  {
810  // Create input event
811  sourceRotationEventData.Initialize(source, sourceId, tags, pointerRotation, gripRotation);
812 
813  // Pass handler through HandleEvent to perform modal/fallback logic
814  HandleEvent(sourceRotationEventData, OnSourceRotationChangedEventHandler);
815  }
816 
817  #endregion // Controller Events
818 
819  [Obsolete("Use RaiseSourceDetected")]
820  public void RaiseGamePadDetected(IInputSource source, uint sourceId, string gamePadName)
821  {
822  }
823 
824  [Obsolete("Use RaiseSourceLost")]
825  public void RaiseGamePadLost(IInputSource source, uint sourceId, string gamePadName)
826  {
827  }
828 
829  #region Xbox Controller Events
830 
831  private static readonly ExecuteEvents.EventFunction<IXboxControllerHandler> OnXboxInputUpdateHandler =
832  delegate (IXboxControllerHandler handler, BaseEventData eventData)
833  {
834  var casted = ExecuteEvents.ValidateEventData<XboxControllerEventData>(eventData);
835  handler.OnXboxInputUpdate(casted);
836  };
837 
838  public void RaiseXboxInputUpdate(IInputSource source, uint sourceId, XboxControllerData inputData)
839  {
840  // Create input event
841  xboxControllerEventData.Initialize(source, sourceId, inputData);
842 
843  // Pass handler through HandleEvent to perform modal/fallback logic
844  HandleEvent(xboxControllerEventData, OnXboxInputUpdateHandler);
845  }
846 
847  #endregion // Xbox Controller Events
848 
849  #region Bounding Box Rig Activity Events
850  private static readonly ExecuteEvents.EventFunction<IBoundingBoxStateHandler> OnBoundingBoxRigActivatedEventHandler =
851  delegate (IBoundingBoxStateHandler handler, BaseEventData eventData)
852  {
853  BoundingBoxEventData casted = ExecuteEvents.ValidateEventData<BoundingBoxEventData>(eventData);
854  handler.OnBoundingBoxRigActivated(casted);
855  };
856 
857  public void RaiseBoundingBoxRigActivated(GameObject boundingBoxRiggedObject)
858  {
859  // Create input event
860  boundingBoxActivityEventData.Initialize(boundingBoxRiggedObject);
861 
862  // Pass to the handler through HandleEvent to perform the fallback logic
863  HandleEvent(boundingBoxActivityEventData, OnBoundingBoxRigActivatedEventHandler);
864  }
865 
866  private static readonly ExecuteEvents.EventFunction<IBoundingBoxStateHandler> OnBoundingBoxRigDeactivatedEventHandler =
867  delegate (IBoundingBoxStateHandler handler, BaseEventData eventData)
868  {
869  BoundingBoxEventData casted = ExecuteEvents.ValidateEventData<BoundingBoxEventData>(eventData);
870  handler.OnBoundingBoxRigDeactivated(casted);
871  };
872 
873  public void RaiseBoundingBoxRigDeactivated(GameObject boundingBoxRiggedObject)
874  {
875  // Create input event
876  boundingBoxActivityEventData.Initialize(boundingBoxRiggedObject);
877 
878  // Pass to the handler through HandleEvent to perform the fallback logic
879  HandleEvent(boundingBoxActivityEventData, OnBoundingBoxRigDeactivatedEventHandler);
880  }
881  #endregion // Bounding Box Rig Activity Events
882 
883 #if UNITY_WSA || UNITY_STANDALONE_WIN
884  #region Speech Events
885 
886  private static readonly ExecuteEvents.EventFunction<ISpeechHandler> OnSpeechKeywordRecognizedEventHandler =
887  delegate (ISpeechHandler handler, BaseEventData eventData)
888  {
889  SpeechEventData casted = ExecuteEvents.ValidateEventData<SpeechEventData>(eventData);
890  handler.OnSpeechKeywordRecognized(casted);
891  };
892 
893  public void RaiseSpeechKeywordPhraseRecognized(IInputSource source, uint sourceId, ConfidenceLevel confidence, TimeSpan phraseDuration, DateTime phraseStartTime, SemanticMeaning[] semanticMeanings, string text, object[] tags = null)
894  {
895  // Create input event
896  speechEventData.Initialize(source, sourceId, tags, confidence, phraseDuration, phraseStartTime, semanticMeanings, text);
897 
898  // Pass handler through HandleEvent to perform modal/fallback logic
899  HandleEvent(speechEventData, OnSpeechKeywordRecognizedEventHandler);
900  }
901 
902  #endregion // Speech Events
903 
904  #region Dictation Events
905 
906  private static readonly ExecuteEvents.EventFunction<IDictationHandler> OnDictationHypothesisEventHandler =
907  delegate (IDictationHandler handler, BaseEventData eventData)
908  {
909  DictationEventData casted = ExecuteEvents.ValidateEventData<DictationEventData>(eventData);
910  handler.OnDictationHypothesis(casted);
911  };
912 
913  public void RaiseDictationHypothesis(IInputSource source, uint sourceId, string dictationHypothesis, AudioClip dictationAudioClip = null, object[] tags = null)
914  {
915  // Create input event
916  dictationEventData.Initialize(source, sourceId, tags, dictationHypothesis, dictationAudioClip);
917 
918  // Pass handler through HandleEvent to perform modal/fallback logic
919  HandleEvent(dictationEventData, OnDictationHypothesisEventHandler);
920  }
921 
922  private static readonly ExecuteEvents.EventFunction<IDictationHandler> OnDictationResultEventHandler =
923  delegate (IDictationHandler handler, BaseEventData eventData)
924  {
925  DictationEventData casted = ExecuteEvents.ValidateEventData<DictationEventData>(eventData);
926  handler.OnDictationResult(casted);
927  };
928 
929  public void RaiseDictationResult(IInputSource source, uint sourceId, string dictationResult, AudioClip dictationAudioClip = null, object[] tags = null)
930  {
931  // Create input event
932  dictationEventData.Initialize(source, sourceId, tags, dictationResult, dictationAudioClip);
933 
934  // Pass handler through HandleEvent to perform modal/fallback logic
935  HandleEvent(dictationEventData, OnDictationResultEventHandler);
936  }
937 
938  private static readonly ExecuteEvents.EventFunction<IDictationHandler> OnDictationCompleteEventHandler =
939  delegate (IDictationHandler handler, BaseEventData eventData)
940  {
941  DictationEventData casted = ExecuteEvents.ValidateEventData<DictationEventData>(eventData);
942  handler.OnDictationComplete(casted);
943  };
944 
945  public void RaiseDictationComplete(IInputSource source, uint sourceId, string dictationResult, AudioClip dictationAudioClip, object[] tags = null)
946  {
947  // Create input event
948  dictationEventData.Initialize(source, sourceId, tags, dictationResult, dictationAudioClip);
949 
950  // Pass handler through HandleEvent to perform modal/fallback logic
951  HandleEvent(dictationEventData, OnDictationCompleteEventHandler);
952  }
953 
954  private static readonly ExecuteEvents.EventFunction<IDictationHandler> OnDictationErrorEventHandler =
955  delegate (IDictationHandler handler, BaseEventData eventData)
956  {
957  DictationEventData casted = ExecuteEvents.ValidateEventData<DictationEventData>(eventData);
958  handler.OnDictationError(casted);
959  };
960 
961  public void RaiseDictationError(IInputSource source, uint sourceId, string dictationResult, AudioClip dictationAudioClip = null, object[] tags = null)
962  {
963  // Create input event
964  dictationEventData.Initialize(source, sourceId, tags, dictationResult, dictationAudioClip);
965 
966  // Pass handler through HandleEvent to perform modal/fallback logic
967  HandleEvent(dictationEventData, OnDictationErrorEventHandler);
968  }
969 
970  #endregion // Dictation Events
971 #endif
972 
973  #region Helpers
974 
975  private static void AddSource(IInputSource source, uint sourceId)
976  {
977  bool alreadyDetected = false;
978 
979  for (int i = 0; i < detectedInputSources.Count; i++)
980  {
981  if (detectedInputSources[i].Matches(source, sourceId))
982  {
983  alreadyDetected = true;
984  break;
985  }
986  }
987 
988  if (!alreadyDetected)
989  {
990  detectedInputSources.Add(new InputSourceInfo(source, sourceId));
991  }
992  }
993 
994  private static void RemoveSource(IInputSource source, uint sourceId)
995  {
996  for (int iDetected = 0; iDetected < detectedInputSources.Count; iDetected++)
997  {
998  if (detectedInputSources[iDetected].Matches(source, sourceId))
999  {
1000  detectedInputSources.RemoveAt(iDetected);
1001  break;
1002  }
1003  }
1004  }
1005 
1006  #endregion
1007  }
1008 }
void Initialize(GameObject boundingBoxRiggedObject)
Describes activity of a bounding box rig events.
void PushModalInputHandler(GameObject inputHandler)
Push a game object into the modal input stack. Any input handlers on the game object are given priori...
Definition: InputManager.cs:87
void Initialize(IInputSource inputSource, uint sourceId, object tag, Quaternion pointerRotation, Quaternion gripRotation)
void RaiseFocusEnter(GameObject focusedObject)
Raise the event OnFocusEnter to the game object when focus enters it.
void OnNavigationCanceled(NavigationEventData eventData)
void OnManipulationStarted(ManipulationEventData eventData)
void OnPositionChanged(SourcePositionEventData eventData)
void RaiseSourceLost(IInputSource source, uint sourceId, object[] tags=null)
void RaiseManipulationCompleted(IInputSource source, uint sourceId, Vector3 cumulativeDelta, object[] tags=null)
void Initialize(IInputSource inputSource, uint sourceId, object tag)
Describes a Unity pointer event that was generated by a specific input source and ID...
Input Manager is responsible for managing input sources and dispatching relevant events to the approp...
Definition: InputManager.cs:19
Interface to implement to react to per-pointer focus enter/exit.
void OnSourceLost(SourceStateEventData eventData)
void OnNavigationStarted(NavigationEventData eventData)
InputSourceInfo gives you the input source like hands or motion controller. It will also report the s...
void OnSpeechKeywordRecognized(SpeechEventData eventData)
Interface to implement reacting to bounding box rig&#39;s activation or deactivation. ...
void OnSelectPressedAmountChanged(SelectPressedEventData eventData)
void OnFocusExit(PointerSpecificEventData eventData)
void OnDictationError(DictationEventData eventData)
void ClearFallbackInputStack()
Clear all fallback input handlers off the stack.
void OnRotationChanged(SourceRotationEventData eventData)
override void Awake()
Base Awake method that sets the Singleton&#39;s unique instance. Called by Unity when initializing a Mono...
void RaiseTouchpadTouched(IInputSource source, uint sourceId, object[] tags=null)
Describes an input event that involves content manipulation.
void RaiseNavigationUpdated(IInputSource source, uint sourceId, Vector3 normalizedOffset, object[] tags=null)
Interface to implement to react to navigation gestures.
void ClearInputDisableStack()
Clear the input disable stack, which will immediately re-enable input.
void Initialize(IInputSource inputSource, uint sourceId, object tag, Vector3 pointerPosition, Vector3 gripPosition)
void PushInputDisable()
Push a disabled input state onto the input manager. While input is disabled no events will be sent ou...
void PopModalInputHandler()
Remove the last game object from the modal input stack.
Definition: InputManager.cs:95
Describes an input event that a source moving.
void OnDictationResult(DictationEventData eventData)
void RaiseSourceRotationChanged(IInputSource source, uint sourceId, Quaternion pointerRotation, Quaternion gripRotation, object[] tags=null)
Interface to implement to react to select pressed changes.
void PopFallbackInputHandler()
Remove the last game object from the fallback input stack.
void Initialize(IInputSource inputSource, uint sourceId, object tag, Vector3 normalizedOffset)
void OnDictationComplete(DictationEventData eventData)
void Initialize(IInputSource inputSource, uint sourceId, object tag, string dictationResult, AudioClip dictationAudioClip=null)
void OnSourceDetected(SourceStateEventData eventData)
void OnHoldCompleted(HoldEventData eventData)
void RaiseHoldStarted(IInputSource source, uint sourceId, object[] tags=null)
void OnInputClicked(InputClickedEventData eventData)
void Initialize(IInputSource inputSource, uint sourceId, object tag, InteractionSourcePressInfo pressType, int tapCount)
void PushFallbackInputHandler(GameObject inputHandler)
Push a game object into the fallback input stack. Any input handlers on the game object are given inp...
void ClearModalInputStack()
Clear all modal input handlers off the stack.
Interface to implement to react to controller input changes.
void Initialize(IInputSource inputSource, uint sourceId, object tag, InteractionSourcePressInfo pressType, Vector2 position)
Data class that carries the input data for the event handler.
Interface to implement to react to source position changes.
void RaiseXboxInputUpdate(IInputSource source, uint sourceId, XboxControllerData inputData)
void RaiseBoundingBoxRigDeactivated(GameObject boundingBoxRiggedObject)
void OnHoldCanceled(HoldEventData eventData)
void OnManipulationUpdated(ManipulationEventData eventData)
Interface to implement to react to touchpad controls.
Event dispatched associated with a specific pointer.
Interface to implement dictation events.
void OnXboxInputUpdate(XboxControllerEventData eventData)
void Initialize(IInputSource inputSource, uint sourceId, XboxControllerData inputData, object tag=null)
void OnInputUp(InputEventData eventData)
void RaiseFocusExit(GameObject deFocusedObject)
Raise the event OnFocusExit to the game object when focus exists it.
Interface to implement to react to simple click input.
void OnDictationHypothesis(DictationEventData eventData)
void Initialize(IInputSource inputSource, uint sourceId, object tag)
void RaiseHoldCompleted(IInputSource source, uint sourceId, object[] tags=null)
Describes an input event that involves a select press.
void RaiseManipulationCanceled(IInputSource source, uint sourceId, object[] tags=null)
void RaiseInputPositionChanged(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, Vector2 position, object[] tags=null)
void Initialize(IInputSource inputSource, uint sourceId, object tag, double pressedAmount)
static T Instance
Returns the Singleton instance of the classes type. If no instance is found, then we search for an in...
Definition: Singleton.cs:26
void RaiseManipulationUpdated(IInputSource source, uint sourceId, Vector3 cumulativeDelta, object[] tags=null)
void RaiseSourcePositionChanged(IInputSource source, uint sourceId, Vector3 pointerPosition, Vector3 gripPosition, object[] tags=null)
void RaiseSourceUp(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, object[] tags=null)
void OnHoldStarted(HoldEventData eventData)
void OnInputPositionChanged(InputPositionEventData eventData)
Describes an input event that involves content navigation.
Interface to implement to react to hold gestures.
Definition: IHoldHandler.cs:11
void RemoveGlobalListener(GameObject listener)
Removes a global listener.
void RaiseGamePadLost(IInputSource source, uint sourceId, string gamePadName)
void RaiseSelectPressedAmountChanged(IInputSource source, uint sourceId, double pressedAmount, object[] tags=null)
void RaiseManipulationStarted(IInputSource source, uint sourceId, object[] tags=null)
Interface for an input source. An input source can be anything that a user can use to interact with a...
Definition: IInputSource.cs:12
Interface to implement to react to source state changes, such as when an input source is detected or ...
Interface to implement to react to focus enter/exit.
Definition: IFocusable.cs:11
void OnFocusEnter(PointerSpecificEventData eventData)
Describes an input event that involves keyword recognition.
Describes an input event that involves a source&#39;s rotation changing.
void PopInputDisable()
Pop disabled input state. When the last disabled state is popped off the stack input will be re-enabl...
void AddGlobalListener(GameObject listener)
Adds a global listener that will receive all input events, regardless of which other game objects mig...
Interface to implement to react to speech recognition.
Focus manager is the bridge that handles different types of pointing sources like gaze cursor or poin...
Definition: FocusManager.cs:16
void RaiseNavigationCompleted(IInputSource source, uint sourceId, Vector3 normalizedOffset, object[] tags=null)
void RaiseHoldCanceled(IInputSource source, uint sourceId, object[] tags=null)
Describes an input event that involves a tap.
void RaiseBoundingBoxRigActivated(GameObject boundingBoxRiggedObject)
Interface to implement to react to simple pointer-like input.
Implement this interface to register your pointer as a pointing source. This could be gaze based or m...
void OnBoundingBoxRigDeactivated(BoundingBoxEventData eventData)
void OnBoundingBoxRigActivated(BoundingBoxEventData eventData)
void RaiseSourceDetected(IInputSource source, uint sourceId, object[] tags=null)
void OnNavigationUpdated(NavigationEventData eventData)
Describes an source state event that has a source id.
void RaiseSourceDown(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, object[] tags=null)
void RaiseGamePadDetected(IInputSource source, uint sourceId, string gamePadName)
void Initialize(IInputSource inputSource, uint sourceId, object tag, Vector3 cumulativeDelta)
Event dispatched when a hold gesture is detected.
void OnManipulationCanceled(ManipulationEventData eventData)
void Initialize(IInputSource inputSource, uint sourceId, object tag, InteractionSourcePressInfo pressType)
Describes an input event that has a source id and a press kind.
void RaisePointerSpecificFocusChangedEvents(IPointingSource pointer, GameObject oldFocusedObject, GameObject newFocusedObject)
Raise focus enter and exit events for when an input (that supports pointing) points to a game object...
void OnInputDown(InputEventData eventData)
void RaiseTouchpadReleased(IInputSource source, uint sourceId, object[] tags=null)
void RaiseNavigationStarted(IInputSource source, uint sourceId, object[] tags=null)
Interface to implement to react to source rotation changes.
void RaiseNavigationCanceled(IInputSource source, uint sourceId, object[] tags=null)
void RaiseInputClicked(IInputSource source, uint sourceId, InteractionSourcePressInfo pressType, int tapCount, object[] tags=null)
static bool IsInitialized
Returns whether the instance has been initialized or not.
Definition: Singleton.cs:58
void OnManipulationCompleted(ManipulationEventData eventData)
Singleton behaviour class, used for components that should only have one instance.
Definition: Singleton.cs:14
Interface to implement to react to manipulation gestures.
void OnNavigationCompleted(NavigationEventData eventData)