Skip to content

PlayCanvas

The PlayCanvas connector. playcanvas is a peer dependency — the connector reads your existing PlayCanvas instance and never bundles or mutates it.

Terminal window
npm install @uptimizr/playcanvas playcanvas

Because PlayCanvas supports multiple camera entities with no single “active” camera, and the connector reads FPS and the canvas from app.graphicsDevice, the camera Entity is an explicit argument:

import { trackScene } from "@uptimizr/playcanvas";
const client = trackScene(app, cameraEntity, {
projectId: "your-project",
endpoint: "https://collect.example.com",
});
// later, on teardown
await client.stop("manual");

trackScene returns the @uptimizr/sdk-core UptimizrClient. Read client.sessionId, emit custom events, or stop the session early.

World-space data is normalized from PlayCanvas’ native right-handed, y-up frame to the canonical wire frame (left-handed, y-up) at the emission boundary; the session is attributed to the playcanvas connector.

Captures camera pose, pointer move/click (with optional raycast hit), mesh picks, FPS, and asset load timing (asset_load, on by default — see below). Opt-in: mesh visibility and hover dwell. It tears down all DOM listeners, timers, frameend handlers, and asset-registry listeners on stop.

The connector hooks the PlayCanvas app.assets registry load lifecycle (load:startload / error) and emits one asset_load per observed load, carrying the asset’s name, load duration (loadMs), and byte size (bytes, when the engine knows it). Privacy (ADR 0003): only the asset’s app-defined name is recorded — never the file URL — and loads the connector didn’t observe from the start (already-cached assets) are skipped rather than reported with a fabricated duration. Disable with capture: { assetLoad: false }.

When the canvas holds the browser Pointer Lock (first-person/FPS navigation), the OS cursor is hidden and the aim point is the fixed crosshair at the viewport centre. The connector detects pointer lock and reports pointer/click events from screen centre (screen = [0.5, 0.5]), raycasting from the centre — so the 2D pointer heatmap clusters at the centre for locked scenes. Read the cursor-independent gaze / floor-plan heatmaps instead; cursor (orbit/viewer) scenes are unaffected. See Concepts → pointer lock (ADR 0034).

import { UptimizrClient } from "@uptimizr/sdk-core";
import { playcanvasCollector, readDeviceCaps } from "@uptimizr/playcanvas";
const client = new UptimizrClient({
projectId: "your-project",
endpoint: "https://collect.example.com",
});
client.use(playcanvasCollector({ app, camera: cameraEntity }));

See sdk-core (advanced) for the full client API.