This repo contains a basic plugin that you can use in your Unity projects to easily use the Azure Spatial Anchors Service. There is also a DEMO Unity project that shows the use of the plugin. As the current implementation of the Azure Spatial Anchors Service Preview (May 2019) doesn’t provide a way to retrieve anchor ID’s, a seperate ASP.NET Core solution is included to store a single anchor ID. The TokenServer can be run locally on a machine or it can be deployed on Azure Web Apps.
The solution makes use of pieces from the Azure Spatial Anchors official samples here but it does not use all of the pieces.
The plugin is created as an extension service for the MixedRealityToolkit V2 RC1. We use a basic configuration profile for the editor to configure the service.
Note that Azure Spatial Anchors supports 2 methods of authentication - here, we have only made use of the ID/Key based authentication mechanism. We have not attempted to make use of Azure Active Directory way of authenticating.
Using the plugin
Download and import the MixedRealityToolkit v2 RC1
Go to the MRTK release page.
Under Assets, and download
Microsoft.MixedRealityToolkit.Unity.Foundation.unitypackage. In your Unity project, select Assets > Import Package > Custom Package and then select the unitypackage file you previously downloaded. In the Import Unity Package dialog box, make sure all files are selected and then select Import.
Download and import the Azure Spatial Anchors Plugin
Download the AzureSpatialAnchors UnityPackage. In your Unity project, select Assets > Import Package > Custom Package and then select the unitypackage file you previously downloaded. In the Import Unity Package dialog box, make sure all files are selected and then select Import.
For iOS: download and copy the Unity ARKit Plugin
Download Unity ARKit Plugin version 2.0.0 and extract the archive. Copy the contents of the
Assets folder to your project’s
For Android: download and copy the ARCore SDK for Unity
Download ARCore SDK for Unity 1.7 release. In your Unity project, select Assets > Import Package > Custom Package and then select the unitypackage file you previously downloaded. In the Import Unity Package dialog box, make sure all files are selected and then select Import.
Configure the MixedRealityToolkit Extension Service for the Azure Spatial Anchors Plugin
Click the MixedRealityToolkit in your scene.
This will show the MRTK Active Profile in the properties window.
Scroll down to the Extension Services section, clone the confuguration and click Show Registered Services if it’s not open already. Next, click Register a new Service Provider.
Give the new service a name (e.g. “Azure Spatial Anchor Service”) and click on **Component Type"to select AzureSpatialAnchors > AzureSpatialAnchorsService.
Clone the default configuration by clicking on Clone. In the dialog that pops up, give the cloned configuration a name. E.g. “AzureSpatialAnchorsConfiguration”. Then click clone.
In the configuration you’ll see these fields:
- Azure Account Id - get this from the Azure portal in the Azure Spatial Acnhor Service you created on the Overview page.
- Authentication Mode - leave this on Key
- Azure Service Key - get the Key from the Keys part of the Azure Spatial Acnhor Service you create in the Azure portal.
- Token Server Endpoint - the URL of the deployed TokenServer (either local address or Azure WebApp address).
Folders in the Repo
There are 3 folders in the repo;
- UnityProject - this is a DEMO project which also contains all of the source that we have for the plugin.
- TokenServer - this is an ASP.NET Core 2.2 WebApi project which provides a REST API for storing a single token (anchor ID) in the cloud, retrieving it and clearing it out.
- UnityPackages - this is a folder with pre-exported Unity packages containing the pieces from the UnityProject which are intended for re-use rather than just for demonstration.
This is a very basic project. It displays a cube 1.5m in front of the user and then there are 3 voice commands (which require focus on the cube).
- “create” - this takes the WorldAnchor that is attached to the cube, passes it into the AzureSpatialAnchorsService using the CreateAnchorInStoreAsync method. That method will then call the Azure Spatial Anchors service to create an anchor. If the service is not ready to create an anchor, then the event CreateReadinessUpdated will be fired repeatedly with a floating point value (0-1) to indicate how much more “scanning” the user should do to get the service ready. Once ready, the service will fire the ReadyForCreate event. At this point, the anchor is uploaded to the cloud, an ID is created and that ID is then sent to the token service in the cloud for storage.
- “populate” - this calls the PopulateAnchorFromStoreAsync method on the AzureSpatialAnchorsService. This method will call the token server to see if there is a persisted ID in the cloud. If so, it will call the Azure Spatial Anchors service to download that anchor and return it.
- “delete” - this command expects that either the create or populate commands have already been executed so that (either way) a cloud anchor is loaded. It then calls the DeleteAnchorInStoreAsync method on the AzureSpatialAnchorsService which will delete the anchor in the cloud and also call the token server to delete the ID stored as well.
The pieces of the project that are intended for re-use here are highlighted in the image below;
AzureSpatialAnchorsPlugin is content taken directly from the Azure Spatial Anchors Sample on github - note that if you put this into a sub-folder then the build scripts that are contained within will stop working so it is perhaps best to leave it in the root folder as it is here (or change the scripts).
AzureSpatialAnchorExtensions is custom code and provides the following classes;
IAzureSpatialAnchorService- the interface for interactions with the anchor functionality. This plugs in to the MixedRealityToolkit such that you can access it via
AzureSpatialAnchorService- the implementation of the interface making use of both the SDK for Azure Spatial Anchors and the token Server.
AzureSpatialAnchorServiceProfile- the basic profile that provides the settings which the
AzureSpatialAnchorServiceneeds to operate - specifically, a key and ID for Azure Spatial Anchors and a URL for the endpoint of the deployed token Server.
TokenClient/TokenClient- a proxy for accessing the token Server.
Profiles/DefaultAzureSpatialAnchorsServiceProfile- the default profile for the configuration of the AzureSpatialAnchorsService
The service is plugged into the MixedRealityToolkit as in the image below. You would need to (at least) make your own configuration for the toolkit (by cloning the default one) and then go to the “Extension Services” where you can add a new service, choose the “AzureSpatialAnchorsService”.
And the default profile will need to be cloned/changed because it is empty as below. Note that you can create one of these profiles in the editor by using the right mouse menu to Create->Mixed Reality Toolkit->Azure Spatial Anchors Profile.
Re-using the Pieces from the Unity Project
With the toolkit configured as described in the previous section, the expected flow for using the
IAzureSpatialAnchorsService would be as below;
- The application would run up.
- The application code can access the service via
var service = MixedRealityToolkit.Instance.GetService<IAzureSpatialAnchorsService>();
- The application would create a root object that is to be anchored.
- The application would call the
StartSessionmethod to start the cloud anchor session.
- The application would call the
PopulateAnchorFromStoreAsync- this method will return whether there is already an anchor persisted in the cloud and, if so, it will be set as the underlying anchor for the
GameObjectpassed (one is added if it is not already there). The return value indicates the status of the anchor - it may not exist, it may exist and be located or it may exist and not be located.
- If the anchor does not exist or cannot be located then the object should be positioned manually (using markers etc) and then the method
CreateAnchorInStoreAsynused to store the anchor in the cloud. You can pass a
WorldAnchoron it. This function also polls the cloud so a polling interval needs to be provided too. There is a chance that the session is not ready to create anchors. If so, it will fire the events
ReadyForCreateand you can display some UI to tell the user to move around and scan more space. Once created, the method returns success/failure.
- If there is a need to reset the environment, you need to first have loaded the anchor either via the
Populatemethods and then you can use the
DeleteAnchorInStoreAsyncmethod to delete the anchor from the cloud.
This folder contains one Visual Studio solution with two projects in it:
AzureSpatialAnchors.TokenServer- the server solution
AzureSpatialAnchors.TokenClient.SDK- the client proxy for accessing the server API.
AzureSpatialAnchors.TokenClient- a test client to see what’s in the store. It also provides an interface to set and clear the stored ID.
As the Azure Spatial Anchor Service Preview (May 2019) doesn’t provide a way to query for ID’s of stored anchors, a separate server is needed to store the ID. We created a simple one storing just one ID at the moment.
The ID is used to get a world anchor from the Azure Spatial Anchors Service. Currently this is the only way to share one ID over multiple machines. The server is a ASP.NET Core 2.2 server that runs on port 8000 locally or however it’s configured in Azure. It provides a REST service on
/api/Token. Swagger info is available on
/swagger/v1/swagger.json, and the API can be tested on
/swagger There are 3 methods implemented
- Get - get the stored token
- Post - put an ID in storage
- Delete - clear the token in storage
This means that this service currently only stores 1 ID, which is good enough for the demo.
Running the server on a local machine
Create a publishing package to publish to the file system. Right click the
AzureSpatialAnchors.TokenServer project and select
In the dialog select Folder as target and choose a folder to publish to. By default the publised server relies on the runtime to be installed on the machine. ASP.NET Core 2.2 is required on the machine to run it. Go to https://dotnet.microsoft.com/download/dotnet-core/2.2 and install the latest ASP.NET Core/.NET Core Runtime & Hosting Bundle.
To start the server execute the command
Running the service in Azure
If you want to deploy the service to Azure, use the Publish menu-option. To do that, right click the
AzureSpatialAnchors.TokenServer project and select Publish
In the dialog that appears, select an existing App Service or create a new one to host the service.
To create a new one use the default selected Create New and click Publish. A new dialog is shown with the options for the new to be created App Service:
Select the account for the Azure subsription, give the service a name, select the correct subscription, select a resource group or create a new one and select a hosting plan or create a new one. For the hosting plan a Free size server is sufficient to run the service.
This is a Universal Windows Platform (UWP) app that can be used to test the client actions against the TokenServer. You can set an ID, get the ID and clear the ID. NSwagStudio was used against the swagger info to generate a client class
TokenClient.cs, which is available in the
AzureSpatialAnchors.TokenClient.SDK project. Use this class if you want to access the server. Using the client class is simple.
To create the client, use this code:
TokenClient client; client = new TokenClient(new System.Net.Http.HttpClient()); client.BaseUrl = "http://[servername or IP address]:8000";
To put an ID in storage:
await client.PostAsync("AN ID");
To retrieve the ID in storage:
string id = await client.GetAsync();
To clear storage:
Unity Packages Folder
This folder contains an exported package of the pieces that are intended for re-use as described in the Unity Project section of this readme.