Home > Software engineering >  Could not obtain the ARAnchor.nativePtr
Could not obtain the ARAnchor.nativePtr

Time:12-20

I'm currently trying to save a Spatial Anchor to the Azure Spatial Anchor Cloud on an Android device.

The problem
I keep getting the following error:

InvalidOperationException: Could not obtain the ARAnchor.nativePtr

What I've tried
This is my code where I create the Anchor and try to save it on the Azure Spatial Anchor Cloud :

    private async Task CreateAnchor(Vector3 position)
    {
        //...
        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(); }
        // here is the error it can't do cloudNativeAnchor.NativeToCloud();
        CloudSpatialAnchor cloudSpatialAnchor = cloudNativeAnchor.CloudAnchor;
        cloudSpatialAnchor.Expiration = DateTimeOffset.Now.AddDays(3);

        //...
    }

What I noticed is that I can't make it through await cloudNativeAnchor.NativeToCloud() because it then returns InvalidOperationException: Could not obtain the ARAnchor.nativePtr

I use Unity 2020.3.30f1, ASA 2.13.3, AR Core XR Plugin 4.1.13, MRTK 2.8.2

[UPDATE] I tried also like this :

        //Add and configure ASA components
        CloudNativeAnchor cloudNativeAnchor = anchorGameObject.AddComponent<CloudNativeAnchor>();
     
        // Then we create a new local cloud anchor
        CloudSpatialAnchor cloudSpatialAnchor = new CloudSpatialAnchor();
        // Now we set the local cloud anchor's position to the native XR anchor's position
        cloudSpatialAnchor.LocalAnchor = await anchorGameObject.FindNativeAnchor().GetPointer();
        // Check to see if we got the local XR anchor pointer
        if (cloudSpatialAnchor.LocalAnchor == IntPtr.Zero)
        {
            UnityEngine.Debug.Log("Didn't get the local anchor...");
            return;
        }
        else
        {
            UnityEngine.Debug.Log("Local anchor created");
        }

but the GetPointer() returns null

CodePudding user response:

Adding the following code solved the issue about the pointer being null :

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

        CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;

then the rest of the script is the same as in my post

CodePudding user response:

For the code above, this should point to an existing local anchor first to be valid. Example, here is reference to those docs at Microsoft site for ASA showing how this is setup prior to the cloudNativeAnchor.NativeToCloud() call.

https://learn.microsoft.com/en-us/azure/spatial-anchors/how-tos/create-locate-anchors-unity#create-a-cloud-spatial-anchor

Example:

    // Create a local anchor, perhaps by hit-testing and spawning an object within the scene
    Vector3 hitPosition = new Vector3();
#if UNITY_ANDROID || UNITY_IOS
    Vector2 screenCenter = new Vector2(0.5f, 0.5f);
    List<ARRaycastHit> aRRaycastHits = new List<ARRaycastHit>();
    if(arRaycastManager.Raycast(screenCenter, aRRaycastHits) && aRRaycastHits.Count > 0)
    {
        ARRaycastHit hit = aRRaycastHits[0];
        hitPosition = hit.pose.position;
    }
#elif WINDOWS_UWP || UNITY_WSA
    RaycastHit hit;
    if (this.TryGazeHitTest(out hit))
    {
        hitPosition = hit. Point;
    }
#endif

    Quaternion rotation = Quaternion.AngleAxis(0, Vector3.up);
    this.localAnchor = GameObject.Instantiate(/* some prefab */, hitPosition, rotation);
    this.localAnchor.AddComponent<CloudNativeAnchor>();

    // If the user is placing some application content in their environment,
    // you might show content at this anchor for a while, then save when
    // the user confirms placement.
    CloudNativeAnchor cloudNativeAnchor = this.localAnchor.GetComponent<CloudNativeAnchor>();
    if (cloudNativeAnchor.CloudAnchor == null) { await cloudNativeAnchor.NativeToCloud(); }  
    CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;
    await this.cloudSession.CreateAnchorAsync(cloudAnchor);
    this. Feedback = $"Created a cloud anchor with ID={cloudAnchor.Identifier}");
  • Related