Using Wayspot Anchors

Use VPS Wayspot Anchors to place virtual objects that maintain a consistent, stable pose in an AR environment. Wayspot anchors allow you to precisely locate your AR content in the real world relative to a VPS-activated Wayspot or Private VPS Location. Wayspot Anchors can also be restored in future VPS sessions and shared between users of your app. Because Wayspot Anchors use position and orientation information relative to a VPS-activated Wayspot, you can set placement position with a much higher level of precision than just using GPS location.

Use Wayspot Anchors for scenarios where you need to place and share virtual content associated with VPS-activated Wayspots. Example scenarios include:

Place and find: Allow a user to place and persist virtual content near a VPS-activated Wayspot. At a future time, allow the user, or other users, to locate the object in the real world at the same location where it was placed using VPS.

Object discovery: You, or users of your app, can place virtual objects in the real world near VPS-activated Wayspots. Later, other users can discover these objects as they travel near the same real world locations.

Shared object interaction: Users collaborate at the same time with shared virtual objects when located together at the same VPS-activated Wayspot.

Note

VPS Wayspot Anchors should not be confused with ARDK AR anchors such as ARPlaneAnchor and ARImageAnchor. IARAnchor is not compatible with VPS Wayspot Anchors.

Once your app has successfully obtained camera and location service permissions, started a VPS session, and localized with a VPS-activated Wayspot, you can use the Wayspot Anchor API to place Wayspot Anchors relative to the VPS-activated Wayspot the user has localized with.

The VPS Wayspot Anchor API provides two interfaces. WayspotAnchorService is a straight-forward “high-level” API for creating and managing Wayspot Anchors, whereas WayspotAnchorController is a “low-level” API that you can use if you need more granular control. In your app you can use WayspotAnchorService or WayspotAnchorController but not both.

Note

Use of features such as VPS localization or the VPS Wayspot Anchors API involves the collection of personal information from your end user. For more information, see the Lightship ARDK Data Privacy FAQ.

Basic Flow

You can use the Wayspot Anchor API to create and place new Wayspot Anchors, or restore previously placed Wayspot Anchors. You can mix creating and restoring Anchors in your VPS session as needed. The basic flow for creating new Anchors is:

  1. Create and place a new Wayspot Anchor

  2. VPS Wayspots Anchor API returns a payload that you can persist for future restoring or sharing

  3. Use Anchors for placing GameObjects as needed

  4. Get Anchor tracking updates from the Wayspots Anchor API and use Anchor position updates to adjust GameObjects as needed

../../_images/anchors_create_flow.png

The basic flow for restoring Wayspot Anchors is similar, except you use your persisted payload information to restore the Anchors

../../_images/anchors_restore_flow.png

Enable Location Permissions

Because the VPS Wayspot Anchors API uses device camera and location information, you’ll need to make sure the user has enabled location permissions on their device. See Permissions for details on requesting device permissions.

Using WayspotAnchorService

WayspotAnchorService simplifies the process of localizing with VPS-activated Wayspots and working with Wayspot Anchors. WayspotAnchorService maintains a cache of Wayspot Anchors for you, and handles many of the low-level VPS events for you.

For an example of using WayspotAnchorService, see the WayspotAnchors sample in ARDK-examples.

Creating a Wayspot Anchor

To create a wayspot anchor, in your session where you’ve started VPS, call WayspotAnchorService.CreateWayspotAnchors() with your anchor positions and orientations in your local coordinate space. The current localization state must be LocalizationState.Localized before you create any anchors. WayspotAnchorService provides await async versions of CreateWayspotAnchors(), or you can provide a callback:

using Niantic.ARDK.AR.WayspotAnchors;

private void PlaceAnchor(Matrix4x4 localPose)
{
    _wayspotAnchorService.CreateWayspotAnchors(CreateAnchorGameObjects, localPose);
    // Alternatively, you can make this method async and create wayspot anchors using await:
    // var wayspotAnchors = await _wayspotAnchorService.CreateWayspotAnchorsAsync(localPose);
    // CreateAnchorGameObjects(wayspotAnchors);
}

The returned IWayspotAnchors will have an anchor ID that VPS assigns, that you’ll use to identify anchors tracked when the user position changes. IWayspotAnchor will also have a payload, a binary blob that you should save for when you want to restore previously created anchors, or share the anchor with other users.

private void CreateAnchorGameObjects(IWayspotAnchor[] wayspotAnchors)
{
    foreach (var wayspotAnchor in wayspotAnchors)
    {
        var id = wayspotAnchor.ID;
        _waypointAnchorGameObjects.Add(id, anchor);
    }
}

If you need to persist the Wayspot Anchors for restoring later, or for sharing between users of your app, see “Persisting and Sharing Wayspot Anchors” below for how to serialize and deserialize Wayspot Anchors.

Once a Wayspot Anchor has been created, you’ll also want to set up an event handler for tracking and updating the anchor position as the user moves, and also create any necessary child Game Objects of the anchor. See “Resolving Wayspot Anchor Pose as the User Position Changes” below for more details.

Restoring a Wayspot Anchor

To restore a Wayspot Anchor created in a prior VPS session, use WayspotAnchorService.RestoreWayspotAnchors(). The current localization state must be LocalizationState.Localized before you attempt to restore any anchors. You’ll provide a list of anchor payloads that contain all the information needed to restore the anchors relative to the VPS-activated Wayspot where they were placed:

using Niantic.ARDK.AR.WayspotAnchors;

// Deserialize/load saved payloads, using WayspotAnchorPayload.Deserialize() as needed
// var payloads = ...load payloads...
if (payloads.Length > 0)
{
    var wayspotAnchors = _wayspotAnchorService.RestoreWayspotAnchors(payloads);

    CreateAnchorGameObjects(wayspotAnchors);
}

If you need to load previously persisted Wayspot Anchor payloads see “Persisting and Sharing Wayspot Anchors” below for how to serialize and deserialize Wayspot Anchors.

RestoreWayspotAnchors() returns an array of IWayspotAnchors similar to what CreateWayspotAnchors() returns. Unlike CreateWayspotAnchors(), RestoreWayspotAnchors() returns synchronously and does not require an await async call or callback.

Just like when creating new anchors, you’ll want to set up an event handler for tracking and updating the anchor position as the player moves, and also create any necessary child Game Objects of the anchor. See “Resolving Wayspot Anchor Pose as the User Position Changes” below for more details.

Resolving Wayspot Anchor Pose as the User Position Changes

As the user moves and changes position and orientation relative to the VPS-activated Wayspot, Lightship VPS automatically updates its understanding of the updated environment. This may result in Lightship VPS making corrections to Wayspot Anchor position and orientation to ensure the Wayspot Anchor stays fixed in the same real-world position. Lightship VPS will send these corrections via events. In your event handler you can apply the corrected position information to child game objects of the Wayspot Anchor.

Corrected anchor position and orientation information is sent in a IWayspotAnchor.TrackingStateUpdated event. You’ll specify an event handler for this event when you create or restore a wayspot anchor:

foreach (var wayspotAnchor in wayspotAnchors)
{
    wayspotAnchor.TrackingStateUpdated += HandleWayspotAnchorTrackingUpdated;
    // ....
}

In your event handler, determine which anchor has been updated (via anchor ID) and adjust any child game object position information accordingly. For example:

private void HandleWayspotAnchorTrackingUpdated(WayspotAnchorResolvedArgs wayspotAnchorResolvedArgs)
{
    var anchor = _waypointAnchorGameObjects[wayspotAnchorResolvedArgs.ID].transform;
    anchor.position = wayspotAnchorResolvedArgs.Position;
    anchor.rotation = wayspotAnchorResolvedArgs.Rotation;
    // perform any GameObject refresh as well...
}

Deleting Wayspot Anchors

WayspotAnchorService manages a cache of Wayspot Anchors for you. If you no longer need to track one or more Wayspot Anchors, you can delete the Anchors from the cache using WayspotAnchorService.DestroyWayspotAnchors(), providing either a list of IWayspotAnchors or a list of anchor IDs.

using Niantic.ARDK.AR.WayspotAnchors;

Guid[] ids;

// ...populate ID array with Anchor IDs you want to remove...

// Delete anchors from cache using Anchor IDs
_wayspotAnchorService.DestroyWayspotAnchors(ids);

Restarting a VPS Session

If your app needs to restart the VPS session from scratch, you can use WayspotAnchorService.Restart(). See “Understanding Localization Flow” in Localizing with VPS for examples of when you might need to restart VPS. Also, see “Restarting VPS” in Localizing with VPS for additional details on what happens when you restart a VPS session.

Using WayspotAnchorController (For Advanced Users)

WayspotAnchorController provides a low-level interface for working with Wayspot Anchors. Use WayspotAnchorController if you need more flexibility, for example if you need to maintain your own cache of Wayspot Anchors.

For an example of using WayspotAnchorController, see the implementation of WayspotAnchorService.

For an example of creating a WayspotAnchorController instance, see “Using WayspotAnchorController” in Localizing with VPS.

Creating a Wayspot Anchor with WayspotAnchorController

First, set an event handler for WayspotAnchorController.WayspotAnchorsCreated wherever you create your WayspotAnchorController instance.

wayspotAnchorController.WayspotAnchorsCreated += HandleWayspotAnchorsCreated;

To create a Wayspot Anchor call WayspotAnchorController.CreateWayspotAnchors() with a list of anchor positions and orientations. The current localization state must be LocalizationState.Localized before you create any anchors. The call will make a request to the VPS backend and return an array of IDs of the created anchors. WayspotAnchorController will send a WayspotAnchorsCreated event once all of the Anchors are created.

using Niantic.ARDK.AR.WayspotAnchors;
private void PlaceWayspotAnchors(params Matrix4x4[] localPoses)
{
    // ...Verified we’ve localized with a VPS-activated Wayspot, the most recent WayspotController.LocalizationStateUpdated event should indicate LocalizationState.Localized...

    var ids = _wayspotAnchorController.CreateWayspotAnchors(localPoses);
    // ...Add IDs to cache...
}

private void HandleWayspotAnchorsCreated(WayspotAnchorsCreatedArgs wayspotAnchorsCreatedArgs)
{
    foreach (var anchor in wayspotAnchorsCreatedArgs.WayspotAnchors)
    {
        // Look up anchor.ID in our cache, add associated IWayspotAnchor
        if (!_wayspotAnchors.ContainsKey(anchor.ID))
        {
            _wayspotAnchors.Add(anchor.ID, anchor);
        }
    }
}

The created IWayspotAnchor instances will have a payload, a binary blob that you should save for when you want to restore previously created anchors, or share the anchor with other users.

You may need to persist Wayspot Anchors for restoring later, or for sharing between users of your app. See “Persisting and Sharing Wayspot Anchors” below for how to serialize and deserialize Wayspot Anchors.

Restoring a Previously Created Wayspot Anchor with WayspotAnchorController

To restore a Wayspot Anchor created in a prior VPS session, use WayspotAnchorController.RestoreWayspotAnchors(). The current localization state must be LocalizationState.Localized before you attempt to restore any anchors. You’ll provide a list of anchor payloads that identify which anchors need to be restored:

using Niantic.ARDK.AR.WayspotAnchors;

// Deserialize/load saved payloads, using WayspotAnchorPayload.Deserialize() as needed
// var payloads = ...load payloads...
if (payloads.Length > 0)
{
    var wayspotAnchors = _wayspotAnchorController.RestoreWayspotAnchors(payloads);

    CreateAnchorGameObjects(wayspotAnchors);
}

If you need to load previously persisted Wayspot Anchor payloads see “Persisting and Sharing Wayspot Anchors” below for how to serialize and deserialize Wayspot Anchors.

Resolving Wayspot Anchor Pose as the User Position Changes with WayspotAnchorController

As the user moves and changes position and orientation relative to the VPS-activated Wayspot, Lightship VPS automatically updates its understanding of the updated environment. This may result in Lightship VPS making corrections to Wayspot Anchor position and orientation to ensure the Wayspot Anchor stays fixed in the same real-world position. Lightship VPS will send these corrections via events. In your event handler you can apply the corrected position information to child game objects of the Wayspot Anchor.

To get Anchor tracking updates with WayspotAnchorController, you’ll need to register an event handler for WayspotAnchorController.WayspotAnchorsTrackingUpdated.

using Niantic.ARDK.AR.WayspotAnchors;

_wayspotAnchorController.WayspotAnchorsTrackingUpdated += HandleWayspotAnchorsResolved;

In your event handler, determine which anchors have been updated (via anchor ID) and adjust any child game object position information accordingly. For example:

private void HandleWayspotAnchorsResolved(WayspotAnchorsResolvedArgs wayspotAnchorsResolvedArgs)
{
    foreach (var resolution in wayspotAnchorsResolvedArgs.Resolutions)
    {
        // Look up Anchor by ID in our cache
        var wayspotAnchor = _wayspotAnchors[resolution.ID];

        // ...Update associated GameObjects using resolution.Position and resolution.Rotation...
        }
    }
}

Pausing Wayspot Anchor Tracking

Your AR experience might use many Wayspot Anchors, however you might not need to track and display associated game objects all the time. For example, you might have a game object used to help players visualize placement during a specific mode of your game, that you don’t need to track (or display) in other game modes. You can pause tracking for VPS Wayspot Anchors in these situations to reduce computational and network overhead.

To pause anchor tracking, use WayspotAnchorController.PauseTracking() with the wayspot anchor IDs that don’t need to be tracked.

Stopping a VPS Session

If you no longer need to create or track any Wayspot Anchors, you can stop the VPS service without stopping your AR session. You might need to do this if your AR experience needs to provide AR features when your users are not near any VPS-activated Wayspots. For example, if your users are traveling between different VPS-activated Wayspots, but you still want to display some virtual objects using AR depth, or AR meshing.

You might also need to stop and restart a VPS session when your app encounters localization issues. See “Understanding Localization Flow” in Localizing with VPS for examples of when you might need to restart VPS. Also, see “Restarting VPS” in Localizing with VPS for additional details on what happens when you restart a VPS session.

Stop the VPS session using WayspotAnchorController.StopVps(). Note that any in-progress Wayspot Anchor creation or tracking will be canceled.

Persisting and Sharing Wayspot Anchors

To be able to restore Wayspot Anchors, you’ll need to persist the Wayspot Anchor payload. WayspotAnchorPayload has convenience Serialize() and Deserialize() methods you can use that convert the payload data into a Base64 string representation. You can then persist this string in your app, in your cloud, and/or share it with other users.

Wayspot Anchors and Mock Mode

You can place and restore Wayspot Anchors in Virtual Studio Mock Mode. VPS will simulate a fake localization and be localized after 300 milliseconds when you run in Mock Mode in the Unity editor. You can then use WaypointAnchorService or WaypointAnchorController to place and restore Wayspot Anchors, and the Wayspot Anchors API will automatically use a mock anchor implementation for these anchors.

Note that the anchor payloads that are returned for mock anchors should not be used outside of Mock Mode. Attempts to restore an anchor using a mock anchor payload when running on the device will fail.

See Playing in Mock Mode for more details on running in Mock Mode.

Wayspot Anchors Best Practices

When placing Anchors, there may be a very small delay before your app receives the payload for the Anchor. If your user is interactively placing Anchors, we recommend rendering the game objects associated with the Anchor immediately rather than waiting for the returned payload, to avoid any perceived lag with displaying the placed objects.