The lifecycle of a Spatial Anchor allows it to be created, saved, erased, and destroyed. You can also share or receieve a shared spatial anchor. Each one of these possible lifecycle states is documented below with examples both in Blueprints and C++.
Recognize the functionalities covered by spatial anchors such as create, save, load, erase, destroy, and share.
Define the process of creating a spatial anchor using both Blueprint and C++.
Describe the process of destroying a spatial anchor with a using a blueprint or C++
A user can create a spatial anchor in their environment to create a stabilized transform that is tracked by the device and remains static even after headset position and orientation resets. Creating a spatial anchor requires specifying a valid location within the environment that will allow for localization.
Create a spatial anchor with Blueprints
In this example:
An actor is created at the location the anchor should be spawned at.
The latent action Create Spatial Anchor is called using the actor and transform as parameters.
If it succeeds execution continues, on failure the execution destroys the actor previously created.
Here is an example of calling the function and binding to the callback.
EOculusXRAnchorResult::Type SaveAnchors(const TArray<UOculusXRAnchorComponent*>& Components)
{
EOculusXRAnchorResult::Type OutResult; // Detailed immediate (non-async) result code
OculusXRAnchors::FOculusXRAnchors::SaveAnchors(
Components,
FOculusXRSaveAnchorsDelegate::CreateLambda([](
EOculusResult::Type Result,
const TArray<UOculusXRAnchorComponent*>& SavedAnchors)
{
// Post save anchors logic here
}),
OutResult
);
return OutResult;
}
Discover spatial anchors
A previously persisted spatial anchor can be found on the device or cloud storage using the Discover API. This is a filter based querying mechanism that allows you to find anchors that have been persisted via the Save API.
The discovery filters are objects you must create and pass into the function call in either Blueprints or C++. You can perform a discovery request with no filters and find every anchor in your environment, but typically you would want to either request anchors using a UUID filter or a Component Filter. See Scene Documentation for information on component filters.
The API signature also requires two callbacks to be present. One callback, Results, will fire every time there are anchors that are discovered and can be localized and provided to the user. The second callback, Complete, will only fire once all asynchronous work is complete.
It is possible to make a request, discover no anchors, and receive a Complete callback with a success code.
Discover spatial anchors with Blueprints
In this example:
A Discovery ID filter is created.
The filter is populated with Anchor UUIDs.
The filter is placed in a filter array.
The Discovery info struct is populated and passed to the Discover Anchors function.
The filter types are UOculusXRSpaceDiscoveryIdsFilter and UOculusXRSpaceDiscoveryComponentsFilter. You can create a filter in code using NewObject. See the code below for an example.
EOculusXRAnchorResult::Type DiscoverAnchors(const TArray<FOculusXRUUID>& UUIDsToFind)
{
EOculusXRAnchorResult::Type OutResult; // Detailed immediate (non-async) result code
// Create a filter object and assign UUIDs to it
UOculusXRSpaceDiscoveryIdsFilter* IdFilter = NewObject<UOculusXRSpaceDiscoveryIdsFilter>(this);
for(const auto& it : UUIDsToFind)
{
IdFilter.Uuids.Add(it);
}
// Create the info structure and add the filter we created to the filter list
FOculusXRSpaceDiscoveryInfo info;
info.Filters.Add(IdFilter);
OculusXRAnchors::FOculusXRAnchors::DiscoverAnchors(
info,
FOculusXRDiscoverAnchorsResultsDelegate::CreateLambda([](
const TArray<FOculusXRAnchorsDiscoverResult>& DiscoveredAnchors)
{
// Do something with the list of anchors you found
}),
FOculusXRDiscoverAnchorsCompleteDelegate::CreateLambda([](
EOculusXRAnchorResult::Type Result)
{
// All done! Check error code, etc...
}),
OutResult
);
return Outresult;
}
Erase spatial anchors
There are several ways to erase anchors with the Spatial Anchors API. You can erase using the Anchor Component pointers, you can erase by Anchor UUIDs, or Anchor Handles. Erasing by Anchor Component or by Anchor Handle are the typical use cases. In both scenarios you will only be able to erase anchors that are known to the runtime. i.e., they have been created or queried for in this session.
Erasing by UUID is unique in that an anchor does not have to be loaded by the runtime to be erased. This is helpful if you are trying to clean up anchors that are not able to be loaded by the app or that you do not wish to persist any longer.
Erase spatial anchors with Blueprints
In this example:
An array of actors with Spatial Anchor Components is passed to the Erase Anchors function.
In the Success case the list of erased anchors is iterated in a For Each loop.
Erase spatial anchors with C++
Component erase
The component erase function looks like the following:
TArray<FOculusXRUUID> AnchorUUIDs = … // Find the UUIDs of the anchors you want to erase, maybe from a save data file
EOculusXRAnchorResult::Type OutResult; // Detailed immediate (non-async) result code
OculusXRAnchors::FOculusXRAnchors::EraseAnchors(
TArray<FOculusXRUInt64>(), // Empty
AnchorUUIDs,
FOculusXRSaveAnchorsDelegate::CreateLambda([](
EOculusResult::Type Result,
const TArray<UOculusXRAnchorComponent*>& ErasedAnchors,
const TArray<FOculusXRUInt64>& ErasedAnchorHandles,
const TArray<FOculusXRUUID>& ErasedAnchorUUID)
{
// Post erase anchors logic here
}),
OutResult
);
Destroy a spatial anchor
This is a non async function that will destroy the anchor’s runtime representation. If the anchor has been saved, then the anchor will not be removed from persistent storage and you can still recover the anchor with DiscoverAnchors.
Destroy spatial anchors with Blueprints
Anchors will automatically be destroyed if you delete the actor or component associated with the spatial anchor. For example:
In this example, a component of type Oculus Spatial Anchor is passed into the function which will immediately destroy the internal anchor representation from the runtime. The developer is responsible for cleaning up any references to this component or actor state that may rely on it.
Sharing a spatial anchor allows multiple devices in the same environment to localize an anchor as a shared reference point and share associated content or scene data. For more information on sharing please see Anchor Sharing
Share spatial anchors with Blueprints
In this example:
There is an array of actors that each have a Spatial Anchor Component. There is also an array of strings representing User IDs.
These two arrays are passed as parameters to the Share Anchors function.
On success, the array of shared anchors is iterated over in a For Each loop.