# XrManager

Class · extends [`EventHandler`](https://api.playcanvas.com/engine/classes/EventHandler.md) · category: XR

Source: https://github.com/playcanvas/engine/blob/f059dc005842f76e052cdf44d8370c8c7ec475ac/src/framework/xr/xr-manager.js#L69

XrManager provides a comprehensive interface for WebXR integration in PlayCanvas applications.
It manages the full lifecycle of XR sessions (VR/AR), handles device capabilities, and provides
access to various XR features through specialized subsystems.

In order for XR to be available, ensure that your application is served over HTTPS or localhost.

The [AppBase](https://api.playcanvas.com/engine/classes/AppBase.md) class automatically creates an instance of this class and makes it available
as [AppBase#xr](https://api.playcanvas.com/engine/classes/AppBase.md#xr).

Ready-made XR building blocks ship under `playcanvas/scripts/esm/xr/`: `xr-session.mjs` for
session lifecycle and camera rig transforms, `xr-controllers.mjs` for WebXR controller and hand
models, `xr-navigation.mjs` for teleportation, smooth locomotion and turning,
`xr-manipulation.mjs` for two-handed drag, rotate and scale of the world, and `xr-menu.mjs` for
hand-tracked and controller-driven 3D menus.

## Properties

### anchors

```ts
anchors: XrAnchors
```

Provides access to Anchors.

### domOverlay

```ts
domOverlay: XrDomOverlay
```

Provides access to DOM overlay capabilities.

### hitTest

```ts
hitTest: XrHitTest
```

Provides the ability to perform hit tests on the representation of real world geometry
of the underlying AR system.

### imageTracking

```ts
imageTracking: XrImageTracking
```

Provides access to image tracking capabilities.

### input

```ts
input: XrInput
```

Provides access to Input Sources.

### lightEstimation

```ts
lightEstimation: XrLightEstimation
```

Provides access to light estimation capabilities.

### meshDetection

```ts
meshDetection: XrMeshDetection
```

Provides access to mesh detection capabilities.

### planeDetection

```ts
planeDetection: XrPlaneDetection
```

Provides access to plane detection capabilities.

### views

```ts
views: XrViews
```

Provides access to views and their capabilities.

## Accessors

### active

```ts
get active(): boolean
```

True if XR session is running.

### camera

```ts
get camera(): Entity | null
```

Active camera for which XR session is running or null.

### fixedFoveation

```ts
get fixedFoveation(): number | null
set fixedFoveation(value: number | null)
```

Gets the current fixed foveation level, which is between 0 and 1. 0 is no foveation and 1
is highest foveation. If fixed foveation is not supported, this value returns null.

### framebufferScaleFactor

```ts
get framebufferScaleFactor(): number
```

Framebuffer scale factor. This value is read-only and can only be set when starting a new
XR session.

### frameRate

```ts
get frameRate(): number | null
```

XR session frameRate or null if this information is not available. This value can change
during an active XR session.

### graphicsBinding

```ts
get graphicsBinding(): any
```

Backend-specific XR binding for GPU camera/depth paths when available (for example WebGL
`XRWebGLBinding` or WebGPU `XRGPUBinding` when exposed by the user agent).

### session

```ts
get session(): XRSession | null
```

Provides access to XRSession of WebXR.

### spaceType

```ts
get spaceType(): string | null
```

Returns reference space type of currently running XR session or null if no session is
running. Can be any of XRSPACE_*.

### supported

```ts
get supported(): boolean
```

True if XR is supported.

### supportedFrameRates

```ts
get supportedFrameRates(): number[] | null
```

List of supported frame rates, or null if this data is not available.

### type

```ts
get type(): string | null
```

Returns type of currently running XR session or null if no session is running. Can be any of
XRTYPE_*.

## Methods

### end

```ts
end(callback?: XrErrorCallback): void
```

Attempts to end XR session and optionally fires callback when session is ended or failed to
end.

**Parameters**

- `callback` ([`XrErrorCallback`](https://api.playcanvas.com/engine/types/XrErrorCallback.md), optional): Optional callback function called once session is
  ended. The callback has one argument Error - it is null if successfully ended XR session.

**Example**

```ts
app.keyboard.on('keydown', (evt) => {
    if (evt.key === KEY_ESCAPE && app.xr.active) {
        app.xr.end();
    }
});
```

### initiateRoomCapture

```ts
initiateRoomCapture(callback: XrRoomCaptureCallback): void
```

Initiate manual room capture. If the underlying XR system supports manual capture of the
room, it will start the capturing process, which can affect plane and mesh detection,
and improve hit-test quality against real-world geometry.

**Parameters**

- `callback` ([`XrRoomCaptureCallback`](https://api.playcanvas.com/engine/types/XrRoomCaptureCallback.md)): Callback that will be fired once capture is complete
  or failed.

**Example**

```ts
this.app.xr.initiateRoomCapture((err) => {
    if (err) {
        // capture failed
        return;
    }
    // capture was successful
});
```

### isAvailable

```ts
isAvailable(type: string): boolean
```

Check if the specified type of session is available.

**Parameters**

- `type` (`string`): Session type. Can be one of the following:

  - [XRTYPE_INLINE](https://api.playcanvas.com/engine/variables/XRTYPE_INLINE.md): Inline - always available type of session. It has limited features
  availability and is rendered into HTML element.
  - [XRTYPE_VR](https://api.playcanvas.com/engine/variables/XRTYPE_VR.md): Immersive VR - session that provides exclusive access to VR device with
  best available tracking features.
  - [XRTYPE_AR](https://api.playcanvas.com/engine/variables/XRTYPE_AR.md): Immersive AR - session that provides exclusive access to VR/AR device
  that is intended to be blended with real-world environment.

**Returns** `boolean`: True if the specified session type is available.

**Example**

```ts
if (app.xr.isAvailable(XRTYPE_VR)) {
    // VR is available
}
```

### start

```ts
start(camera: CameraComponent, type: string, spaceType: string, options?: object): void
```

Attempts to start XR session for provided [CameraComponent](https://api.playcanvas.com/engine/classes/CameraComponent.md) and optionally fires
callback when session is created or failed to create. Integrated XR APIs need to be enabled
by providing relevant options.

Note that the start method needs to be called in response to user action, such as a button
click. It will not work if called in response to a timer or other event.

**Parameters**

- `camera` ([`CameraComponent`](https://api.playcanvas.com/engine/classes/CameraComponent.md)): It will be used to render XR session and manipulated based
  on pose tracking.
- `type` (`string`): Session type. Can be one of the following:

  - [XRTYPE_INLINE](https://api.playcanvas.com/engine/variables/XRTYPE_INLINE.md): Inline - always available type of session. It has limited features
  availability and is rendered into HTML element.
  - [XRTYPE_VR](https://api.playcanvas.com/engine/variables/XRTYPE_VR.md): Immersive VR - session that provides exclusive access to VR device with
  best available tracking features.
  - [XRTYPE_AR](https://api.playcanvas.com/engine/variables/XRTYPE_AR.md): Immersive AR - session that provides exclusive access to VR/AR device
  that is intended to be blended with real-world environment.
- `spaceType` (`string`): Reference space type. Can be one of the following:

  - [XRSPACE_VIEWER](https://api.playcanvas.com/engine/variables/XRSPACE_VIEWER.md): Viewer - always supported space with some basic tracking
  capabilities.
  - [XRSPACE_LOCAL](https://api.playcanvas.com/engine/variables/XRSPACE_LOCAL.md): Local - represents a tracking space with a native origin near the
  viewer at the time of creation. It is meant for seated or basic local XR sessions.
  - [XRSPACE_LOCALFLOOR](https://api.playcanvas.com/engine/variables/XRSPACE_LOCALFLOOR.md): Local Floor - represents a tracking space with a native origin
  at the floor in a safe position for the user to stand. The y axis equals 0 at floor level.
  Floor level value might be estimated by the underlying platform. It is meant for seated or
  basic local XR sessions.
  - [XRSPACE_BOUNDEDFLOOR](https://api.playcanvas.com/engine/variables/XRSPACE_BOUNDEDFLOOR.md): Bounded Floor - represents a tracking space with its native
  origin at the floor, where the user is expected to move within a pre-established boundary.
  - [XRSPACE_UNBOUNDED](https://api.playcanvas.com/engine/variables/XRSPACE_UNBOUNDED.md): Unbounded - represents a tracking space where the user is
  expected to move freely around their environment, potentially long distances from their
  starting point.
- `options` (`object`, optional): Object with additional options for XR session initialization.
    - `options.anchors` (`boolean`, optional): Set to true to attempt to enable
      [XrAnchors](https://api.playcanvas.com/engine/classes/XrAnchors.md).
    - `options.callback` ([`XrErrorCallback`](https://api.playcanvas.com/engine/types/XrErrorCallback.md), optional): Optional callback function called once session
      is started. The callback has one argument Error - it is null if successfully started XR
      session.
    - `options.depthSensing` (`object`, optional): Optional object with parameters to attempt to enable
      depth sensing.
        - `options.depthSensing.dataFormatPreference` (`string`, optional): Optional data format
          preference for depth sensing, can be 'luminance-alpha' or 'float32'
          (XRDEPTHSENSINGFORMAT_*), defaults to 'luminance-alpha'. Most preferred and supported will
          be chosen by the underlying depth sensing system.
        - `options.depthSensing.usagePreference` (`string`, optional): Optional usage preference for depth
          sensing, can be 'cpu-optimized' or 'gpu-optimized' (XRDEPTHSENSINGUSAGE_*), defaults to
          'cpu-optimized'. Most preferred and supported will be chosen by the underlying depth sensing
          system.
    - `options.framebufferScaleFactor` (`number`, optional): Framebuffer scale factor should
      be higher than 0.0, by default 1.0 (no scaling). A value of 0.5 will reduce the resolution
      of an XR session in half, and a value of 2.0 will double the resolution.
    - `options.imageTracking` (`boolean`, optional): Set to true to attempt to enable
      [XrImageTracking](https://api.playcanvas.com/engine/classes/XrImageTracking.md).
    - `options.meshDetection` (`boolean`, optional): Set to true to attempt to enable
      [XrMeshDetection](https://api.playcanvas.com/engine/classes/XrMeshDetection.md).
    - `options.optionalFeatures` (`string[]`, optional): Optional features for XRSession start. It is
      used for getting access to additional WebXR spec extensions.
    - `options.planeDetection` (`boolean`, optional): Set to true to attempt to enable
      [XrPlaneDetection](https://api.playcanvas.com/engine/classes/XrPlaneDetection.md).

**Example**

```ts
button.on('click', () => {
    app.xr.start(camera, XRTYPE_VR, XRSPACE_LOCALFLOOR);
});
```

**Example**

```ts
button.on('click', () => {
    app.xr.start(camera, XRTYPE_AR, XRSPACE_LOCALFLOOR, {
        anchors: true,
        imageTracking: true,
        depthSensing: { }
    });
});
```

### updateTargetFrameRate

```ts
updateTargetFrameRate(frameRate: number, callback?: Function): void
```

Update target frame rate of an XR session to one of supported value provided by
supportedFrameRates list.

**Parameters**

- `frameRate` (`number`): Target frame rate. It should be any value from the list
  of supportedFrameRates.
- `callback` (`Function`, optional): Callback that will be called when frameRate has been
  updated or failed to update with error provided.

### isDeviceSupported

```ts
static isDeviceSupported(deviceType: string, type: string): Promise<boolean>
```

Tests whether an immersive WebXR session of the given type can run on the specified graphics
backend. Unlike [XrManager#isAvailable](https://api.playcanvas.com/engine/classes/XrManager.md#isavailable), this is a static method that can be called
before a graphics device (or the [AppBase](https://api.playcanvas.com/engine/classes/AppBase.md)) is created, which makes it useful for
deciding which device type to create for XR - for example WebGPU vs WebGL2.

This is a best-effort preflight check. The only authoritative test remains a successful
[XrManager#start](https://api.playcanvas.com/engine/classes/XrManager.md#start), so a fallback path should always be kept.

**Parameters**

- `deviceType` (`string`): The graphics device type the session would run on. Can be
  [DEVICETYPE_WEBGPU](https://api.playcanvas.com/engine/variables/DEVICETYPE_WEBGPU.md) or [DEVICETYPE_WEBGL2](https://api.playcanvas.com/engine/variables/DEVICETYPE_WEBGL2.md).
- `type` (`string`): The session type. Can be:

  - [XRTYPE_VR](https://api.playcanvas.com/engine/variables/XRTYPE_VR.md): Immersive VR session.
  - [XRTYPE_AR](https://api.playcanvas.com/engine/variables/XRTYPE_AR.md): Immersive AR session.

**Returns** `Promise<boolean>`: Promise that resolves to true if a session of the given type is
reported supported on the given backend, false otherwise.

**Example**

```ts
const supported = await XrManager.isDeviceSupported(DEVICETYPE_WEBGPU, XRTYPE_VR);
if (supported) {
    // a WebGPU device can be created and used to offer VR
}
```

## Events

### EVENT_AVAILABLE

```ts
static EVENT_AVAILABLE: string = 'available'
```

Fired when availability of the XR type is changed. This event is available in two
forms. They are as follows:

1. `available` - Fired when availability of any XR type is changed. The handler is passed
the session type that has changed availability and a boolean representing the availability.
2. `available:[type]` - Fired when availability of specific XR type is changed. The handler
is passed a boolean representing the availability.

**Example**

```ts
app.xr.on('available', (type, available) => {
    console.log(`XR type ${type} is now ${available ? 'available' : 'unavailable'}`);
});
```

**Example**

```ts
app.xr.on(`available:${XRTYPE_VR}`, (available) => {
    console.log(`XR type VR is now ${available ? 'available' : 'unavailable'}`);
});
```

### EVENT_END

```ts
static EVENT_END: string = 'end'
```

Fired when XR session is ended. While the handlers run, [XrManager#camera](https://api.playcanvas.com/engine/classes/XrManager.md#camera),
[XrManager#type](https://api.playcanvas.com/engine/classes/XrManager.md#type) and [XrManager#spaceType](https://api.playcanvas.com/engine/classes/XrManager.md#spacetype) still describe the session that has
ended, and they are reset once all handlers have run.

**Example**

```ts
app.xr.on('end', () => {
    // XR session has ended
});
```

### EVENT_ERROR

```ts
static EVENT_ERROR: string = 'error'
```

Fired when XR session is failed to start or failed to check for session type support. The handler
is passed the [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
object related to failure of session start or check of session type support.

**Example**

```ts
app.xr.on('error', (error) => {
    console.error(error.message);
});
```

### EVENT_START

```ts
static EVENT_START: string = 'start'
```

Fired when XR session is started.

**Example**

```ts
app.xr.on('start', () => {
    // XR session has started
});
```

### EVENT_UPDATE

```ts
static EVENT_UPDATE: string = 'update'
```

Fired when XR session is updated, providing relevant XRFrame object. The handler is passed
[XRFrame](https://developer.mozilla.org/en-US/docs/Web/API/XRFrame) object that can be used
for interfacing directly with WebXR APIs.

**Example**

```ts
app.xr.on('update', (frame) => {
    console.log('XR frame updated');
});
```

## Inherited from [EventHandler](https://api.playcanvas.com/engine/classes/EventHandler.md)

- `fire(name: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any, arg7?: any, arg8?: any): EventHandler`
- `hasEvent(name: string): boolean`
- `off(name?: string, callback?: HandleEventCallback, scope?: any): EventHandler`
- `on(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
- `once(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
