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.

151 lines
6.6 KiB

  1. // Room Extender|Locomotion|20130
  2. namespace VRTK
  3. {
  4. using UnityEngine;
  5. /// <summary>
  6. /// Multiplies each real world step within the play area to enable further distances to be travelled in the virtual world.
  7. /// </summary>
  8. /// <remarks>
  9. /// **Script Usage:**
  10. /// * Place the `VRTK_RoomExtender` script on any active scene GameObject.
  11. ///
  12. /// **Script Dependencies:**
  13. /// * The Controller Events script on the controller Script Alias to determine when the touchpad is pressed.
  14. /// </remarks>
  15. /// <example>
  16. /// `VRTK/Examples/028_CameraRig_RoomExtender` shows how the RoomExtender script is controlled by a VRTK_RoomExtender_Controller Example script located at both controllers. Pressing the `Touchpad` on the controller activates the Room Extender. The Additional Movement Multiplier is changed based on the touch distance to the centre of the touchpad.
  17. /// </example>
  18. [AddComponentMenu("VRTK/Scripts/Locomotion/VRTK_RoomExtender")]
  19. [System.Obsolete("`VRTK_RoomExtender` has been replaced with `VRTK_StepMultiplier`. This script will be removed in a future version of VRTK.")]
  20. public class VRTK_RoomExtender : MonoBehaviour
  21. {
  22. /// <summary>
  23. /// Movement methods.
  24. /// </summary>
  25. public enum MovementFunction
  26. {
  27. /// <summary>
  28. /// Moves the head with a non-linear drift movement.
  29. /// </summary>
  30. Nonlinear,
  31. /// <summary>
  32. /// Moves the headset in a direct linear movement.
  33. /// </summary>
  34. LinearDirect
  35. }
  36. [Tooltip("This determines the type of movement used by the extender.")]
  37. public MovementFunction movementFunction = MovementFunction.LinearDirect;
  38. [Tooltip("Enables the additional movement.")]
  39. public bool additionalMovementEnabled = true;
  40. [Tooltip("If this is checked then the touchpad needs to be pressed to enable it. If this is unchecked then it is disabled by pressing the touchpad.")]
  41. public bool additionalMovementEnabledOnButtonPress = true;
  42. [Tooltip("This is the factor by which movement at the edge of the circle is amplified. `0` is no movement of the play area. Higher values simulate a bigger play area but may be too uncomfortable.")]
  43. [Range(0, 10)]
  44. public float additionalMovementMultiplier = 1.0f;
  45. [Tooltip("This is the size of the circle in which the play area is not moved and everything is normal. If it is to low it becomes uncomfortable when crouching.")]
  46. [Range(0, 5)]
  47. public float headZoneRadius = 0.25f;
  48. [Tooltip("This transform visualises the circle around the user where the play area is not moved. In the demo scene this is a cylinder at floor level. Remember to turn of collisions.")]
  49. public Transform debugTransform;
  50. [HideInInspector]
  51. public Vector3 relativeMovementOfCameraRig = new Vector3();
  52. protected Transform movementTransform;
  53. protected Transform playArea;
  54. protected Vector3 headCirclePosition;
  55. protected Vector3 lastPosition;
  56. protected Vector3 lastMovement;
  57. protected virtual void Awake()
  58. {
  59. VRTK_SDKManager.AttemptAddBehaviourToToggleOnLoadedSetupChange(this);
  60. }
  61. protected virtual void OnEnable()
  62. {
  63. movementTransform = VRTK_DeviceFinder.HeadsetTransform();
  64. if (movementTransform == null)
  65. {
  66. VRTK_Logger.Warn(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_SCENE, "VRTK_RoomExtender", "Headset Transform"));
  67. }
  68. playArea = VRTK_DeviceFinder.PlayAreaTransform();
  69. additionalMovementEnabled = !additionalMovementEnabledOnButtonPress;
  70. if (debugTransform != null)
  71. {
  72. debugTransform.localScale = new Vector3(headZoneRadius * 2, 0.01f, headZoneRadius * 2);
  73. }
  74. MoveHeadCircleNonLinearDrift();
  75. lastPosition = movementTransform.localPosition;
  76. }
  77. protected virtual void OnDestroy()
  78. {
  79. VRTK_SDKManager.AttemptRemoveBehaviourToToggleOnLoadedSetupChange(this);
  80. }
  81. protected virtual void Update()
  82. {
  83. switch (movementFunction)
  84. {
  85. case MovementFunction.Nonlinear:
  86. MoveHeadCircleNonLinearDrift();
  87. break;
  88. case MovementFunction.LinearDirect:
  89. MoveHeadCircle();
  90. break;
  91. default:
  92. break;
  93. }
  94. }
  95. protected virtual void Move(Vector3 movement)
  96. {
  97. headCirclePosition += movement;
  98. if (debugTransform != null)
  99. {
  100. debugTransform.localPosition = new Vector3(headCirclePosition.x, debugTransform.localPosition.y, headCirclePosition.z);
  101. }
  102. if (additionalMovementEnabled)
  103. {
  104. playArea.localPosition += movement * additionalMovementMultiplier;
  105. relativeMovementOfCameraRig += movement * additionalMovementMultiplier;
  106. }
  107. }
  108. protected virtual void MoveHeadCircle()
  109. {
  110. //Get the movement of the head relative to the headCircle.
  111. Vector3 circleCenterToHead = new Vector3(movementTransform.localPosition.x - headCirclePosition.x, 0, movementTransform.localPosition.z - headCirclePosition.z);
  112. //Get the direction of the head movement.
  113. UpdateLastMovement();
  114. //Checks if the head is outside of the head cirlce and moves the head circle and play area in the movementDirection.
  115. if (circleCenterToHead.sqrMagnitude > headZoneRadius * headZoneRadius && lastMovement != Vector3.zero)
  116. {
  117. //Just move like the headset moved
  118. Move(lastMovement);
  119. }
  120. }
  121. protected virtual void MoveHeadCircleNonLinearDrift()
  122. {
  123. Vector3 movement = new Vector3(movementTransform.localPosition.x - headCirclePosition.x, 0, movementTransform.localPosition.z - headCirclePosition.z);
  124. if (movement.sqrMagnitude > headZoneRadius * headZoneRadius)
  125. {
  126. Vector3 deltaMovement = movement.normalized * (movement.magnitude - headZoneRadius);
  127. Move(deltaMovement);
  128. }
  129. }
  130. protected virtual void UpdateLastMovement()
  131. {
  132. //Save the last movement
  133. lastMovement = movementTransform.localPosition - lastPosition;
  134. lastMovement.y = 0;
  135. lastPosition = movementTransform.localPosition;
  136. }
  137. }
  138. }