Skip to content

Commit

Permalink
feat(Locomotion): rename force teleport to teleport and add new method
Browse files Browse the repository at this point in the history
The `ForceTeleport` method has now been renamed to `Teleport` and a
new `ForceTeleport` method has been added that simply takes a
position and a rotation and sets the player location to those given
parameters.
  • Loading branch information
thestonefox committed Jun 23, 2017
1 parent 2b5280c commit 9a8d97f
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 31 deletions.
102 changes: 79 additions & 23 deletions Assets/VRTK/Scripts/Locomotion/VRTK_BasicTeleport.cs
Expand Up @@ -131,33 +131,46 @@ public virtual bool ValidLocation(Transform target, Vector3 destinationPosition)
}

/// <summary>
/// The ForceTeleport/1 method forces the teleport to update position without needing to listen for a Destination Marker event.
/// The Teleport/1 method calls the teleport to update position without needing to listen for a Destination Marker event.
/// </summary>
/// <param name="teleportArgs">The pseudo Destination Marker event for the teleport action.</param>
public virtual void ForceTeleport(DestinationMarkerEventArgs teleportArgs)
public virtual void Teleport(DestinationMarkerEventArgs teleportArgs)
{
DoTeleport(this, teleportArgs);
}

/// <summary>
/// The ForceTeleport/3 method forces the teleport to update position without needing to listen for a Destination Marker event.
/// The Teleport/4 method calls the teleport to update position without needing to listen for a Destination Marker event.
/// It will build a destination marker out of the provided parameters.
/// </summary>
/// <param name="target">The Transform of the destination object.</param>
/// <param name="destinationPosition">The world position to teleport to.</param>
/// <param name="destinationRotation">The world rotation to teleport to.</param>
/// <param name="forceDestinationPosition">If true then the given destination position should not be altered by anything consuming the payload.</param>
public virtual void ForceTeleport(Transform target, Vector3 destinationPosition, Quaternion? destinationRotation = null, bool forceDestinationPosition = false)
public virtual void Teleport(Transform target, Vector3 destinationPosition, Quaternion? destinationRotation = null, bool forceDestinationPosition = false)
{
DestinationMarkerEventArgs teleportArgs = new DestinationMarkerEventArgs();
teleportArgs.distance = Vector3.Distance(new Vector3(headset.position.x, playArea.position.y, headset.position.z), destinationPosition);
teleportArgs.target = target;
teleportArgs.raycastHit = new RaycastHit();
teleportArgs.destinationPosition = destinationPosition;
teleportArgs.destinationRotation = destinationRotation;
teleportArgs.forceDestinationPosition = forceDestinationPosition;
teleportArgs.enableTeleport = true;
ForceTeleport(teleportArgs);
DestinationMarkerEventArgs teleportArgs = BuildTeleportArgs(target, destinationPosition, destinationRotation, forceDestinationPosition);
Teleport(teleportArgs);
}

/// <summary>
/// The ForceTeleport method forces the position to update to a given destination and ignores any target checking or floor adjustment.
/// </summary>
/// <param name="destinationPosition">The world position to teleport to.</param>
/// <param name="destinationRotation">The world rotation to teleport to.</param>
public virtual void ForceTeleport(Vector3 destinationPosition, Quaternion? destinationRotation = null)
{
DestinationMarkerEventArgs teleportArgs = BuildTeleportArgs(null, destinationPosition, destinationRotation);
StartTeleport(this, teleportArgs);
CalculateBlinkDelay(blinkTransitionSpeed, destinationPosition);
Blink(blinkTransitionSpeed);
if (ValidRigObjects())
{
playArea.position = destinationPosition;
}
Quaternion updatedRotation = SetNewRotation(destinationRotation);
ProcessOrientation(this, teleportArgs, destinationPosition, updatedRotation);
EndTeleport(this, teleportArgs);
}

protected virtual void Awake()
Expand Down Expand Up @@ -202,6 +215,34 @@ protected virtual void Blink(float transitionSpeed)
Invoke("ReleaseBlink", blinkPause);
}

protected virtual DestinationMarkerEventArgs BuildTeleportArgs(Transform target, Vector3 destinationPosition, Quaternion? destinationRotation = null, bool forceDestinationPosition = false)
{
DestinationMarkerEventArgs teleportArgs = new DestinationMarkerEventArgs();
teleportArgs.distance = (ValidRigObjects() ? Vector3.Distance(new Vector3(headset.position.x, playArea.position.y, headset.position.z), destinationPosition) : 0f);
teleportArgs.target = target;
teleportArgs.raycastHit = new RaycastHit();
teleportArgs.destinationPosition = destinationPosition;
teleportArgs.destinationRotation = destinationRotation;
teleportArgs.forceDestinationPosition = forceDestinationPosition;
teleportArgs.enableTeleport = true;
return teleportArgs;
}

protected virtual bool ValidRigObjects()
{
if (headset == null)
{
VRTK_Logger.Warn(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_SCENE, "VRTK_BasicTeleport", "rig headset", ". Are you trying to access the headset before the SDK Manager has initialised it?"));
return false;
}
if (playArea == null)
{
VRTK_Logger.Warn(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_SCENE, "VRTK_BasicTeleport", "rig boundaries", ". Are you trying to access the boundaries before the SDK Manager has initialised it?"));
return false;
}
return true;
}

protected virtual void DoTeleport(object sender, DestinationMarkerEventArgs e)
{
if (enableTeleport && ValidLocation(e.target, e.destinationPosition) && e.enableTeleport)
Expand Down Expand Up @@ -233,17 +274,25 @@ protected virtual void EndTeleport(object sender, DestinationMarkerEventArgs e)

protected virtual Vector3 SetNewPosition(Vector3 position, Transform target, bool forceDestinationPosition)
{
playArea.position = CheckTerrainCollision(position, target, forceDestinationPosition);
return playArea.position;
if (ValidRigObjects())
{
playArea.position = CheckTerrainCollision(position, target, forceDestinationPosition);
return playArea.position;
}
return Vector3.zero;
}

protected virtual Quaternion SetNewRotation(Quaternion? rotation)
{
if (rotation != null)
if (ValidRigObjects())
{
playArea.rotation = (Quaternion)rotation;
if (rotation != null)
{
playArea.rotation = (Quaternion)rotation;
}
return playArea.rotation;
}
return playArea.rotation;
return Quaternion.identity;
}

protected virtual Vector3 GetNewPosition(Vector3 tipPosition, Transform target, bool returnOriginalPosition)
Expand All @@ -253,9 +302,16 @@ protected virtual Vector3 GetNewPosition(Vector3 tipPosition, Transform target,
return tipPosition;
}

float newX = (headsetPositionCompensation ? (tipPosition.x - (headset.position.x - playArea.position.x)) : tipPosition.x);
float newY = playArea.position.y;
float newZ = (headsetPositionCompensation ? (tipPosition.z - (headset.position.z - playArea.position.z)) : tipPosition.z);
float newX = 0f;
float newY = 0f;
float newZ = 0f;

if (ValidRigObjects())
{
newX = (headsetPositionCompensation ? (tipPosition.x - (headset.position.x - playArea.position.x)) : tipPosition.x);
newY = playArea.position.y;
newZ = (headsetPositionCompensation ? (tipPosition.z - (headset.position.z - playArea.position.z)) : tipPosition.z);
}

return new Vector3(newX, newY, newZ);
}
Expand All @@ -265,7 +321,7 @@ protected virtual Vector3 CheckTerrainCollision(Vector3 position, Transform targ
Terrain targetTerrain = target.GetComponent<Terrain>();
if (adjustYForTerrain && targetTerrain != null)
{
Vector3 checkPosition = (useHeadsetForPosition ? new Vector3(headset.position.x, position.y, headset.position.z) : position);
Vector3 checkPosition = (useHeadsetForPosition && ValidRigObjects() ? new Vector3(headset.position.x, position.y, headset.position.z) : position);
float terrainHeight = targetTerrain.SampleHeight(checkPosition);
position.y = (terrainHeight > position.y ? position.y : targetTerrain.GetPosition().y + terrainHeight);
}
Expand Down Expand Up @@ -294,7 +350,7 @@ protected virtual void CalculateBlinkDelay(float blinkSpeed, Vector3 newPosition
if (distanceBlinkDelay > 0f)
{
float minBlink = 0.5f;
float distance = Vector3.Distance(playArea.position, newPosition);
float distance = (ValidRigObjects() ? Vector3.Distance(playArea.position, newPosition) : 0f);
blinkPause = Mathf.Clamp((distance * blinkTransitionSpeed) / (maxBlinkDistance - distanceBlinkDelay), minBlink, maxBlinkTransitionSpeed);
blinkPause = (blinkSpeed <= 0.25 ? minBlink : blinkPause);
}
Expand Down
5 changes: 4 additions & 1 deletion Assets/VRTK/Scripts/Locomotion/VRTK_DashTeleport.cs
Expand Up @@ -95,7 +95,10 @@ protected override void StartTeleport(object sender, DestinationMarkerEventArgs

protected override void ProcessOrientation(object sender, DestinationMarkerEventArgs e, Vector3 newPosition, Quaternion newRotation)
{
StartCoroutine(lerpToPosition(sender, e, newPosition));
if (ValidRigObjects())
{
StartCoroutine(lerpToPosition(sender, e, newPosition));
}
}

protected override void EndTeleport(object sender, DestinationMarkerEventArgs e)
Expand Down
Expand Up @@ -50,7 +50,7 @@ protected override Vector3 GetNewPosition(Vector3 tipPosition, Transform target,

protected virtual float GetTeleportY(Transform target, Vector3 tipPosition)
{
if (!snapToNearestFloor)
if (!snapToNearestFloor || !ValidRigObjects())
{
return tipPosition.y;
}
Expand Down
24 changes: 18 additions & 6 deletions DOCUMENTATION.md
Expand Up @@ -1841,20 +1841,20 @@ The ToggleTeleportEnabled method is used to determine whether the teleporter wil

The ValidLocation method determines if the given target is a location that can be teleported to

#### ForceTeleport/1
#### Teleport/1

> `public virtual void ForceTeleport(DestinationMarkerEventArgs teleportArgs)`
> `public virtual void Teleport(DestinationMarkerEventArgs teleportArgs)`
* Parameters
* `DestinationMarkerEventArgs teleportArgs` - The pseudo Destination Marker event for the teleport action.
* Returns
* _none_

The ForceTeleport/1 method forces the teleport to update position without needing to listen for a Destination Marker event.
The Teleport/1 method calls the teleport to update position without needing to listen for a Destination Marker event.

#### ForceTeleport/4
#### Teleport/4

> `public virtual void ForceTeleport(Transform target, Vector3 destinationPosition, Quaternion? destinationRotation = null, bool forceDestinationPosition = false)`
> `public virtual void Teleport(Transform target, Vector3 destinationPosition, Quaternion? destinationRotation = null, bool forceDestinationPosition = false)`
* Parameters
* `Transform target` - The Transform of the destination object.
Expand All @@ -1864,7 +1864,19 @@ The ForceTeleport/1 method forces the teleport to update position without needin
* Returns
* _none_

The ForceTeleport/3 method forces the teleport to update position without needing to listen for a Destination Marker event. It will build a destination marker out of the provided parameters.
The Teleport/4 method calls the teleport to update position without needing to listen for a Destination Marker event. It will build a destination marker out of the provided parameters.

#### ForceTeleport/2

> `public virtual void ForceTeleport(Vector3 destinationPosition, Quaternion? destinationRotation = null)`
* Parameters
* `Vector3 destinationPosition` - The world position to teleport to.
* `Quaternion? destinationRotation` - The world rotation to teleport to.
* Returns
* _none_

The ForceTeleport method forces the position to update to a given destination and ignores any target checking or floor adjustment.

### Example

Expand Down

0 comments on commit 9a8d97f

Please sign in to comment.