Computer Graphics for Virtual  
and Augmented Reality  
Lecture 05 Navigation Methods for  
Virtual Reality in Unity  
Edirlei Soares de Lima  
<edirlei.lima@universidadeeuropeia.pt>  
Navigation Methods for Virtual Reality  
The navigation defines how the user moves from place to  
place within the virtual environment  
The combination of travel with wayfinding  
Wayfinding: cognitive component of navigation  
Travel: motor component of navigation  
Types of navigation:  
Exploration: no explicit goal for the movement  
Search: moving to specific target location  
Naïve: target position is not known  
Informed: position of target is known  
Navigation Methods for Virtual Reality  
Implicit navigation: natural movement  
Dependent on display, tracking technology, and the available space  
Boundary control  
Keep the user inside of safe space without destroying immersion  
Navigation Methods for Virtual Reality  
Implicit navigation with smart use of space:  
Redirected Walking  
Rotate the scene to bend long straight walks  
22m radius circular walk can feel straight  
But rotation is really bad for cyber sickness  
Portals and Corridors  
Dynamic scene that adapts to the real room  
Maze-like spaceship or dense thickets  
Navigation Methods for Virtual Reality  
Implicit navigation with locomotion interfaces:  
Navigate by stationary motion  
Unrealistic movement: the technology is not there yet  
Navigation Methods for Virtual Reality  
Explicit navigation: explicitly controls the navigation  
Use controller keys  
Apply a metaphor:  
Flying  
Goal driven navigation  
Object driven navigation  
Select where to go/fly/walk  
Navigation Techniques  
Navigation Techniques  
Controller-Based Navigation:  
Use controller keys to move and rotate  
Very common in games  
Can cause motion sickness (especially the rotation)  
The snap turn technique can be used to reduce motion sickness: use pre-  
determined rotation amounts (15, 30, 45, or 90 degrees)  
Controller-Based Navigation in Unity  
public class ControllerNavigation: MonoBehaviour{  
private Rigidbody rb;  
public InputActionProperty moveAction;  
public InputActionProperty rotateAction;  
public float moveForce;  
public bool snapTurn;  
public int snapTurnAngle = 30;  
private bool snapTurnDone = false;  
void Start(){  
rb = GetComponent<Rigidbody>();  
}
void FixedUpdate(){  
Vector2 moveAxis = moveAction.action.ReadValue<Vector2>();  
Vector2 rotateAxis = rotateAction.action.ReadValue<Vector2>();  
if (moveAxis.magnitude != 0){  
rb.AddForce(((transform.forward * moveAxis.y) +  
transform.right * moveAxis.x) * moveForce,  
ForceMode.VelocityChange);  
}
Controller-Based Navigation in Unity  
else{  
rb.velocity = Vector3.zero;  
}
if (rotateAxis.magnitude != 0){  
if (snapTurn){  
if (!snapTurnDone){  
snapTurnDone = true;  
float angle = snapTurnAngle;  
if (rotateAxis.x < 0)  
angle = snapTurnAngle * -1;  
rb.transform.Rotate(new Vector3(0, angle, 0));  
}
}
else{  
rb.transform.Rotate(new Vector3(0, rotateAxis.x, 0));  
}
}
else if (snapTurn){  
snapTurnDone = false;  
}
}
}
Controller-Based Navigation in Unity  
XR Interaction Toolkit implementation:  
Add a locomotion system and select the XR  
Origin;  
For movement:  
Add and configure a Continuous Move Provider  
component;  
For rotation:  
Add and configure a Continuous Turn Provider  
component; or  
Add and configure a Snap Turn Provider  
component;  
Navigation Techniques  
Gaze Directed Steering:  
Move in the direction that the user is looking  
Very intuitive, natural and can be used on the most basic HMDs  
Limited interaction and the user can’t look in different direction while  
moving  
Gaze Directed Navigation in Unity  
public class GazeNavigation : MonoBehaviour  
{
private Rigidbody rb;  
public Camera cameraVR;  
public float moveSpeed = 0.16f;  
public float rotateSpeed = 1f;  
public bool xMovement = true;  
public bool yMovement = false;  
public bool zMovement = true;  
void Start()  
{
rb = GetComponent<Rigidbody>();  
}
Gaze Directed Navigation in Unity  
void FixedUpdate()  
{
float x = 0, y = 0, z = 0;  
if (xMovement)  
x = cameraVR.transform.forward.x;  
if (yMovement)  
y = cameraVR.transform.forward.y;  
if (zMovement)  
z = cameraVR.transform.forward.z;  
Vector3 moveDirection = new Vector3(x, y, z);  
rb.AddForce(moveDirection * moveSpeed,  
ForceMode.VelocityChange);  
rb.transform.rotation = Quaternion.Lerp(rb.transform.rotation,  
Quaternion.LookRotation(moveDirection),  
rotateSpeed * Time.fixedDeltaTime);  
}
}
Navigation Techniques  
Pointing Direction:  
Use hand tracker instead of head tracker  
The user points in the direction that he wants to go  
Allows travel and gaze in different directions  
Good for relative motion: look one way, move another  
https://www.youtube.com/watch?v=JRgCe_8q4vE  
Pointing Navigation in Unity  
public class PointingNavigation : MonoBehaviour  
{
private Rigidbody rb;  
public Transform hand;  
public InputActionProperty moveAction;  
public float moveSpeed = 0.16f;  
public float rotateSpeed = 1f;  
public bool xMovement = true;  
public bool yMovement = false;  
public bool zMovement = true;  
void Start()  
{
rb = GetComponent<Rigidbody>();  
}
Pointing Navigation in Unity  
void FixedUpdate(){  
float x = 0, y = 0, z = 0;  
float moveButton = moveAction.action.ReadValue<float>();  
if (moveButton > 0)  
{
if (xMovement)  
x = hand.transform.forward.x;  
if (yMovement)  
y = hand.transform.forward.y;  
if (zMovement)  
z = hand.transform.forward.z;  
Vector3 moveDirection = new Vector3(x, y, z);  
rb.AddForce(moveDirection * moveSpeed,  
ForceMode.VelocityChange);  
rb.transform.rotation = Quaternion.Lerp(rb.transform.rotation,  
Quaternion.LookRotation(moveDirection),  
rotateSpeed * Time.fixedDeltaTime);  
}
}
}
Navigation Techniques  
Fly-to (teleportation or motion):  
User can point to a target position in the virtual environment  
Predefined positions vs. free positions  
The user moves or teleported to the target position  
Teleportation in Unity (Anchor-Based)  
XR Interaction Toolkit implementation:  
Add and configure a Teleportation Provider  
Component in the XR Origin.  
Create the anchor location:  
Add a GameObject as visual clue and a Collider  
If a trigger is used, the trigger collision must be enabled in the  
XR Ray Interactor.  
Add another parent empty GameObject to define  
the teleportation position.  
Add and configure a Teleportation Anchor  
Component.  
Teleportation in Unity (Area-Based)  
XR Interaction Toolkit implementation:  
Add and configure a Teleportation Provider  
Component in the XR Origin.  
Create the teleportation area:  
Add a GameObject as visual clue and a Collider (or  
select an existing object of the scene, such as the  
ground).  
If a trigger is used, the trigger collision must be enabled in the  
XR Ray Interactor.  
Add and configure a Teleportation Area  
Component.  
Problem: the teleportation area teleports the player  
to the exact point where the ray hits.  
Solution: create a custom teleportation area script.  
Teleportation in Unity (Area-Based)  
using UnityEngine;  
using UnityEngine.XR.Interaction.Toolkit;  
public class MyTeleportationArea : BaseTeleportationInteractable  
{
public Vector3 teleportationOffset = Vector3.zero;  
protected override bool GenerateTeleportRequest(  
IXRInteractor interactor, RaycastHit raycastHit,  
ref TeleportRequest teleportRequest)  
{
if (raycastHit.collider == null)  
return false;  
teleportRequest.destinationPosition = raycastHit.point +  
teleportationOffset;  
teleportRequest.destinationRotation = transform.rotation;  
return true;  
}
}
Navigation Techniques  
Automatic navigation:  
Automatic movement on a pre-selected path (on-rails locomotion)  
Continuous movement  
Pre-selected positions for additional interaction  
https://www.youtube.com/watch?v=HC3E3bc9A7o  
Automatic Navigation in Unity  
Use waypoints to define the path:  
public class Waypoint : MonoBehaviour  
{
public Waypoint[] edges;  
void OnDrawGizmos()  
{
Gizmos.color = Color.green;  
foreach (Waypoint e in edges)  
{
if (e != null)  
{
Gizmos.DrawLine(transform.position,  
e.gameObject.transform.position);  
}
}
}
}
Automatic Navigation in Unity  
public class AutomaticNavigation : MonoBehaviour  
{
public Waypoint startWaypoint;  
public float moveSpeed;  
private Rigidbody playerRigidbody;  
private Waypoint targetWaypoint;  
private Vector3 targetPosition;  
void Start()  
{
playerRigidbody = GetComponent<Rigidbody>();  
if (startWaypoint)  
{
targetPosition = new Vector3(  
startWaypoint.transform.position.x, transform.position.y,  
startWaypoint.transform.position.z);  
targetWaypoint = startWaypoint;  
}
}
Automatic Navigation in Unity  
void FixedUpdate(){  
if (targetWaypoint){  
playerRigidbody.MovePosition(Vector3.MoveTowards(  
transform.position, targetPosition, moveSpeed *  
Time.fixedDeltaTime));  
if (Vector3.Distance(transform.position,targetPosition) < 0.5f)  
{
if (targetWaypoint.edges.Length > 0){  
targetWaypoint = targetWaypoint.edges[0];  
targetPosition = new Vector3(targetWaypoint.transform.  
position.x, transform.position.y,  
targetWaypoint.transform.position.z);  
}
else{  
targetWaypoint = null;  
}
}
}
}
}
Navigation Techniques  
Grabbing the Air:  
User use hand gestures to move through the world  
Metaphor of pulling a rope  
Often a two-handed technique  
https://www.youtube.com/watch?v=WG5WihQK6ts  
Grabbing the Air Navigation in Unity  
public class GrabAirNavigation : MonoBehaviour  
{
private Rigidbody rb;  
public Transform leftHand;  
public Transform rightHand;  
public InputActionProperty leftGrabAction;  
public InputActionProperty rightGrabAction;  
private Vector3 grabStartPosition;  
private int selectedHand;  
void Start()  
{
rb = GetComponent<Rigidbody>();  
grabStartPosition = Vector3.zero;  
}
Grabbing the Air Navigation in Unity  
void FixedUpdate()  
{
float grabLeftButton = leftGrabAction.action.ReadValue<float>();  
float grabRightButton = rightGrabAction.action.ReadValue<float>();  
if ((grabLeftButton > 0) || (grabRightButton > 0)){  
if (grabStartPosition == Vector3.zero){  
if (grabLeftButton > 0){  
selectedHand = 1;  
grabStartPosition = leftHand.position;  
}
else{  
selectedHand = 2;  
grabStartPosition = rightHand.position;  
}
}
}
else{  
grabStartPosition = Vector3.zero;  
}
Grabbing the Air Navigation in Unity  
if (grabStartPosition != Vector3.zero)  
{
Vector3 startDirection = grabStartPosition –  
rb.transform.position;  
Vector3 endDirection = Vector3.zero;  
if (selectedHand == 1)  
endDirection = leftHand.position - rb.transform.position;  
else if (selectedHand == 2)  
endDirection = rightHand.position - rb.transform.position;  
if (Vector3.Magnitude(startDirection) >  
Vector3.Magnitude(endDirection))  
{
float moveAmount = 0;  
if (selectedHand == 1)  
moveAmount = Vector3.Magnitude(grabStartPosition –  
leftHand.position);  
else if (selectedHand == 2)  
moveAmount = Vector3.Magnitude(grabStartPosition –  
rightHand.position);  
Grabbing the Air Navigation in Unity  
if (moveAmount > 0)  
{
rb.MovePosition(rb.transform.position +  
(Vector3.Normalize(startDirection) * moveAmount));  
grabStartPosition = Vector3.zero;  
}
}
}
}
}
Navigation Techniques  
Moving Your Own Body:  
User can move his own virtual body like any object  
In World in Miniature or in a mini map  
Grab the avatar and move to desired point  
Immediate teleportation to new position  
Navigation Techniques  
Other common navigation techniques:  
Object driven navigation (lifts, stairways)  
Combination of navigation techniques:  
Local navigation implicit  
Larger distances explicit  
Assignment 1  
Create the interior area the house illustrated in the image  
below (with corridors, rooms, and doors). Then, implement  
and test the following navigation techniques:  
1
2
3
. Controller-Based Navigation  
. Fly-to/teleportation  
B
C
A
D
E
. Automatic navigation (following a  
predefined path)  
F
G
H
I
J
Further Reading  
Sherman, W. R., Craigm A. B. (2003). Understanding Virtual Reality:  
Interface, Application, and Design (1st ed.). Morgan Kaufmann. ISBN: 978-  
1
558603530.  
Chapter 6: Interacting with the Virtual World