Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
7.9 KiB

  1. // Touchpad Control|Locomotion|20070
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. /// <summary>
  6. /// Provides the ability to control a GameObject's position based on the position of the controller touchpad axis.
  7. /// </summary>
  8. /// <remarks>
  9. /// > This script forms the stub of emitting the touchpad axis X and Y changes that are then digested by the corresponding Object Control Actions that are listening for the relevant event.
  10. ///
  11. /// **Required Components:**
  12. /// * `VRTK_ControllerEvents` - The Controller Events script to listen for the touchpad events on.
  13. ///
  14. /// **Optional Components:**
  15. /// * `VRTK_BodyPhysics` - The Body Physics script to utilise to determine if falling is occuring.
  16. ///
  17. /// **Script Usage:**
  18. /// * Place the `VRTK_TouchpadControl` script on either:
  19. /// * The GameObject with the Controller Events script.
  20. /// * Any other scene GameObject and provide a valid `VRTK_ControllerEvents` component to the `Controller` parameter of this script.
  21. /// * Place a corresponding Object Control Action for the Touchpad Control script to notify of touchpad changes. Without a corresponding Object Control Action, the Touchpad Control script will do nothing.
  22. /// </remarks>
  23. /// <example>
  24. /// `VRTK/Examples/017_CameraRig_TouchpadWalking` has a collection of walls and slopes that can be traversed by the user with the touchpad. There is also an area that can only be traversed if the user is crouching.
  25. /// </example>
  26. [AddComponentMenu("VRTK/Scripts/Locomotion/VRTK_TouchpadControl")]
  27. public class VRTK_TouchpadControl : VRTK_ObjectControl
  28. {
  29. [Header("Touchpad Control Settings")]
  30. [Tooltip("The axis to use for the direction coordinates.")]
  31. public VRTK_ControllerEvents.Vector2AxisAlias coordinateAxis = VRTK_ControllerEvents.Vector2AxisAlias.Touchpad;
  32. [Tooltip("An optional button that has to be engaged to allow the touchpad control to activate.")]
  33. public VRTK_ControllerEvents.ButtonAlias primaryActivationButton = VRTK_ControllerEvents.ButtonAlias.TouchpadTouch;
  34. [Tooltip("An optional button that when engaged will activate the modifier on the touchpad control action.")]
  35. public VRTK_ControllerEvents.ButtonAlias actionModifierButton = VRTK_ControllerEvents.ButtonAlias.TouchpadPress;
  36. [Tooltip("A deadzone threshold on the touchpad that will ignore input if the touch position is within the specified deadzone. Between `0f` and `1f`.")]
  37. public Vector2 axisDeadzone = new Vector2(0.2f, 0.2f);
  38. protected bool touchpadFirstChange;
  39. protected bool otherTouchpadControlEnabledState;
  40. protected bool otherTouchpadControlEnabledStateSet;
  41. protected VRTK_ControllerEvents.ButtonAlias coordniateButtonAlias;
  42. protected override void OnEnable()
  43. {
  44. base.OnEnable();
  45. touchpadFirstChange = true;
  46. otherTouchpadControlEnabledStateSet = false;
  47. coordniateButtonAlias = (coordinateAxis == VRTK_ControllerEvents.Vector2AxisAlias.Touchpad ? VRTK_ControllerEvents.ButtonAlias.TouchpadTouch : VRTK_ControllerEvents.ButtonAlias.TouchpadTwoTouch);
  48. }
  49. protected override void ControlFixedUpdate()
  50. {
  51. ModifierButtonActive();
  52. if (OutsideDeadzone(currentAxis.x, axisDeadzone.x) || currentAxis.x == 0f)
  53. {
  54. OnXAxisChanged(SetEventArguements(directionDevice.right, currentAxis.x, axisDeadzone.x));
  55. }
  56. if (OutsideDeadzone(currentAxis.y, axisDeadzone.y) || currentAxis.y == 0f)
  57. {
  58. OnYAxisChanged(SetEventArguements(directionDevice.forward, currentAxis.y, axisDeadzone.y));
  59. }
  60. }
  61. protected override VRTK_ObjectControl GetOtherControl()
  62. {
  63. GameObject foundController = (VRTK_DeviceFinder.IsControllerLeftHand(gameObject) ? VRTK_DeviceFinder.GetControllerRightHand(false) : VRTK_DeviceFinder.GetControllerLeftHand(false));
  64. if (foundController != null)
  65. {
  66. return foundController.GetComponentInChildren<VRTK_TouchpadControl>();
  67. }
  68. return null;
  69. }
  70. protected override void SetListeners(bool state)
  71. {
  72. if (controllerEvents != null)
  73. {
  74. if (state)
  75. {
  76. switch (coordinateAxis)
  77. {
  78. case VRTK_ControllerEvents.Vector2AxisAlias.Touchpad:
  79. controllerEvents.TouchpadAxisChanged += TouchpadAxisChanged;
  80. controllerEvents.TouchpadTouchEnd += TouchpadTouchEnd;
  81. break;
  82. case VRTK_ControllerEvents.Vector2AxisAlias.TouchpadTwo:
  83. controllerEvents.TouchpadTwoAxisChanged += TouchpadAxisChanged;
  84. controllerEvents.TouchpadTwoTouchEnd += TouchpadTouchEnd;
  85. break;
  86. }
  87. }
  88. else
  89. {
  90. switch (coordinateAxis)
  91. {
  92. case VRTK_ControllerEvents.Vector2AxisAlias.Touchpad:
  93. controllerEvents.TouchpadAxisChanged -= TouchpadAxisChanged;
  94. controllerEvents.TouchpadTouchEnd -= TouchpadTouchEnd;
  95. break;
  96. case VRTK_ControllerEvents.Vector2AxisAlias.TouchpadTwo:
  97. controllerEvents.TouchpadTwoAxisChanged -= TouchpadAxisChanged;
  98. controllerEvents.TouchpadTwoTouchEnd -= TouchpadTouchEnd;
  99. break;
  100. }
  101. }
  102. }
  103. }
  104. protected override bool IsInAction()
  105. {
  106. return (ValidPrimaryButton() && TouchpadTouched());
  107. }
  108. protected virtual bool OutsideDeadzone(float axisValue, float deadzoneThreshold)
  109. {
  110. return (axisValue > deadzoneThreshold || axisValue < -deadzoneThreshold);
  111. }
  112. protected virtual bool ValidPrimaryButton()
  113. {
  114. return (controllerEvents != null && (primaryActivationButton == VRTK_ControllerEvents.ButtonAlias.Undefined || controllerEvents.IsButtonPressed(primaryActivationButton)));
  115. }
  116. protected virtual void ModifierButtonActive()
  117. {
  118. modifierActive = (controllerEvents != null && actionModifierButton != VRTK_ControllerEvents.ButtonAlias.Undefined && controllerEvents.IsButtonPressed(actionModifierButton));
  119. }
  120. protected virtual bool TouchpadTouched()
  121. {
  122. return (controllerEvents != null && controllerEvents.IsButtonPressed(coordniateButtonAlias));
  123. }
  124. protected virtual void TouchpadAxisChanged(object sender, ControllerInteractionEventArgs e)
  125. {
  126. Vector2 actualAxis = (coordinateAxis == VRTK_ControllerEvents.Vector2AxisAlias.Touchpad ? e.touchpadAxis : e.touchpadTwoAxis);
  127. if (touchpadFirstChange && otherObjectControl != null && disableOtherControlsOnActive && actualAxis != Vector2.zero)
  128. {
  129. otherTouchpadControlEnabledState = otherObjectControl.enabled;
  130. otherTouchpadControlEnabledStateSet = true;
  131. otherObjectControl.enabled = false;
  132. }
  133. currentAxis = (ValidPrimaryButton() ? actualAxis : Vector2.zero);
  134. if (currentAxis != Vector2.zero)
  135. {
  136. touchpadFirstChange = false;
  137. }
  138. }
  139. protected virtual void TouchpadTouchEnd(object sender, ControllerInteractionEventArgs e)
  140. {
  141. if (otherTouchpadControlEnabledStateSet && otherObjectControl != null && disableOtherControlsOnActive)
  142. {
  143. otherObjectControl.enabled = otherTouchpadControlEnabledState;
  144. }
  145. currentAxis = Vector2.zero;
  146. touchpadFirstChange = true;
  147. }
  148. }
  149. }