Spatial Systems Journal • Game Engines

Unity XR Interaction Toolkit Integration Patterns for Spatial APIs

How to connect a spatial backend to Unity XR without coupling network models to GameObjects, including adapters, interactors, anchors, async state, and testing.

Unity Xr + Api — neon spatial systems typography card

Unity makes it easy to put an object in a scene and attach behavior to it. That convenience can become a liability when network records, runtime tracking, interaction state, and GameObject lifetime are treated as the same thing. A spatial backend needs stable IDs, versioned data, permissions, and explicit frames. Unity scenes need components, transforms, assets, and responsive interaction. An adapter layer should connect them without allowing either side to dictate the other’s shape.

The XR Interaction Toolkit provides a vocabulary of interactors, interactables, managers, locomotion, and feedback. Your spatial API should complement that vocabulary by supplying durable entities and actions. The goal is not to mirror every component over the network; it is to synchronize the domain state that matters.

Use a three-model architecture

Keep separate models for transport, domain, and presentation. The transport model matches JSON or binary payloads and handles serialization. The domain model represents stable entities, revisions, ownership, spatial frames, and allowed actions. The presentation model is composed of GameObjects, components, prefabs, and materials. Mapping between them can be explicit and testable.

This separation prevents API field changes from rippling through every MonoBehaviour. It also allows a domain entity to exist while its asset is unloaded or while it is outside the current scene. Presentation objects can be pooled or recreated without losing identity, and transport retries do not have to understand Unity component lifecycles.

Map entity IDs to scene objects

Create a registry that maps each durable spatial entity ID to its active scene representation. The registry can instantiate a prefab based on entity type, attach a small identity component, and update pose or state through dedicated presenters. Avoid searching the scene by name or assuming hierarchy position is identity.

When an entity leaves scope, decide whether to deactivate, pool, or destroy its presentation object. Keep the domain record if the client may need it for history or pending operations. When it returns, the registry can reuse or recreate the object and restore relevant local state.

Translate interaction into domain commands

An XR grab is a local interaction event; a durable move is a domain command. During manipulation, render responsive local motion. At an appropriate boundary—release, snap, or explicit save—send a command containing the entity ID, proposed pose, frame, base revision, and intent. The server validates authorization and constraints, then returns the accepted state.

This command pattern supports undo, audit, and conflict handling. It also prevents every frame of controller motion from becoming a network write. For collaborative scenes, other clients can receive semantic updates and interpolate toward accepted poses.

Normalize coordinate systems at one boundary

Unity’s coordinate conventions may differ from geographic, robotics, or external 3D systems. Put conversion in a dedicated spatial adapter with documented units, axes, handedness, and quaternion rules. Do not scatter sign flips and scale factors across components. Add round-trip tests with known poses and orientations.

Every backend pose should include a frame ID. The adapter resolves that frame into the active Unity world or tracking origin. When the XR origin recenters or relocates, update the transform chain rather than rewriting all domain coordinates. This keeps network state stable while the local session changes.

Integrate interactors and permissions

Interaction components should reflect domain capabilities. If the current user cannot move an entity, disable or replace the grab behavior and explain the state through visuals or UI. If an entity is locked by a workflow, the scene should not allow a local manipulation that will inevitably fail. Capability data can be part of the domain entity or a separate authorization service.

Use interaction layers and filters to prevent invalid targets. Keep business rules out of low-level input callbacks when possible. A command service can answer whether an action is currently allowed and return a reason that the presentation layer renders appropriately.

Async loading and cancellation

Spatial scenes often load metadata, models, textures, and anchor state independently. Build async flows with cancellation tied to scene and entity lifetime. If a user leaves an area, cancel pending asset work rather than instantiating an object into a stale context. Show progressive states so an entity can be selected or described before its full model is ready.

Cache assets by immutable version or content hash. Separate an entity’s identity from its asset URL so assets can be replaced without changing references. Handle failures with a visible proxy rather than a null object that breaks interaction logic.

Anchors and persistence

A runtime anchor keeps an object stable in the current tracking environment. A backend record keeps the product’s meaning stable across sessions and devices. Store the durable anchor ID and resolution metadata in the domain model, then create or resolve the runtime anchor through a platform service. The GameObject follows the runtime result but does not own persistence.

When resolution fails, preserve the entity in an unresolved state. The user may see it in a list, map, or staging area and retry localization. Avoid placing unresolved content at world origin, where it can look like a valid but incorrect placement.

Testing without a headset

Most integration logic can be tested without physical XR hardware. Unit-test transport mapping, coordinate conversion, command validation, revision handling, and entity registries. Use recorded pose streams and synthetic interaction events for deterministic play-mode tests. Fixtures should cover recentering, out-of-order updates, duplicate events, and failed asset loads.

Hardware tests remain essential for comfort, tracking, input, and performance. Keep the domain and adapter tests fast so device sessions focus on the issues that truly require a headset. Diagnostic overlays can display entity IDs, frame IDs, revisions, anchor state, and network latency in development builds.

Conclusion

Unity XR integrations remain maintainable when GameObjects are presentations of durable domain entities rather than the source of truth. A transport-domain-presentation split, explicit coordinate adapter, semantic commands, capability-aware interaction, and resolvable anchors create a clean boundary between the XR toolkit and the spatial backend. That boundary supports responsive local interaction without sacrificing synchronization or portability.

Offline operation and conflict recovery

Many XR tasks happen in warehouses, field sites, or events with unreliable connectivity. Cache the project snapshot, required assets, and permitted operations before the session. Queue durable commands with client-generated IDs and base revisions. When connectivity returns, replay the queue in order and stop when a command conflicts or requires user review.

Not every action should be available offline. Mark commands by whether they can be safely queued, require fresh authorization, or depend on current shared state. A local annotation may queue cleanly; approving a safety-critical placement may require an online check. The interface should show which changes are pending and which have been accepted by the server.

When a conflict occurs, preserve the user’s proposal rather than silently discarding it. The domain layer can return current state and a reason, while Unity presents a comparison or asks the user to reapply the intent. This is more trustworthy than snapping an object to a new pose without explanation.

Production integration checklist

These patterns keep the XR interaction layer responsive while the domain layer remains auditable and resilient. They also make it practical to replace the network protocol or support a second client without rebuilding the Unity scene architecture.

  • Keep transport DTOs, domain entities, and GameObject presenters separate.
  • Use a registry keyed by durable entity ID rather than scene names.
  • Convert coordinates in one tested adapter with explicit frames and units.
  • Send semantic commands at commit points instead of streaming every local frame.
  • Cancel asset and network work when scenes or entities leave scope.
  • Expose permissions and locks through interaction filters and visible state.
  • Cache immutable asset versions and show proxies for failed or pending content.
  • Test domain behavior with mocks before spending device time.