super1 发表于 2023-3-7 21:10

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]
查看完整版本: Unity+Hololens2+WorldAnchor实现锚点锁定