Custom Virtual Reality UX

Use `XrService` to interact with virtual reality devices and controllers

WebXR experiences can run on desktop, mobile and virtual reality devices alike. Utilizing the XrService in the Create SDK, you can write custom code to manage VR controllers, locomotion settings, and XR session callbacks.

Custom Locomotion Settings

By default, the VIVERSE character controller uses teleport for locomotion, since this is the more comfortable option, in general. However, smooth locomotion (where the player glides smoothly across the floor) can be enabled on either or both controllers by setting the LocomotionType of each.

Import the XrService from the Create SDK into an .mjs script. Per the API docs, this gives you access to both left and right controllers, and their properties, to set on init:

import { Script, Asset } from "playcanvas";
import { XrService } from "../@viverse/create-sdk.mjs";

export class ViverseXrManager extends Script {
  static scriptName = "viverseXrManager";
  
  initialize() {
    this.xrService = new XrService();
    this.xrService.controllers.right.locomotionType = 2;  // Teleport
    this.xrService.controllers.left.locomotionType = 1;  // Smooth
    // See enum definitions here:
    // https://viveportsoftware.github.io/pc-lib/enums/XrTypes.LocomotionTypes.html
  }
}

NOTE: this script asset must be placed in /scripts or another subfolder, since it assumes the VIVERSE SDK is one level up, located at: "../@viverse/create-sdk.mjs" - or you can alter this import path as needed. For more information on how .mjs scripts and imports work, see Introduction to MJS.

Custom Controller Models

Checking the IXrController interface further, we can use the setModelAsset() function to set custom 3D models for our controllers, instead of the default VIVERSE models.

import { Script, Asset } from "playcanvas";
import { XrService } from "../@viverse/create-sdk.mjs";

export class ViverseXrManager extends Script {
  static scriptName = "viverseXrManager";
  
  /**
  * @attribute
  * @type {Asset}
  */
  vrControllerAssetR = null;

  /**
  * @attribute
  * @type {Asset}
  */
  vrControllerAssetL = null;

  initialize() {
    this.xrService = new XrService();
    this.xrService.controllers.right.setModelAsset(this.vrControllerAssetR);
    this.xrService.controllers.left.setModelAsset(this.vrControllerAssetL);
  }
}

After defining the vrControllerAssetL and vrControllerAssetR attributes of type Asset in the above script, we then reference custom 3D controller assets in the editor, which our script instantiates at runtime in VR.

Last updated

Was this helpful?