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.

193 lines
8.0 KiB

  1. // Object Touch Auto Interact|Interactables|35050
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. using System.Collections.Generic;
  6. /// <summary>
  7. /// Allows for Interact Grab or Interact Use interactions to automatically happen upon touching an Interactable Object.
  8. /// </summary>
  9. /// <remarks>
  10. /// **Required Components:**
  11. /// * `VRTK_InteractableObject` - The Interactable Object component to detect interactions on. This must be applied on the same GameObject as this script if one is not provided via the `Interactable Object` parameter.
  12. ///
  13. /// **Script Usage:**
  14. /// * Place the `VRTK_ObjectTouchAutoInteract` script on either:
  15. /// * The GameObject of the Interactable Object to detect interactions on.
  16. /// * Any other scene GameObject and provide a valid `VRTK_InteractableObject` component to the `Interactable Object` parameter of this script.
  17. /// </remarks>
  18. [AddComponentMenu("VRTK/Scripts/Interactions/Interactables/VRTK_ObjectTouchAutoInteract")]
  19. public class VRTK_ObjectTouchAutoInteract : VRTK_InteractableListener
  20. {
  21. /// <summary>
  22. /// Situation when auto interaction can occur.
  23. /// </summary>
  24. public enum AutoInteractions
  25. {
  26. /// <summary>
  27. /// Auto interaction can never occur on touch.
  28. /// </summary>
  29. Never,
  30. /// <summary>
  31. /// Auto interaction will occur on touch even if the specified interaction button is not held down.
  32. /// </summary>
  33. NoButtonHeld,
  34. /// <summary>
  35. /// Auto interaction will only occur on touch if the specified interaction button is held down.
  36. /// </summary>
  37. ButtonHeld
  38. }
  39. [Header("Auto Grab")]
  40. [Tooltip("Determines when a grab on touch should occur.")]
  41. public AutoInteractions grabOnTouchWhen = AutoInteractions.Never;
  42. [Tooltip("After being ungrabbed, another auto grab on touch can only occur after this time.")]
  43. public float regrabDelay = 0.1f;
  44. [Tooltip("If this is checked then the grab on touch check will happen every frame and not only on the first touch of the Interactable Object.")]
  45. public bool continuousGrabCheck = false;
  46. [Header("Auto Use")]
  47. [Tooltip("Determines when a use on touch should occur.")]
  48. public AutoInteractions useOnTouchWhen = AutoInteractions.Never;
  49. [Tooltip("After being unused, another auto use on touch can only occur after this time.")]
  50. public float reuseDelay = 0.1f;
  51. [Tooltip("If this is checked then the use on touch check will happen every frame and not only on the first touch of the Interactable Object.")]
  52. public bool continuousUseCheck = false;
  53. [Header("Custom Settings")]
  54. [Tooltip("The Interactable Object that the auto interaction will occur on. If this is blank then the script must be on the same GameObject as the Interactable Object script.")]
  55. public VRTK_InteractableObject interactableObject;
  56. protected float regrabTimer;
  57. protected float reuseTimer;
  58. protected List<GameObject> touchers = new List<GameObject>();
  59. protected virtual void OnEnable()
  60. {
  61. regrabTimer = 0f;
  62. reuseTimer = 0f;
  63. touchers.Clear();
  64. EnableListeners();
  65. }
  66. protected virtual void OnDisable()
  67. {
  68. TearDownListeners();
  69. }
  70. protected virtual void Update()
  71. {
  72. if (interactableObject != null && (continuousGrabCheck || continuousUseCheck))
  73. {
  74. for (int i = 0; i < touchers.Count; i++)
  75. {
  76. if (continuousGrabCheck)
  77. {
  78. CheckGrab(touchers[i]);
  79. }
  80. if (continuousUseCheck)
  81. {
  82. CheckUse(touchers[i]);
  83. }
  84. }
  85. }
  86. }
  87. protected override bool SetupListeners(bool throwError)
  88. {
  89. interactableObject = (interactableObject != null ? interactableObject : GetComponentInParent<VRTK_InteractableObject>());
  90. if (interactableObject != null)
  91. {
  92. interactableObject.InteractableObjectTouched += InteractableObjectTouched;
  93. interactableObject.InteractableObjectUntouched += InteractableObjectUntouched;
  94. interactableObject.InteractableObjectUngrabbed += InteractableObjectUngrabbed;
  95. interactableObject.InteractableObjectUnused += InteractableObjectUnused;
  96. return true;
  97. }
  98. else if (throwError)
  99. {
  100. VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_GAMEOBJECT, "VRTK_ObjectTouchAutoInteract", "VRTK_InteractableObject", "the same or parent"));
  101. }
  102. return false;
  103. }
  104. protected override void TearDownListeners()
  105. {
  106. if (interactableObject != null)
  107. {
  108. interactableObject.InteractableObjectTouched -= InteractableObjectTouched;
  109. interactableObject.InteractableObjectUntouched -= InteractableObjectUntouched;
  110. interactableObject.InteractableObjectUngrabbed -= InteractableObjectUngrabbed;
  111. interactableObject.InteractableObjectUnused -= InteractableObjectUnused;
  112. }
  113. }
  114. protected virtual void InteractableObjectTouched(object sender, InteractableObjectEventArgs e)
  115. {
  116. ManageTouchers(e.interactingObject, true);
  117. CheckGrab(e.interactingObject);
  118. CheckUse(e.interactingObject);
  119. }
  120. protected virtual void InteractableObjectUntouched(object sender, InteractableObjectEventArgs e)
  121. {
  122. ManageTouchers(e.interactingObject, false);
  123. }
  124. protected virtual void InteractableObjectUngrabbed(object sender, InteractableObjectEventArgs e)
  125. {
  126. regrabTimer = regrabDelay + Time.time;
  127. }
  128. protected virtual void InteractableObjectUnused(object sender, InteractableObjectEventArgs e)
  129. {
  130. reuseTimer = reuseDelay + Time.time;
  131. }
  132. protected virtual void ManageTouchers(GameObject interactingObject, bool add)
  133. {
  134. if (add)
  135. {
  136. VRTK_SharedMethods.AddListValue(touchers, interactingObject, true);
  137. }
  138. else
  139. {
  140. touchers.Remove(interactingObject);
  141. }
  142. }
  143. protected virtual void CheckGrab(GameObject interactingObject)
  144. {
  145. if (grabOnTouchWhen != AutoInteractions.Never && regrabTimer < Time.time)
  146. {
  147. VRTK_InteractGrab interactGrabScript = interactingObject.GetComponentInChildren<VRTK_InteractGrab>();
  148. if (interactGrabScript != null && (grabOnTouchWhen == AutoInteractions.NoButtonHeld || (grabOnTouchWhen == AutoInteractions.ButtonHeld && interactGrabScript.IsGrabButtonPressed())))
  149. {
  150. interactGrabScript.AttemptGrab();
  151. }
  152. }
  153. }
  154. protected virtual void CheckUse(GameObject interactingObject)
  155. {
  156. if (useOnTouchWhen != AutoInteractions.Never && reuseTimer < Time.time)
  157. {
  158. VRTK_InteractUse interactUseScript = interactingObject.GetComponentInChildren<VRTK_InteractUse>();
  159. if (interactUseScript != null && (useOnTouchWhen == AutoInteractions.NoButtonHeld || (useOnTouchWhen == AutoInteractions.ButtonHeld && interactUseScript.IsUseButtonPressed())))
  160. {
  161. if (!interactableObject.holdButtonToUse && interactableObject.IsUsing())
  162. {
  163. interactableObject.ForceStopInteracting();
  164. }
  165. else
  166. {
  167. interactUseScript.AttemptUse();
  168. }
  169. }
  170. }
  171. }
  172. }
  173. }