A gaze-based teleportation system

In gaze-based teleportation, the player focuses on a location, the system provides visual feedback, the player responds with controller input (a gesture or button-click), and teleportation occurs with or without transitional effects. For our midway, we will provide a GameObject to indicate player gaze and provide a destination for the teleportation. This object will only be displayed when the player gazes at ground-level teleportation locations, indicating a wish to travel to that location. We will then map the primary controller button to trigger positional transformation of the LocalAvatar GameObject. Remember this GameObject contains the POV camera, controller hands, and the player's colliders. To the user, it will appear as if they have been teleported to a new location, retaining their previous head and tilt positional values:

  1. Create an empty root-level GameObject, rename it TeleportSystem, and set the Position Transform to (0, 0, -4). The GameObject will contain the player's macro-navigation assets.
  2. Add a cube to TeleportSystem positioned at (0, 0, 0.66) with a scale of (3.8, 0.01, 3.5). Rename the cube TeleportArea (1).

The TeleportArea GameObject will be used to indicate areas accessible by the player. Once the other assets are prepared, we will duplicate the TeleportAreas to fit the space:

  1. Create a new layer called TeleportTrigger.
  2. Assign TeleportArea (1) to the TeleportTrigger.
  3. Add a cylinder to TeleportSystem positioned at (0, 0.005, 0) with a scale of (1, 0.0025, 1).
  1. Rename the cylinder TeleportTarget and set Is Trigger to true for the capsule collider.
  2. Create a new C# script called Teleporter and put it in the Script folder.
  3. Assign the script to the LocalAvatar GameObject.
  4. Double-click the Teleporter script to open the editor.

The Teleporter script is broken into a few distinct sections. Perform the following steps to create the required behaviors.

  1. Add the teleporter and layerMask variables:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Teleporter : MonoBehaviour {
[SerializeField] GameObject target;
[SerializeField] LayerMask layerMask;
  1. Delete the Start() function and add the following to Update():
void Update () { 
    RaycastHit hit; 
    if (Physics.Raycast (Camera.main.transform.position,  
Camera.main.transform.rotation *
Vector3.forward, out hit, 9999, layerMask)) { target.SetActive (true); target.transform.position = hit.point; } else { target.SetActive (false); }

if (Input.GetButtonDown("Button.One") ||
Input.GetButtonDown("Button.Three")) {
Vector3 markerPosition = target.transform.position;
transform.position = new Vector3 (markerPosition.x,
transform.position.y, markerPosition.z);
}
}
}

The Update() function first creates a RaycastHit called a hit and then tests if the ray has collided with an object on the layerMask layer. If a hit is registered, then the visible target is turned on and moved to the point where the ray passes through the layerMask. This statement also hides the target if a hit is not registered.

The second if statement checks to see if a specific button on the right (Button.One) or left (Button.Three) controller was pressed. (See Figure 7.15 for a mapping of the controller buttons.) If a press was detected, then the position of the target is stored, and the player's transform position is set to the same location. This results in the actual teleportation, because we move the player to a new location, instantly changing their point of view in the scene:

Figure 7.15: Touch controller button mapping