/// <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); }
public async Task <CloudSpatialAnchor> StoreAnchorInCloud(CloudSpatialAnchor cloudSpatialAnchor) { if (SessionStatusIndicators[(int)SessionStatusIndicatorType.ReadyForCreate] < 1) { return(null); } await cloudSpatialAnchorSession.CreateAnchorAsync(cloudSpatialAnchor); return(cloudSpatialAnchor); }
private void CreateAndSaveAnchor() { Log("Creating new anchor..."); // Just in case clean up any visuals that have been placed. CleanupObjects(); // Raycast to find a hitpoint where the anchor should be placed Ray gazeRay = new Ray(Camera.main.transform.position, Camera.main.transform.forward); Physics.Raycast(gazeRay, out RaycastHit hitPoint, float.MaxValue); // Instantiate the anchor visual Prefab _prefabInstance = Instantiate(Prefab, hitPoint.point, Quaternion.identity) as GameObject; var localAnchor = _prefabInstance.AddComponent <WorldAnchor>(); Log("Created local anchor."); // Create CloudSpatialAnchor and link the local anchor _currentCloudAnchor = new CloudSpatialAnchor { LocalAnchor = localAnchor.GetNativeSpatialAnchorPtr() }; _ = Task.Run(async() => { // Wait for enough spatial data about the environment so the anchor can be relocalized later while (_recommendedSpatialDataForUpload < 1.0F) { Log($"Look around to capture enough anchor data: {_recommendedSpatialDataForUpload:P0}", Color.yellow); await Task.Delay(50); } try { Log($"Creating and uploading ASA anchor...", Color.yellow); await _cloudSpatialAnchorSession.CreateAnchorAsync(_currentCloudAnchor); if (_currentCloudAnchor != null) { // Allow the user to tap again to clear the state and enter localization mode _wasTapped = false; _currentCloudAnchorId = _currentCloudAnchor.Identifier; Log($"Saved anchor to Azure Spatial Anchors: {_currentCloudAnchorId}\r\nTap to localize it.", Color.cyan); } } catch (Exception ex) { Log($"Failed to create ASA anchor: {ex.Message}", Color.red); } }); }
public async Task <CloudSpatialAnchor> StoreAnchorInCloud(CloudSpatialAnchor cloudSpatialAnchor) { if (SessionStatusIndicators[(int)SessionStatusIndicatorType.ReadyForCreate] < 1) { return(null); } await cloudSpatialAnchorSession.CreateAnchorAsync(cloudSpatialAnchor); OnAnchorCreatedSuccessfully?.Invoke(); Debug.Log("Anchor Created Succesfully!"); return(cloudSpatialAnchor); }
private async Task <ISpatialCoordinate> TryCreateCoordinateImplAsync(Vector3 worldPosition, Quaternion worldRotation, CancellationToken cancellationToken) { await EnsureInitializedAsync().Unless(cancellationToken); RequestSessionStart(); try { await recommendedForCreate.Task.Unless(cancellationToken); GameObject spawnedAnchorObject = SpawnGameObject(worldPosition, worldRotation); try { spawnedAnchorObject.AddARAnchor(); // Let a frame pass to ensure any AR anchor is properly attached (WorldAnchors used to have issues with this) await Task.Delay(100, cancellationToken); CloudSpatialAnchor cloudSpatialAnchor = new CloudSpatialAnchor() { LocalAnchor = spawnedAnchorObject.GetNativeAnchorPointer(), Expiration = DateTime.Now.AddDays(1) }; if (cloudSpatialAnchor.LocalAnchor == IntPtr.Zero) { Debug.LogError($"{nameof(SpatialAnchorsCoordinateService)} failed to get native anchor pointer when creating anchor."); return(null); } await session.CreateAnchorAsync(cloudSpatialAnchor); return(new SpatialAnchorsCoordinate(cloudSpatialAnchor, spawnedAnchorObject)); } catch { UnityEngine.Object.Destroy(spawnedAnchorObject); throw; } } finally { ReleaseSessionStartRequest(); } }
/// <summary> /// Creates the specified anchor when the session is ready to create it. /// This task is cancelable. /// </summary> /// <param name="anchor"> /// The anchor to create. /// </param> /// <param name="cancellationToken"> /// </param> /// <returns> /// A <see cref="Task"/> that represents the operation. /// </returns> /// <remarks> /// If there is no active <see cref="Session"/>, calling this method will /// result in an exception. If there is an active session, this method /// will wait until <see cref="IsReadyForCreate"/> returns <c>true</c> /// before continuing the operation. The <paramref name="cancellationToken"/> /// parameter can be used to cancel the operation. /// </remarks> public async Task CreateAnchorAsync(CloudSpatialAnchor anchor, CancellationToken cancellationToken) { // Validate if (anchor == null) { throw new ArgumentNullException(nameof(anchor)); } EnsureSessionStarted(); // Wait for enough data while (!IsReadyForCreate) { cancellationToken.ThrowIfCancellationRequested(); await Task.Delay(50); } // Actually create await session.CreateAnchorAsync(anchor); }
private async Task CreateAnchorAsync(Vector3 newPosition) { var dist = Vector3.Distance(localAnchorPosition, newPosition); if (newPosition != Vector3.zero && (localAnchorPosition == Vector3.zero || dist > minPositionChangeDistance)) { // Lock game object. While anchor is saved. localAnchorGameObject.GetComponent <DragonAI>().StopPlayerPositionTracking(); localAnchorGameObject.AddARAnchor(); if (loadedAnchor != null) { // Remove old anchor. await cloudSession.DeleteAnchorAsync(loadedAnchor); } // Save to server. CloudSpatialAnchor cloudAnchor = new CloudSpatialAnchor(); cloudAnchor.LocalAnchor = localAnchorGameObject.GetNativeAnchorPointer(); cloudAnchor.AppProperties[@"label"] = @"Dragon"; await cloudSession.CreateAnchorAsync(cloudAnchor); await storageService.PostAnchorId(cloudAnchor.Identifier); Debug.Log(DEBUG_FILTER + $"Created a cloud anchor with ID={cloudAnchor.Identifier}"); // Unlock game object. localAnchorGameObject.RemoveARAnchor(); localAnchorGameObject.GetComponent <DragonAI>().ChangePosition(newPosition); Debug.Log(DEBUG_FILTER + "saved position" + newPosition + " to server"); await Task.Delay(5000); // Wait 5 sec before tracking again. Debug.Log(DEBUG_FILTER + "continue tracking"); localAnchorGameObject.GetComponent <DragonAI>().StartPlayerPositionTracking(); localAnchorPosition = new Vector3(newPosition.x, newPosition.y, newPosition.z); } }
/// <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); } }); }
public Task <CloudSpatialAnchor> CreateAnchorAsync(CloudSpatialAnchor anchor) { return(spatialAnchorsSession.CreateAnchorAsync(anchor)); }
/// <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); } }); }