HoloLens開發手記 - Unity之Persistence 場景保持


Persistence 場景保持是HoloLens全息體驗的一個關鍵特性,當用戶離開原場景中時,原場景中全息對象會保持在特定位置,當用戶回到原場景時,能夠准確還原原場景的全息內容。WorldAnchorStore類是實現此特性的關鍵API,這保證了用戶能夠將任何全息對象貼到任何他們想要放置的位置。

 

How to persist holograms across sessions 如何在整個會話中保持全息對象


 

WorldAnchorStore能夠允許你保持場景中空間錨的位置,為了能夠真正保持全息對象,你需要單獨使用特定的空間錨來追蹤每一個對象。通常創建一個根GameObject並附上空間錨,同時對它的子GameObject也附上具有相對位置偏移的空間錨組件。

為了從先前場景載入全息對象:

  1. 獲取WorldAnchorStore對象
  2. 載入空間錨關聯的應用數據,從中獲取空間錨ID
  3. 通過ID獲取空間錨對象

 

下個場景之前,為了保存全息對象信息:

  1. 獲取WorldAnchorStore對象
  2. 指定ID來保持對應空間錨對象
  3. 保持與空間錨關聯的應用數據

 

Getting the WorldAnchorStore 獲取WorldAnchorStore對象


 

命名空間: UnityEngine.WSA.VR.Persistence

類型: WorldAnchorStore

 

為了能夠在后續使用WorldAnchorStore,我們需要先通過異步操作打開此對象,如下:

 

WorldAnchorStore.GetAsync(StoreLoaded);

private void StoreLoaded(WorldAnchorStore store)
{
       this.store = store;
}

 

現在就可以使用WorldAnchorStore對象來保存場景信息了。

 

Saving a WorldAnchor 保存一個空間錨


 

注意:同一空間錨不能多次保存。每個空間錨只應該保存一次,如果需要更新空間錨信息,則需要先刪除舊的空間錨信息,然后再保存新的空間錨信息。

 

private void SaveGame()
{
       // 保存空間錨對應的全息對象數據
       if (!this.savedRoot) // 僅僅保存根對象一次
       {
              this.savedRoot = this.store.Save("rootGameObject", anchor);
              Assert(this.savedRoot);
       }
}

 

Loading a WorldAnchor 載入一個空間錨


 

載入空間錨數據很簡單,如下:

 

private void LoadGame()
{
       // Save data about holograms positioned by this world anchor
       this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
       if (!this.savedRoot)
       {
              // 我們沒有成功保存空間錨和全息對象數據,需要重新替換我們的對象
       }
}

 

Enumerating Existing Anchors 枚舉已有的空間錨


 

我們可以通過枚舉已保存的空間錨信息來查找之前保存的空間錨:

 

string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
        Debug.Log(ids[index]);
}

 

示例代碼


using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VR.WSA;
using UnityEngine.VR.WSA.Persistence;

public class SceneManager : Singleton<SceneManager>
{

    private WorldAnchorStore anchorStore;
    private Dictionary<string, GameObject> SceneObjects = new Dictionary<string, GameObject>();
    
    void Start()
    {

        WorldAnchorStore.GetAsync(WorldAnchorStoreLoaded);
    }

    private void WorldAnchorStoreLoaded(WorldAnchorStore store)
    {
        this.anchorStore = store;
    }

    //保存場景對象信息
    public bool SaveSceneObject(string objectId, WorldAnchor anchor)
    {
        var result= this.anchorStore.Save(objectId, anchor);
        if (result)
        {
            SceneObjects.Add(objectId, anchor.gameObject);
        }
        return result;
    }

    //載入場景對象信息
    public WorldAnchor LoadSceneObject(string objectId)
    {
        if (SceneObjects.ContainsKey(objectId))
        {
            var target = SceneObjects[objectId];
            return this.anchorStore.Load(objectId, target);
        }
        return null;
       
    }

    //還原場景全部內容
    public void RestoreAllSceneObjects()
    {
        foreach(var key in SceneObjects.Keys)
        {
            var target = SceneObjects[key];
            this.anchorStore.Load(key, target);
        }
    }


}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM