Unity+Hololens2+WorldAnchor实现锚点锁定
本篇使用旧版Unity(2019)的WorldAnchor功能实现将物体锁定于虚拟空间的特定位置,多个物体可分别锁定锚点位置。官方文档:https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/unity/spatial-anchors-in-unity?tabs=worldanchor
一、新建空物体挂载脚本WorldAnchorManager
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.XR.WSA.Persistence;public class WorldAnchorManager : MonoBehaviour{ public static WorldAnchorManager Instance; public bool canChangeAnchor; //控制改变物体锚点的开关 public WorldAnchorStore anchorStore;//保存锚点的库 public string[] ids; void Awake() { Instance = this; //加载世界锚点 WorldAnchorStore.GetAsync(StoreLoaded); } private void StoreLoaded(WorldAnchorStore store) { //读取所有已保存的空间锚 anchorStore = store; ids = anchorStore.GetAllIds(); } public void ChangeAnchor() { canChangeAnchor = !canChangeAnchor; }}二、在物体上添加组件WorldAnchor
image.png
三、在物体上添加WorldAnchorTest
将RemoveAnchor和AddAnchor方法注册到物体MRTK的操作脚本上
using System.Collections;using System.Collections.Generic;using System.Linq;using UnityEngine;using UnityEngine.XR.WSA;public class WorldAnchorTest : MonoBehaviour{ void Start() { Invoke("LoadAnchor", .1f); } void LoadAnchor() { if (WorldAnchorManager.Instance.ids.Contains(transform.name)) { WorldAnchorManager.Instance.anchorStore.Load(transform.name, gameObject); } } /// <summary> /// 添加世界锚点 /// </summary> public void AddAnchor() { if (!WorldAnchorManager.Instance.canChangeAnchor) { return; } Debug.Log("添加锚点"); if (WorldAnchorManager.Instance.anchorStore == null) { return; } WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>(); if (anchor.isLocated) { WorldAnchorManager.Instance.anchorStore.Save(transform.name, anchor); } else { anchor.OnTrackingChanged += Anchor_OnTrackingChanged; } } void Anchor_OnTrackingChanged(WorldAnchor self, bool located) { if (located) { WorldAnchorManager.Instance.anchorStore.Save(transform.name, self); //取消事件监听 self.OnTrackingChanged -= Anchor_OnTrackingChanged; } } /// <summary> /// 删除世界锚点 /// </summary> public void RemoveAnchor() { if (!WorldAnchorManager.Instance.canChangeAnchor) { return; } Debug.Log("删除锚点"); DestroyImmediate(gameObject.GetComponent<WorldAnchor>()); if (WorldAnchorManager.Instance.anchorStore.GetAllIds().Contains(transform.name)) { WorldAnchorManager.Instance.anchorStore.Delete(transform.name); } }}
image.png
1.png
2.png
四、结语
这样就可以通过操作bool值canChangeAnchor的开关来控制是否可以移动物体添加锚点(因为有WorldAnchor存在时,物体是不可以进行操作的)。
当canChangeAnchor为flase时不可以移动操作物体(将物体锁定在场景中的某个位置)。
当canChangeAnchor为true时可以移动操作物体,并在操作结束后改变锚点的位置。
页:
[1]