//***********************************************************
// Filename: Teleport.cs
// Author: Moritz Kolvenbach, Marco Fendrich
// Last changes: Mittwoch, 8. August 2018
// Content: Class for actual positional change of player
//***********************************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// Base class for teleportation
///
public class Teleport : MonoBehaviour
{
/// Origin of SteamVR tracking space
[Tooltip("Origin of the SteamVR tracking space")]
public Transform OriginTransform;
/// Origin of the player's head
[Tooltip("Transform of the player's head")]
public Transform HeadTransform;
/// How long, in seconds, the fade-in/fade-out animation should take
[Tooltip("Duration of the \"blink\" animation (fading in and out upon teleport) in seconds")]
public float TeleportFadeDuration = 0.2f;
/// Indicates the current use of teleportation.
/// NONE: The player is not using teleportation right now
/// TELEPORTING: The player has selected a teleport destination and is currently teleporting now (fading in/out)
private TeleportState currentTeleportState = TeleportState.NONE;
private bool FadingIn = false; // tracks whether fading in or out
private float TeleportTimeMarker; // tracks start time of last teleport
// script to trigger fade in/out effect
public FadeInOut fadeScript;
// Spot to be teleported to if called externally
private Vector3 destinationPoint;
private float rotation = float.NegativeInfinity;
// Time to be used as time stamp for teleport event
private float teleportStartTime;
///
/// Initiates a teleportation of the player to the given position
///
/// Where the player should be teleported
public void CallTeleport(Vector3 destinationPoint)
{
currentTeleportState = TeleportState.TELEPORTING;
this.destinationPoint = destinationPoint;
TeleportTimeMarker = Time.time;
}
///
/// Initiates a teleportation including rotation of the player to given position and with given rotation
///
/// Where the player should be teleported
/// Angle in degrees that the player should be rotated
public void CallTeleport(Vector3 destinationPoint, float rotation)
{
currentTeleportState = TeleportState.TELEPORTING;
this.destinationPoint = destinationPoint;
TeleportTimeMarker = Time.time;
this.rotation = rotation;
}
///
/// Initiates a teleportation including rotation of the player to given position and with given rotation. Creates an event including timestamps
///
/// Where the player should be teleported
/// Angle in degrees that the player should be rotated
/// Time at which the teleportbutton was first pressed
public void CallTeleport(Vector3 destinationPoint, float rotation, float teleportStartTime)
{
currentTeleportState = TeleportState.TELEPORTING;
this.destinationPoint = destinationPoint;
TeleportTimeMarker = Time.time;
this.rotation = rotation;
this.teleportStartTime = teleportStartTime;
}
void Update()
{
if (currentTeleportState == TeleportState.TELEPORTING)
{
// Wait until half of the teleport time has passed before the next event (note: both the switch from fade
// out to fade in and the switch from fade in to stop the animation is half of the fade duration)
if (Time.time - TeleportTimeMarker >= TeleportFadeDuration / 2)
{
if (FadingIn)
{
// We have finished fading in, reset teleport state
currentTeleportState = TeleportState.NONE;
}
else
{
// We have finished fading out, get player's transform properties
Vector3 startPosition = HeadTransform.position;
Vector3 startRotation = HeadTransform.rotation.eulerAngles;
// If a rotation was set by teleport method, rotate play area
// (player position would change due to this step but this will be compensated for during teleportation)
if (rotation > float.NegativeInfinity)
{
OriginTransform.Rotate(0, rotation, 0);
rotation = float.NegativeInfinity; // Reset rotation given by teleport
}
// Calculate offset between player and play area as play area will be moved but the player position is the one that has been chosen
Vector3 offset = OriginTransform.position - HeadTransform.position;
offset.y = 0; // Ignore player's height
OriginTransform.position = destinationPoint + offset; // Actual teleport
// Call teleport event and fire it
TeleportEvent teleportEvent = new TeleportEvent
{
startTeleportTime = teleportStartTime,
endTeleportTime = Time.time,
startUserPosition = startPosition,
endUserPosition = HeadTransform.position,
startUserRotation = startRotation,
endUserRotation = HeadTransform.rotation.eulerAngles
};
teleportEvent.FireEvent();
}
TeleportTimeMarker = Time.time;
FadingIn = !FadingIn;
}
// Set alpha value of fadeOut screen for blink effect
float alpha = Mathf.Clamp01((Time.time - TeleportTimeMarker) / (TeleportFadeDuration / 2));
if (FadingIn)
alpha = 1 - alpha;
fadeScript.setAlphaValue(alpha);
}
}
}
///
/// Represents the player's current use of the teleport mechanic.
///
public enum TeleportState
{
/// The player is not using teleportation right now
NONE,
/// The player has selected a teleport destination and is currently teleporting (fading in/out)
TELEPORTING,
}