Unity+Hololens2+WorldAnchor實現(xiàn)錨點鎖定

本篇使用舊版Unity(2019)的WorldAnchor功能實現(xiàn)將物體鎖定于虛擬空間的特定位置,多個物體可分別鎖定錨點位置。
官方文檔:https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/unity/spatial-anchors-in-unity?tabs=worldanchor

一、新建空物體掛載腳本W(wǎng)orldAnchorManager

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;        //控制改變物體錨點的開關(guān)
    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);
            //取消事件監(jiān)聽
            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

四、結(jié)語

這樣就可以通過操作bool值canChangeAnchor的開關(guān)來控制是否可以移動物體添加錨點(因為有WorldAnchor存在時,物體是不可以進(jìn)行操作的)。
當(dāng)canChangeAnchor為flase時不可以移動操作物體(將物體鎖定在場景中的某個位置)。
當(dāng)canChangeAnchor為true時可以移動操作物體,并在操作結(jié)束后改變錨點的位置。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容