/// <summary> /// Creates an anchor at the Shared World Anchor's position and orientation /// </summary> /// <returns>The asynchronous Task that for this asynchronous function that will return the status of the anchor creation.</returns> public async Task <bool> CreateAnchorAsync() { // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere. WorldAnchor worldAnchor = SharedWorldAnchor.Instance.gameObject.AddComponent <WorldAnchor>(); // In Editor, don't bother if (Application.isEditor) { // Simulate that we have found an anchor CloudSpatialAnchorId = FakeCloudSpatialAnchorId; return(true); } // Create the CloudSpatialAnchor. currentCloudAnchor = new CloudSpatialAnchor(); currentCloudAnchor.Expiration = DateTimeOffset.Now.AddDays(1); // Save the CloudSpatialAnchor to the cloud. currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr(); // Wait for enough data about the environment. while (recommendedForCreate < 1.0F) { await Task.Delay(330); } bool success = false; try { await CloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor); success = currentCloudAnchor != null; if (success) { // Record the identifier to locate. CloudSpatialAnchorId = currentCloudAnchor.Identifier; Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + CloudSpatialAnchorId); } else { Debug.LogError("ASA Error: Failed to save, but no exception was thrown."); } return(success); } catch (Exception ex) { Debug.LogError("ASA Error: " + ex.Message); } return(false); }
/// <summary> /// Gets the native anchor pointer. /// </summary> /// <param name="source">The source.</param> /// <returns>The native anchor <see cref="IntPtr" />.</returns> /// <exception cref="System.ArgumentNullException">source</exception> /// <exception cref="System.NullReferenceException"></exception> public static IntPtr GetNativeAnchorPointer(this GameObject source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } IntPtr retval = IntPtr.Zero; #if UNITY_IOS UnityARUserAnchorComponent unityARUserAnchorComponent = source.GetComponent <UnityARUserAnchorComponent>(); if (unityARUserAnchorComponent != null) { Debug.LogFormat("User anchor {0}", unityARUserAnchorComponent.AnchorId); retval = unityARUserAnchorComponent.GetAnchorPointer(); } #elif UNITY_ANDROID UnityARCoreWorldAnchorComponent anchorComponent = source.GetComponent <UnityARCoreWorldAnchorComponent>(); if (anchorComponent != null) { Debug.LogFormat("User anchor {0}", anchorComponent.WorldAnchor.m_NativeHandle); retval = anchorComponent.WorldAnchor.m_NativeHandle; } #elif WINDOWS_UWP WorldAnchor worldAnchor = source.GetComponent <WorldAnchor>(); if (worldAnchor != null) { retval = worldAnchor.GetNativeSpatialAnchorPtr(); } #else throw new PlatformNotSupportedException("Unable to retrieve the native anchor pointer. The platform is not supported."); #endif if (retval == IntPtr.Zero) { Debug.LogError("Didn't find AR anchor on gameobject"); } return(retval); }
/// <summary> /// Creates an Azure Spatial Anchor at the position of the local World Anchor attached to the Litecoin symbol game object. Destroys the Litecoin symbol and instantiates the slate prefab. /// </summary> public void CreateAzureSpatialAnchor() { #if UNITY_EDITOR if (!IsSlateActive) { GameObject litecoin = GameObject.FindGameObjectWithTag("Litecoin"); GameObject slate = Instantiate(SlatePrefab, litecoin.transform.position, litecoin.transform.rotation); Destroy(litecoin); IsSlateActive = true; Instructions.text = "Azure Spatial Anchor sessions can't be started when running in the Unity Editor. Build and deploy this sample to a HoloLens device to be able to create and find Azure Spatial Anchors.\n\nLook at the slate and it will detect your gaze and update itself."; } else { Instructions.text = "Azure Spatial Anchor sessions can't be started when running in the Unity Editor. Build and deploy this sample to a HoloLens device to be able to create and find Azure Spatial Anchors.\n\nDelete the current anchor before creating a new one.\n\nLook at the slate and it will detect your gaze and update itself."; } return; #else if (!IsSlateActive) { GameObject litecoin = GameObject.FindGameObjectWithTag("Litecoin"); litecoin.AddComponent <WorldAnchor>(); // Create the CloudSpatialAnchor. currentCloudAnchor = new CloudSpatialAnchor(); // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of the Litecoin symbol. WorldAnchor worldAnchor = litecoin.GetComponent <WorldAnchor>(); if (worldAnchor == null) { throw new Exception("Couldn't get the local anchor pointer."); } // Save the CloudSpatialAnchor to the cloud. currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr(); Task.Run(async() => { // Wait for enough data about the environment. while (recommendedForCreate < 1.0F) { await Task.Delay(330); } bool success = false; try { QueueOnUpdate(() => { Instructions.text = "Saving the Azure Spatial Anchor..."; }); await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor); success = currentCloudAnchor != null; if (success) { // Record the identifier of the Azure Spatial Anchor. cloudSpatialAnchorId = currentCloudAnchor.Identifier; QueueOnUpdate(() => { Instantiate(SlatePrefab, litecoin.transform.position, litecoin.transform.rotation); Destroy(litecoin); IsSlateActive = true; // Save the Azure Spatial Anchor ID so it persists even after the app is closed. PlayerPrefs.SetString("Anchor ID", cloudSpatialAnchorId); Instructions.text = "The Azure Spatial Anchor has been created!\n\nLook at the slate and it will detect your gaze and update itself."; }); } else { QueueOnUpdate(() => { Instructions.text = "An error occured while creating the Azure Spatial Anchor.\n\nPlease try again."; }); } } catch (Exception ex) { QueueOnUpdate(() => { Instructions.text = $"An error occured while creating the Azure Spatial Anchor.\n\nPlease try again.\n\nException: {ex.Message}"; }); } }); } else { Instructions.text = "An Azure Spatial Anchor already exists. Delete the current anchor before creating a new one.\n\nLook at the slate and it will detect your gaze and update itself."; } #endif }
/// <summary> /// Creates a sphere at the hit point, and then saves a CloudSpatialAnchor there. /// </summary> /// <param name="hitPoint">The hit point.</param> protected virtual void CreateAndSaveSphere(Vector3 hitPoint) { // Create a white sphere. sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.position = hitPoint; sphere.transform.localScale = new Vector3(0.25F, 0.25F, 0.25F); sphere.AddComponent <WorldAnchor>(); sphereMaterial = sphere.GetComponent <MeshRenderer>().material; sphereMaterial.color = Color.white; Debug.Log("ASA Info: Created a local anchor."); // Create the CloudSpatialAnchor. currentCloudAnchor = new CloudSpatialAnchor(); // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere. WorldAnchor worldAnchor = sphere.GetComponent <WorldAnchor>(); if (worldAnchor == null) { throw new Exception("ASA Error: Couldn't get the local anchor pointer."); } // Save the CloudSpatialAnchor to the cloud. currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr(); Task.Run(async() => { // Wait for enough data about the environment. while (recommendedForCreate < 1.0F) { await Task.Delay(330); } bool success = false; try { QueueOnUpdate(() => { // We are about to save the CloudSpatialAnchor to the Azure Spatial Anchors, turn it yellow. sphereMaterial.color = Color.yellow; }); await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor); success = currentCloudAnchor != null; if (success) { // Allow the user to tap again to clear state and look for the anchor. tapExecuted = false; // Record the identifier to locate. cloudSpatialAnchorId = currentCloudAnchor.Identifier; QueueOnUpdate(() => { // Turn the sphere blue. sphereMaterial.color = Color.blue; }); Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + cloudSpatialAnchorId); } else { sphereMaterial.color = Color.red; Debug.LogError("ASA Error: Failed to save, but no exception was thrown."); } } catch (Exception ex) { QueueOnUpdate(() => { sphereMaterial.color = Color.red; }); Debug.LogError("ASA Error: " + ex.Message); } }); }
/// <summary> /// Creates a sphere at the hit point, and then saves a CloudSpatialAnchor there. /// </summary> /// <param name="hitPoint">The hit point.</param> public virtual void CreateAndSaveSphere() { GameObject refObj = GameObject.Find("RefernceSceneBuilder"); refObj.AddComponent <WorldAnchor>(); Material indicatorMat = indicator.GetComponent <MeshRenderer>().material; indicatorMat.color = Color.black; Debug.Log("ASA Info: Created a local anchor."); // Create the CloudSpatialAnchor. currentCloudAnchor = new CloudSpatialAnchor(); // Set the LocalAnchor property of the CloudSpatialAnchor to the WorldAnchor component of our white sphere. WorldAnchor worldAnchor = refObj.GetComponent <WorldAnchor>(); if (worldAnchor == null) { throw new Exception("ASA Error: Couldn't get the local anchor pointer."); } // Save the CloudSpatialAnchor to the cloud. currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr(); Task.Run(async() => { // Wait for enough data about the environment. while (recommendedForCreate < 1.0F) { await Task.Delay(330); } bool success = false; try { QueueOnUpdate(() => { // We are about to save the CloudSpatialAnchor to the Azure Spatial Anchors, turn it yellow. indicatorMat.color = Color.yellow; }); await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor); success = currentCloudAnchor != null; if (success) { // Record the identifier to locate. cloudSpatialAnchorId = currentCloudAnchor.Identifier; QueueOnUpdate(() => { // Turn the sphere blue. indicatorMat.color = Color.green; }); Debug.Log("ASA Info: Saved anchor to Azure Spatial Anchors! Identifier: " + cloudSpatialAnchorId); } else { indicatorMat.color = Color.red; Debug.LogError("ASA Error: Failed to save, but no exception was thrown."); } } catch (Exception ex) { QueueOnUpdate(() => { indicatorMat.color = Color.red; }); Debug.LogError("ASA Error: " + ex.Message); } }); }
public void SaveContentsPosition() { Debug.Log("Selected SaveContentsPosition."); m_noticeMSGLabel.text = string.Format("アンカー情報を保存しています。"); /* * IdentifierとAnchorsをAzureSpatialAnchorsに登録 */ //CloudSpatialAnchorセッションを初期化するための処理を実行 ASAInitializeSession(); Debug.Log("ASA Info: 新しいアンカーを生成します。"); currentCloudAnchor = null; // CloudSpatialAnchorを生成する currentCloudAnchor = new CloudSpatialAnchor(); // CloudSpatialAnchorをクラウドに保存する m_labModel.AddComponent <WorldAnchor>(); Debug.Log("ASA Info: ローカルアンカーを生成しました"); WorldAnchor worldAnchor = m_labModel.GetComponent <WorldAnchor>(); if (worldAnchor == null) { throw new Exception("ASA Error: ローカルアンカーのポインタを取得できませんでした。"); } currentCloudAnchor.LocalAnchor = worldAnchor.GetNativeSpatialAnchorPtr(); var context = SynchronizationContext.Current; Task.Run(async() => { // アンカーを保存する周辺の環境情報を取得するまで待つ while (recommendedForCreate < 1.0F) { await Task.Delay(330); } bool success = false; try { await cloudSpatialAnchorSession.CreateAnchorAsync(currentCloudAnchor); success = currentCloudAnchor != null; if (success) { // 検索するアンカーを記録 identifierEntity.Identifier = currentCloudAnchor.Identifier; Debug.Log("ASA Info: Azure Spatial Anchorsへのアンカーを保存しました! Identifier: " + identifierEntity.Identifier); ASAResetSession(); } else { Debug.LogError("ASA Error:保存に失敗しましたが、例外はスローされませんでした"); } /* * ObjectIDとIdentifierをFunctions経由でTableStorageに登録(既に同一ObjectIDのものが存在する場合は更新) */ identifierEntity.ObjectID = m_labModel.GetInstanceID().ToString(); string jsonstr = JsonUtility.ToJson(identifierEntity); context.Post(_ => { StartCoroutine(AzureSpatialAnchorFunctionsRun.Instance.CallSaveFunctions(jsonstr)); DestroyImmediate(m_labModel.GetComponent <WorldAnchor>()); }, null); } catch (Exception ex) { Debug.LogError("ASA Error: " + ex.Message); } }); }