赞
踩
Hololens入门之空间锚与场景保持
World Anchor(空间锚)提供了一种能够将物体保留在特定位置和旋转状态上的方法。这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力。简单地说,你可以为全息物体来添加空间锚点,这样就能在后续步骤中将全息物体准确恢复到它原来的位置。
场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容。WorldAnchorStore类是实现此特性的关键API,这保证了用户能够将任何全息对象贴到任何他们想要放置的位置。
WorldAnchorStore能够允许你保持场景中空间锚的位置,为了能够真正保持全息对象,你需要单独使用特定的空间锚来追踪每一个对象。通常创建一个根GameObject并附上空间锚,同时对它的子GameObject也附上具有相对位置偏移的空间锚组件。
本文实现以下功能
移动两个Cube的位置,关闭应用,,然后通过场景保持在下一次启动应用时,能够恢复应用关闭前Cube所处的位置
本文示例在 Hololens入门之凝视 的基础上进行修改开发
1、在Manager中添加GestureManager.cs脚本组件(直接使用HoloToolkit中的GestureManager.cs)
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // Licensed under the MIT License. See LICENSE in the project root for license information.
-
- using UnityEngine;
- using UnityEngine.VR.WSA.Input;
-
- namespace HoloToolkit.Unity
- {
- /// <summary>
- /// GestureManager creates a gesture recognizer and signs up for a tap gesture.
- /// When a tap gesture is detected, GestureManager uses GazeManager to find the game object.
- /// GestureManager then sends a message to that game object.
- /// </summary>
- [RequireComponent(typeof(GazeManager))]
- public partial class GestureManager : Singleton<GestureManager>
- {
- /// <summary>
- /// Key to press in the editor to select the currently gazed hologram
- /// </summary>
- public KeyCode EditorSelectKey = KeyCode.Space;
-
- /// <summary>
- /// To select even when a hologram is not being gazed at,
- /// set the override focused object.
- /// If its null, then the gazed at object will be selected.
- /// </summary>
- public GameObject OverrideFocusedObject
- {
- get; set;
- }
-
- /// <summary>
- /// Gets the currently focused object, or null if none.
- /// </summary>
- public GameObject FocusedObject
- {
- get { return focusedObject; }
- }
-
- private GestureRecognizer gestureRecognizer;
- private GameObject focusedObject;
-
- void Start()
- {
- // Create a new GestureRecognizer. Sign up for tapped events.
- gestureRecognizer = new GestureRecognizer();
- gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap);
-
- gestureRecognizer.TappedEvent += GestureRecognizer_TappedEvent;
-
- // Start looking for gestures.
- gestureRecognizer.StartCapturingGestures();
- }
-
- private void OnTap()
- {
- if (focusedObject != null)
- {
- focusedObject.SendMessage("OnSelect");
- }
- }
-
- private void GestureRecognizer_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay)
- {
- OnTap();
- }
-
- void LateUpdate()
- {
- GameObject oldFocusedObject = focusedObject;
-
- if (GazeManager.Instance.Hit &&
- OverrideFocusedObject == null &&
- GazeManager.Instance.HitInfo.collider != null)
- {
- // If gaze hits a hologram, set the focused object to that game object.
- // Also if the caller has not decided to override the focused object.
- focusedObject = GazeManager.Instance.HitInfo.collider.gameObject;
- }
- else
- {
- // If our gaze doesn't hit a hologram, set the focused object to null or override focused object.
- focusedObject = OverrideFocusedObject;
- }
-
- if (focusedObject != oldFocusedObject)
- {
- // If the currently focused object doesn't match the old focused object, cancel the current gesture.
- // Start looking for new gestures. This is to prevent applying gestures from one hologram to another.
- gestureRecognizer.CancelGestures();
- gestureRecognizer.StartCapturingGestures();
- }
-
- #if UNITY_EDITOR
- if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(EditorSelectKey))
- {
- OnTap();
- }
- #endif
- }
-
- void OnDestroy()
- {
- gestureRecognizer.StopCapturingGestures();
- gestureRecognizer.TappedEvent -= GestureRecognizer_TappedEvent;
- }
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
2、新增两个Cube GameObject,添加脚本组件CubeScript.cs
CubeScript.cs如下
- using UnityEngine;
- using System.Collections;
- using UnityEngine.VR.WSA.Persistence;
- using System;
- using UnityEngine.VR.WSA;
-
- public class CubeScript : MonoBehaviour {
-
- public string ObjectAnchorStoreName;
-
- WorldAnchorStore anchorStore;
-
- bool Placing = false;
- void Start () {
- //获取WorldAnchorStore 对象
- WorldAnchorStore.GetAsync(AnchorStoreReady);
- }
-
- private void AnchorStoreReady(WorldAnchorStore store)
- {
- anchorStore = store;
- string[] ids = anchorStore.GetAllIds();
- //遍历之前保存的空间锚,载入指定id场景对象信息
- for (int index = 0; index < ids.Length; index++)
- {
- if (ids[index] == ObjectAnchorStoreName)
- {
- WorldAnchor wa = anchorStore.Load(ids[index], gameObject);
- break;
- }
- }
- }
-
- // Update is called once per frame
- void Update () {
- if (Placing)
- {
- //当Cube处于可移动状态,根据凝视射线的位置,更新Cube的位置
- gameObject.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 2;
- }
- }
-
- void OnSelect()
- {
- if (anchorStore == null)
- {
- return;
- }
-
- if (Placing)
- {
- //当再次点击全息对象时,保存空间锚信息
- WorldAnchor attachingAnchor = gameObject.AddComponent<WorldAnchor>();
- if (attachingAnchor.isLocated)
- {
- bool saved = anchorStore.Save(ObjectAnchorStoreName, attachingAnchor);
- }
- else
- {
- //有时空间锚能够立刻被定位到。这时候,给对象添加空间锚后,空间锚组件的isLocated属性
- //值将会被设为true,这时OnTrackingChanged事件将不会被触发。因此,在添加空间锚组件
- //后,推荐立刻使用初始的isLocated状态去调用OnTrackingChanged事件
- attachingAnchor.OnTrackingChanged += AttachingAnchor_OnTrackingChanged;
- }
- }
- else
- {
- //当全息对象已附加空间锚组件后,它不能被移动。如果你需要移动全息对象的话,那么你必须这样做:
- //1.立刻销毁空间锚组件
- //2.移动全息对象
- //3.添加一个新的空间锚到全息对象上
- WorldAnchor anchor = gameObject.GetComponent<WorldAnchor>();
- if (anchor != null)
- {
- DestroyImmediate(anchor);
- }
-
- string[] ids = anchorStore.GetAllIds();
- for (int index = 0; index < ids.Length; index++)
- {
- if (ids[index] == ObjectAnchorStoreName)
- {
- bool deleted = anchorStore.Delete(ids[index]);
- break;
- }
- }
- }
-
- Placing = !Placing;
- }
-
- private void AttachingAnchor_OnTrackingChanged(WorldAnchor self, bool located)
- {
- if (located)
- {
- bool saved = anchorStore.Save(ObjectAnchorStoreName, self);
- self.OnTrackingChanged -= AttachingAnchor_OnTrackingChanged;
- }
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
4、运行测试
1) 启动应用,可以看到Cube的初始位置
2) 选中Cube,移动头部,然后再次选中Cube将Cube放置到新的位置
3)关闭应用
4)再次打开应用,能够看到两个Cube所处的位置为关闭应用前的位置,非初始位置
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。