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.
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}");