Search code examples
unity-game-enginehololensazure-spatial-anchors

Azure Spatial Anchor : share anchor async


I'm trying to share my anchor between multiple devices using Azure Spatial Anchor Cloud.

The problem
I can create and save an anchor on Azure Spatial Anchor Cloud but I can not retrieve it on the other device.

What I've tried
I tried to add .ShareAsync() and .ShareAnchorAsync() in order to be able to use .GetAnchorAsync in order to retrieve every created anchor on my other device but I get the following error : 'CloudSpatialAnchor' does not contain a definition for 'ShareAnchorAsync' and no accessible extension method 'ShareAnchorAsync' accepting a first argument of type 'CloudSpatialAnchor' could be found

Here is my anchor creating code :

    private async Task CreateAnchor(Vector3 position)
    {
        if (!InputDevices.GetDeviceAtXRNode(XRNode.Head).TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 headPosition))
        {
            headPosition = Vector3.zero;
        }

        Quaternion orientationTowardsHead = Quaternion.LookRotation(position - headPosition, Vector3.up);

        GameObject anchorGameObject = GameObject.Instantiate(_CubePrefab);
        anchorGameObject.GetComponent<MeshRenderer>().material.color = Color.white;
        anchorGameObject.transform.position = position;
        anchorGameObject.transform.rotation = orientationTowardsHead;
        anchorGameObject.transform.localScale = Vector3.one * 0.1f;

        //Add and configure ASA components
        CloudNativeAnchor cloudNativeAnchor = anchorGameObject.AddComponent<CloudNativeAnchor>();
        if (cloudNativeAnchor.CloudAnchor == null)
        {
            await cloudNativeAnchor.NativeToCloud();
        }
        CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;

        CloudSpatialAnchor cloudSpatialAnchor = new CloudSpatialAnchor();
        cloudSpatialAnchor.LocalAnchor = await anchorGameObject.FindNativeAnchor().GetPointer();
        if (cloudSpatialAnchor.LocalAnchor == IntPtr.Zero)
        {
            return;
        }

        while (!_spatialAnchorManager.IsReadyForCreate)
        {
            await Task.Delay(330);
            float createProgress = _spatialAnchorManager.SessionStatus.RecommendedForCreateProgress;
            _TxtDebug.text = $"Déplacer le téléphone jusqu'à que le cube devienne vert: {createProgress:0%}%";
        }
        _TxtDebug.text = "";
        try
        {
            await _spatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor);
            bool saveSucceeded = cloudSpatialAnchor != null;
            if (!saveSucceeded)
            {
                return;
            }
            _foundOrCreatedAnchorGameObjects.Add(anchorGameObject);
            _createdAnchorIDs.Add(cloudSpatialAnchor.Identifier);
            //await cloudSpatialAnchor.ShareAnchorAsync();
            anchorGameObject.GetComponent<MeshRenderer>().material.color = Color.green;
        }
        catch (Exception exception)
        {
            UnityEngine.Debug.Log("ASA - Failed to save anchor: " + exception.ToString());
            UnityEngine.Debug.LogException(exception);
        }
    }

I just want to be able to retrieve every anchor created on an other device. Both device use the same configuration credentials so it shouldn't be an issue to be able to retrieve every anchor.

[EDIT] I'm now trying to use a custom identifier so I added this in the anchor creation :

            string anchorId = "myCustomLabel";
            cloudSpatialAnchor.AppProperties["customIdentifier"] = anchorId;
            // Now that the cloud spatial anchor has been prepared, we can try the actual save here.
            await _spatialAnchorManager.CreateAnchorAsync(cloudSpatialAnchor);

In order to retrieve it like this :

        AnchorLocateCriteria criteria = new AnchorLocateCriteria();
        criteria.Identifiers = new string[] { @"myCustomLabel"};
        _spatialAnchorManager.Session.CreateWatcher(criteria);

but it isn't the right solution yet


Solution

  • It's not enough to call the same code from multiple devices and expect to find the same anchor. In order to achieve ASA sharing, you'll need persistent sharing or even have your self-hosted web service.

    As a quick debug step, try to add Debug.Log through your code to pinpoint the issue. ASA have its own logging and diagnostics methods. Our public ASA samples can be found here , including SharingServiceSample