Web Integration

This page covers driving the AR SDK from a web application loaded in a WebView. Commands go out via Unity.call(...) and events come back via a global onUnityMessage(...) function. For the shared concepts and the list of AR object types, see the AR SDK Overview page.

Getting Started

Initialization Flow

Follow this sequence when initializing the AR SDK:

  1. Get screen size - Always run getScreenSize() and send windowSize on load
  2. Set environment - Configure the backend environment
  3. Set tour info - Load the specific 3D model/tour
  4. Start localization - Begin the visual positioning process

Example Initialization

// Get screen dimensions
const screenSize = getScreenSize();

// Initialize the SDK
Unity.call(JSON.stringify({
  type: 'windowSize',
  data: { width: screenSize.width, height: screenSize.height }
}));

// Set environment
Unity.call(JSON.stringify({
  type: 'setEnvironment',
  data: { environment: 'Production' } // or 'Stage'
}));

// Load tour
Unity.call(JSON.stringify({
  type: 'setTourInfo',
  data: { 
    slug: 'your-tour-slug',
    matterId: 'your-matter-id'
  }
}));

// Start localization
Unity.call(JSON.stringify({
  type: 'startLocalization',
  data: {}
}));

Outbound Commands

Commands are sent from your web application to the AR SDK using Unity.call().

Command Reference

Command Data Payload Description
setEnvironment { environment: "Production" | "Stage" } Configures the backend environment
setTourInfo { slug: string, matterId: string } Loads the specific 3D model/tour
windowSize { width: number, height: number } Calibrates SDK viewport dimensions
startLocalization {} Begins the visual positioning process
manualRelocalize {} Resets tracking and starts localization over
startNavigation { toSweepId: string, destinationName: string } Generates a 3D path to the destination
stopNavigation {} Clears current navigation path
teleportConfirm {} Acknowledges transition (e.g., entered an elevator)
teleportEnd {} Resumes normal navigation after transition
showARObject { id: string, type: string } Sets an AR element to visible
hideARObject { id: string, type: string } Sets an AR element to hidden
clickCoords { x: number, y: number } Sends touch coordinates for 3D interaction

Command Examples

// Start navigation to a destination
Unity.call(JSON.stringify({
  type: 'startNavigation',
  data: {
    toSweepId: 'sweep-123',
    destinationName: 'Conference Room A'
  }
}));

// Stop navigation
Unity.call(JSON.stringify({
  type: 'stopNavigation',
  data: {}
}));

AR Object Visibility

// Show an AR object
Unity.call(JSON.stringify({
  type: 'showARObject',
  data: {
    id: 'object-123',
    type: 'TAG'
  }
}));

// Hide an AR object
Unity.call(JSON.stringify({
  type: 'hideARObject',
  data: {
    id: 'object-123',
    type: 'TAG'
  }
}));

Teleport Handling

// Confirm teleport (e.g., user entered elevator)
Unity.call(JSON.stringify({
  type: 'teleportConfirm',
  data: {}
}));

// End teleport (resume normal navigation)
Unity.call(JSON.stringify({
  type: 'teleportEnd',
  data: {}
}));

SDK → WebView Direct JS Calls

The SDK can directly call JavaScript functions in your web application:

  • onNavigationComplete() - Called when navigation completes
  • onNavigationTeleport() - Called for teleport navigation
  • onARObjectClick(id, type) - Called when AR objects are clicked

Inbound Events

The SDK sends events to your web application through the onUnityMessage function. Each message is a JSON string containing a type and data field.

Event Listener Setup

function onUnityMessage(message) {
  const event = JSON.parse(message);
  
  switch (event.type) {
    case 'localization_status':
      handleLocalizationStatus(event.data);
      break;
    case 'localizationWarning':
      showLocalizationWarning(event.data);
      break;
    case 'localizationSuccess':
      showLocalizationSuccess(event.data);
      break;
    case 'warning':
      showWarning(event.data);
      break;
    case 'info':
      showInfo(event.data);
      break;
    case 'onNavigationComplete':
      handleNavigationComplete(event.data);
      break;
    case 'onNavigationTeleport':
      handleNavigationTeleport(event.data);
      break;
    case 'onARObjectClick':
      handleARObjectClick(event.data);
      break;
  }
}

Event Types

Status & Feedback Events

localization_status

  • Updates on the tracking state
  • Common values: "Success", "Searching"
  • Use this to provide user feedback about localization progress

localizationWarning

  • Fired when there's a localization warning
  • Use this to show a warning toast to the user

localizationSuccess

  • Fired when localization succeeds
  • Use this to show a success toast and hide any warning toasts

warning

  • Environmental warnings
  • Examples: "Low Light", "Point at floor"
  • Display these warnings to guide the user

info

  • General system status updates
  • Use for informational messages

onNavigationComplete

  • Fired when the destination is reached
  • No data payload

onNavigationTeleport

  • Fired when the path requires a manual transition move
  • User should call teleportConfirm and teleportEnd to handle the transition

Interaction Events

onARObjectClick

  • Fired when a 3D object is tapped
  • Returns { id: string, type: string } of the tapped object

Event Handling Examples

// Handle localization status updates
function handleLocalizationStatus(data) {
  if (data === 'Success') {
    showToast('Localization successful!');
  } else if (data === 'Searching') {
    showToast('Searching for position...');
  }
}

// Handle warnings
function showWarning(data) {
  showToast(`Warning: ${data}`, 'warning');
}

// Handle AR object clicks
function handleARObjectClick(data) {
  console.log('AR Object clicked:', data.id, data.type);
  // Handle the click event, e.g., show details, navigate, etc.
}

// Handle navigation completion
function handleNavigationComplete() {
  showToast('You have reached your destination!');
}

UI Integration Best Practices

User Feedback

Your UI should listen for localization_status, localizationWarning, localizationSuccess, and warning event types to provide user feedback:

function onUnityMessage(message) {
  const event = JSON.parse(message);
  
  // Show toast notifications for status updates
  if (event.type === 'localization_status') {
    showToast(`Localization: ${event.data}`);
  }
  
  // Show localization warnings
  if (event.type === 'localizationWarning') {
    showWarningToast(event.data);
  }
  
  // Show localization success and hide warnings
  if (event.type === 'localizationSuccess') {
    hideWarningToast();
    showSuccessToast(event.data);
  }
  
  // Show warnings prominently
  if (event.type === 'warning') {
    showWarningToast(event.data);
  }
  
  // Show info messages
  if (event.type === 'info') {
    showInfoToast(event.data);
  }
}

Error Handling

Always wrap SDK calls in try-catch blocks and handle potential errors:

function sendSDKCommand(type, data) {
  try {
    Unity.call(JSON.stringify({ type, data }));
  } catch (error) {
    console.error('Failed to send SDK command:', error);
    showError('Failed to communicate with AR SDK');
  }
}

Complete Integration Example

Here's a complete example of integrating the AR SDK:

// Initialize SDK
function initializeARSDK(environment, slug, matterId) {
  // Get and set window size
  const size = getScreenSize();
  Unity.call(JSON.stringify({
    type: 'windowSize',
    data: { width: size.width, height: size.height }
  }));
  
  // Set environment
  Unity.call(JSON.stringify({
    type: 'setEnvironment',
    data: { environment }
  }));
  
  // Load tour
  Unity.call(JSON.stringify({
    type: 'setTourInfo',
    data: { slug, matterId }
  }));
  
  // Start localization
  Unity.call(JSON.stringify({
    type: 'startLocalization',
    data: {}
  }));
}

// Handle SDK messages
function onUnityMessage(message) {
  const event = JSON.parse(message);
  
  switch (event.type) {
    case 'localization_status':
      updateLocalizationUI(event.data);
      break;
    case 'localizationWarning':
      showLocalizationWarning(event.data);
      break;
    case 'localizationSuccess':
      showLocalizationSuccess(event.data);
      break;
    case 'warning':
      showWarning(event.data);
      break;
    case 'info':
      showInfo(event.data);
      break;
    case 'onNavigationComplete':
      onDestinationReached();
      break;
    case 'onNavigationTeleport':
      promptTeleport();
      break;
    case 'onARObjectClick':
      handleObjectInteraction(event.data);
      break;
  }
}

// Start navigation
function navigateToDestination(sweepId, destinationName) {
  Unity.call(JSON.stringify({
    type: 'startNavigation',
    data: { toSweepId: sweepId, destinationName }
  }));
}

// Handle teleport
function confirmTeleport() {
  Unity.call(JSON.stringify({ type: 'teleportConfirm', data: {} }));
  // After transition completes
  Unity.call(JSON.stringify({ type: 'teleportEnd', data: {} }));
}