|
|
- // Height Adjust Teleport|Locomotion|20020
- namespace VRTK
- {
- using UnityEngine;
-
- /// <summary>
- /// Updates the `x/y/z` position of the SDK Camera Rig with an optional screen fade.
- /// </summary>
- /// <remarks>
- /// > The Camera Rig can be automatically teleported to the nearest floor `y` position when utilising this teleporter.
- ///
- /// **Script Usage:**
- /// * Place the `VRTK_HeightAdjustTeleport` script on any active scene GameObject.
- ///
- /// **Script Dependencies:**
- /// * An optional Destination Marker (such as a Pointer) to set the destination of the teleport location.
- /// </remarks>
- /// <example>
- /// `VRTK/Examples/007_CameraRig_HeightAdjustTeleport` has a collection of varying height objects that the user can either walk up and down or use the laser pointer to climb on top of them.
- ///
- /// `VRTK/Examples/010_CameraRig_TerrainTeleporting` shows how the teleportation of a user can also traverse terrain colliders.
- ///
- /// `VRTK/Examples/020_CameraRig_MeshTeleporting` shows how the teleportation of a user can also traverse mesh colliders.
- /// </example>
- [AddComponentMenu("VRTK/Scripts/Locomotion/VRTK_HeightAdjustTeleport")]
- public class VRTK_HeightAdjustTeleport : VRTK_BasicTeleport
- {
- [Header("Height Adjust Settings")]
-
- [Tooltip("If this is checked, then the teleported Y position will snap to the nearest available below floor. If it is unchecked, then the teleported Y position will be where ever the destination Y position is.")]
- public bool snapToNearestFloor = true;
- [Tooltip("If this is checked then the teleported Y position will also be offset by the play area parent Transform Y position (if the play area has a parent).")]
- public bool applyPlayareaParentOffset = false;
- [Tooltip("A custom raycaster to use when raycasting to find floors.")]
- public VRTK_CustomRaycast customRaycast;
-
- protected override void OnEnable()
- {
- base.OnEnable();
- adjustYForTerrain = true;
- AdjustForParentOffset();
- }
-
- protected override void OnDisable()
- {
- base.OnDisable();
- }
-
- protected override Vector3 GetNewPosition(Vector3 tipPosition, Transform target, bool returnOriginalPosition)
- {
- Vector3 basePosition = base.GetNewPosition(tipPosition, target, returnOriginalPosition);
- if (!returnOriginalPosition)
- {
- basePosition.y = GetTeleportY(target, tipPosition);
- }
- return basePosition;
- }
-
- protected virtual void AdjustForParentOffset()
- {
- if (snapToNearestFloor && applyPlayareaParentOffset && playArea != null && playArea.parent != null)
- {
- Ray ray = new Ray(playArea.parent.position, -playArea.up);
- RaycastHit rayCollidedWith;
- if (VRTK_CustomRaycast.Raycast(customRaycast, ray, out rayCollidedWith, Physics.IgnoreRaycastLayer, Mathf.Infinity, QueryTriggerInteraction.Ignore))
- {
- playArea.position = new Vector3(playArea.position.x, playArea.position.y + rayCollidedWith.point.y, playArea.position.z);
- }
- }
- }
-
- protected virtual float GetParentOffset()
- {
- return (applyPlayareaParentOffset && playArea.parent != null ? playArea.parent.transform.localPosition.y : 0f);
- }
-
- protected virtual float GetTeleportY(Transform target, Vector3 tipPosition)
- {
- float parentOffset = GetParentOffset();
- if (!snapToNearestFloor || !ValidRigObjects())
- {
- return tipPosition.y + parentOffset;
- }
-
- float newY = playArea.position.y;
- float heightOffset = 0.1f;
- //Check to see if the tip is on top of an object
- Vector3 rayStartPositionOffset = Vector3.up * heightOffset;
- Ray ray = new Ray(tipPosition + rayStartPositionOffset, -playArea.up);
- RaycastHit rayCollidedWith;
- if (target != null && VRTK_CustomRaycast.Raycast(customRaycast, ray, out rayCollidedWith, Physics.IgnoreRaycastLayer, Mathf.Infinity, QueryTriggerInteraction.Ignore))
- {
- newY = (tipPosition.y - rayCollidedWith.distance) + heightOffset;
- }
- return newY + parentOffset;
- }
- }
- }
|