找回密码
 立即注册
查看: 308|回复: 0

Unity+Hololens2+WorldAnchor实现锚点锁定

[复制链接]
发表于 2023-3-7 21:10 | 显示全部楼层 |阅读模式
本篇使用旧版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时可以移动操作物体,并在操作结束后改变锚点的位置。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 16:42 , Processed in 0.157158 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表