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.

258 lines
9.8 KiB

  1. // Object Control|Locomotion|20060
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. /// <summary>
  6. /// Event Payload
  7. /// </summary>
  8. /// <param name="controlledGameObject">The GameObject that is going to be affected.</param>
  9. /// <param name="directionDevice">The device that is used for the direction.</param>
  10. /// <param name="axisDirection">The axis that is being affected.</param>
  11. /// <param name="axis">The value of the current touchpad touch point based across the axis direction.</param>
  12. /// <param name="deadzone">The value of the deadzone based across the axis direction.</param>
  13. /// <param name="currentlyFalling">Whether the controlled GameObject is currently falling.</param>
  14. /// <param name="modifierActive">Whether the modifier button is pressed.</param>
  15. public struct ObjectControlEventArgs
  16. {
  17. public GameObject controlledGameObject;
  18. public Transform directionDevice;
  19. public Vector3 axisDirection;
  20. public float axis;
  21. public float deadzone;
  22. public bool currentlyFalling;
  23. public bool modifierActive;
  24. }
  25. /// <summary>
  26. /// Event Payload
  27. /// </summary>
  28. /// <param name="sender">this object</param>
  29. /// <param name="e"><see cref="ObjectControlEventArgs"/></param>
  30. public delegate void ObjectControlEventHandler(object sender, ObjectControlEventArgs e);
  31. /// <summary>
  32. /// Provides a base that all object control locomotions can inherit from.
  33. /// </summary>
  34. /// <remarks>
  35. /// **Script Usage:**
  36. /// > This is an abstract class that is to be inherited to a concrete class that provides object control locomotion functionality, therefore this script should not be directly used.
  37. /// </remarks>
  38. public abstract class VRTK_ObjectControl : MonoBehaviour
  39. {
  40. /// <summary>
  41. /// Devices for providing direction.
  42. /// </summary>
  43. public enum DirectionDevices
  44. {
  45. /// <summary>
  46. /// The headset device.
  47. /// </summary>
  48. Headset,
  49. /// <summary>
  50. /// The left controller device.
  51. /// </summary>
  52. LeftController,
  53. /// <summary>
  54. /// The right controller device.
  55. /// </summary>
  56. RightController,
  57. /// <summary>
  58. /// The controlled object.
  59. /// </summary>
  60. ControlledObject
  61. }
  62. [Header("Control Settings")]
  63. [Tooltip("The direction that will be moved in is the direction of this device.")]
  64. public DirectionDevices deviceForDirection = DirectionDevices.Headset;
  65. [Tooltip("If this is checked then whenever the axis on the attached controller is being changed, all other object control scripts of the same type on other controllers will be disabled.")]
  66. public bool disableOtherControlsOnActive = true;
  67. [Tooltip("If a `VRTK_BodyPhysics` script is present and this is checked, then the object control will affect the play area whilst it is falling.")]
  68. public bool affectOnFalling = false;
  69. [Tooltip("An optional game object to apply the object control to. If this is blank then the PlayArea will be controlled.")]
  70. public GameObject controlOverrideObject;
  71. [Header("Custom Settings")]
  72. [Tooltip("The controller to read the controller events from. If this is blank then it will attempt to get a controller events script from the same GameObject.")]
  73. public VRTK_ControllerEvents controller;
  74. [Tooltip("An optional Body Physics script to check for potential collisions in the moving direction.")]
  75. public VRTK_BodyPhysics bodyPhysics;
  76. /// <summary>
  77. /// Emitted when the X Axis Changes.
  78. /// </summary>
  79. public event ObjectControlEventHandler XAxisChanged;
  80. /// <summary>
  81. /// Emitted when the Y Axis Changes.
  82. /// </summary>
  83. public event ObjectControlEventHandler YAxisChanged;
  84. protected VRTK_ControllerEvents controllerEvents;
  85. protected VRTK_ObjectControl otherObjectControl;
  86. protected GameObject controlledGameObject;
  87. protected GameObject setControlOverrideObject;
  88. protected Transform directionDevice;
  89. protected DirectionDevices previousDeviceForDirection;
  90. protected Vector2 currentAxis;
  91. protected Vector2 storedAxis;
  92. protected bool currentlyFalling = false;
  93. protected bool modifierActive = false;
  94. protected float controlledGameObjectPreviousY = 0f;
  95. protected float controlledGameObjectPreviousYOffset = 0.01f;
  96. public virtual void OnXAxisChanged(ObjectControlEventArgs e)
  97. {
  98. if (XAxisChanged != null)
  99. {
  100. XAxisChanged(this, e);
  101. }
  102. }
  103. public virtual void OnYAxisChanged(ObjectControlEventArgs e)
  104. {
  105. if (YAxisChanged != null)
  106. {
  107. YAxisChanged(this, e);
  108. }
  109. }
  110. protected abstract void ControlFixedUpdate();
  111. protected abstract VRTK_ObjectControl GetOtherControl();
  112. protected abstract bool IsInAction();
  113. protected abstract void SetListeners(bool state);
  114. protected virtual void Awake()
  115. {
  116. VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
  117. }
  118. protected virtual void OnEnable()
  119. {
  120. currentAxis = Vector2.zero;
  121. storedAxis = Vector2.zero;
  122. controllerEvents = (controller != null ? controller : GetComponentInParent<VRTK_ControllerEvents>());
  123. if (!controllerEvents)
  124. {
  125. VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_NOT_INJECTED, "VRTK_ObjectControl", "VRTK_ControllerEvents", "controller", "the same"));
  126. return;
  127. }
  128. SetControlledObject();
  129. bodyPhysics = (!controlOverrideObject ? (bodyPhysics != null ? bodyPhysics : FindObjectOfType<VRTK_BodyPhysics>()) : null);
  130. directionDevice = GetDirectionDevice();
  131. SetListeners(true);
  132. otherObjectControl = GetOtherControl();
  133. }
  134. protected virtual void OnDisable()
  135. {
  136. SetListeners(false);
  137. }
  138. protected virtual void OnDestroy()
  139. {
  140. VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
  141. }
  142. protected virtual void Update()
  143. {
  144. if (controlOverrideObject != setControlOverrideObject)
  145. {
  146. SetControlledObject();
  147. }
  148. }
  149. protected virtual void FixedUpdate()
  150. {
  151. CheckDirectionDevice();
  152. CheckFalling();
  153. ControlFixedUpdate();
  154. }
  155. protected virtual ObjectControlEventArgs SetEventArguements(Vector3 axisDirection, float axis, float axisDeadzone)
  156. {
  157. ObjectControlEventArgs e;
  158. e.controlledGameObject = controlledGameObject;
  159. e.directionDevice = directionDevice;
  160. e.axisDirection = axisDirection;
  161. e.axis = axis;
  162. e.deadzone = axisDeadzone;
  163. e.currentlyFalling = currentlyFalling;
  164. e.modifierActive = modifierActive;
  165. return e;
  166. }
  167. protected virtual void SetControlledObject()
  168. {
  169. Transform playArea = VRTK_DeviceFinder.PlayAreaTransform();
  170. setControlOverrideObject = controlOverrideObject;
  171. controlledGameObject = (controlOverrideObject ? controlOverrideObject : (playArea != null ? playArea.gameObject : null));
  172. if (controlledGameObject != null)
  173. {
  174. controlledGameObjectPreviousY = controlledGameObject.transform.position.y;
  175. }
  176. }
  177. protected virtual void CheckFalling()
  178. {
  179. if (bodyPhysics != null && bodyPhysics.IsFalling() && ObjectHeightChange())
  180. {
  181. if (!affectOnFalling)
  182. {
  183. if (storedAxis == Vector2.zero)
  184. {
  185. storedAxis = new Vector2(currentAxis.x, currentAxis.y);
  186. }
  187. currentAxis = Vector2.zero;
  188. }
  189. currentlyFalling = true;
  190. }
  191. if (bodyPhysics != null && !bodyPhysics.IsFalling() && currentlyFalling)
  192. {
  193. currentAxis = (IsInAction() ? storedAxis : Vector2.zero);
  194. storedAxis = Vector2.zero;
  195. currentlyFalling = false;
  196. }
  197. }
  198. protected virtual bool ObjectHeightChange()
  199. {
  200. bool heightChanged = ((controlledGameObjectPreviousY - controlledGameObjectPreviousYOffset) > controlledGameObject.transform.position.y);
  201. controlledGameObjectPreviousY = controlledGameObject.transform.position.y;
  202. return heightChanged;
  203. }
  204. protected virtual Transform GetDirectionDevice()
  205. {
  206. switch (deviceForDirection)
  207. {
  208. case DirectionDevices.ControlledObject:
  209. return controlledGameObject.transform;
  210. case DirectionDevices.Headset:
  211. return VRTK_DeviceFinder.HeadsetTransform();
  212. case DirectionDevices.LeftController:
  213. return VRTK_DeviceFinder.GetControllerLeftHand(true).transform;
  214. case DirectionDevices.RightController:
  215. return VRTK_DeviceFinder.GetControllerRightHand(true).transform;
  216. }
  217. return null;
  218. }
  219. protected virtual void CheckDirectionDevice()
  220. {
  221. if (previousDeviceForDirection != deviceForDirection)
  222. {
  223. directionDevice = GetDirectionDevice();
  224. }
  225. previousDeviceForDirection = deviceForDirection;
  226. }
  227. }
  228. }