Unity3d 本地保存HoloLens2上的持久世界锚

Unity3d 本地保存HoloLens2上的持久世界锚,unity3d,hololens,windows-mixed-reality,Unity3d,Hololens,Windows Mixed Reality,我目前正在一个房间规模的Unity项目中工作,在这个项目中,我需要使用持久的世界锚来在我的设备上本地保存GameObjects'位置,而不需要使用任何Internet访问或Wifi 我正在使用Unity 2019.4.7和HoloLens2设备 我遇到了早期的HoloLens1项目的一些实现,以及MRTK 2.4的WorldAnchorManager类,它似乎与holoolkit的旧WorldAnchorManager非常相似。(例如:,或) 不幸的是,没有解决办法对我有效 似乎WorldAnc

我目前正在一个房间规模的Unity项目中工作,在这个项目中,我需要使用持久的世界锚来在我的设备上本地保存
GameObject
s'位置,而不需要使用任何Internet访问或Wifi

我正在使用Unity 2019.4.7和HoloLens2设备

我遇到了早期的
HoloLens1
项目的一些实现,以及
MRTK 2.4
WorldAnchorManager
类,它似乎与
holoolkit
的旧
WorldAnchorManager
非常相似。(例如:,或)

不幸的是,没有解决办法对我有效

似乎
WorldAnchors
甚至没有保存在
WorldAnchorsStore
中。我还尝试使用官方的Unity
WorldAnchorStore
而不使用
WorldAnchorManager
-类,即使它将在
Unity 2020
中被弃用

有人能给我一个例子,应该在我的设置工作吗

我也会很高兴每一个提示,使锚工作

我当前使用WorldAnchorManager的代码如下所示。已启用
WorldAnchormaManager
实例中的永久锚定

using Microsoft.MixedReality.Toolkit.Experimental.Utilities;
using UnityEngine;

public class SetWorldAnkeredObject : MonoBehaviour
{
    public GameObject anchoredObject;
    public WorldAnchorManager store;
    private string anchorId = "AnchoredCube";
    private bool savedRoot;

    void Start()
    {
        store.AttachAnchor(anchoredObject, anchorId);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.L))
        {
            store.AttachAnchor(anchoredObject, anchorId);
        }
        if (Input.GetKeyDown(KeyCode.Return))
        {
            if (anchoredObject != null)
                store.RemoveAnchor(anchorId);
            anchoredObject.transform.position = this.transform.position;
            store.AttachAnchor(anchoredObject, anchorId);
        }
    }
}

以下是我的一个项目中的一些代码行,可能会对您有所帮助

进口

    private byte[] _importedData;
    private int _retryCount = 3;

    internal bool ImportAnchors()
    {
        _retryCount = 3;
        string path = GetWorldAnchorsDataPath(); // your path
        if (!File.Exists(path))
        {
            Debug.Log("Fail ImportWorldAnchors ImportAnchors File does not exist");
            return false;
        }

        _importedData = File.ReadAllBytes(path);
        Debug.Log("_importedData count " + _importedData.Length);
        WorldAnchorTransferBatch.ImportAsync(_importedData, OnImportComplete);
    }

    private void OnImportComplete(SerializationCompletionReason completionReason, WorldAnchorTransferBatch deserializedTransferBatch)
    {
        if (completionReason != SerializationCompletionReason.Succeeded)
        {
            Debug.Log("(" + _retryCount + ") Failed to import: " + completionReason.ToString());
            if (_retryCount > 0)
            {
                _retryCount--;
                WorldAnchorTransferBatch.ImportAsync(_importedData, OnImportComplete);
            }
            return;
        }
        Debug.Log("Success ImportWorldAnchors OnImportComplete, anchors count : " + deserializedTransferBatch.anchorCount);
        AnchorsManager.GetAndUpdateAnchorsFromBatch(deserializedTransferBatch);

        deserializedTransferBatch.Dispose();
    }    

  internal static string GetWorldAnchorsDataPath()
    {
        return Application.persistentDataPath + "/worldAnchors.dat";
    }
  
出口

 internal void ExportAnchors()
    {            
        string path = GetWorldAnchorsDataPath();
        if (File.Exists(path))
        {
            FileStream fileStream = File.Open(path, FileMode.Open);

            /* 
             * Set the length of filestream to 0 and flush it to the physical file.
             *
             * Flushing the stream is important because this ensures that
             * the changes to the stream trickle down to the physical file.
             * 
             */
            fileStream.SetLength(0);
            fileStream.Close(); // This flushes the content, too.
        }

        WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();

        AddAnchorsToBatch(transferBatch); // your own function to use your batch
        Debug.Log("Nb anchors in batch : " + transferBatch.anchorCount);
        WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
    }

    private void OnExportDataAvailable(byte[] data)
    {
        AppendAllBytes(GetWorldAnchorsDataPath(), data);    
    }

    private void OnExportComplete(SerializationCompletionReason completionReason)
    {
        if (completionReason != SerializationCompletionReason.Succeeded)
        {
            SendExportFailedToClient();
        }
        else
        {
            SendExportSucceededToClient();
        }
    }

    private void SendExportFailedToClient()
    {
        Debug.Log("Export fail");
        string path = GetWorldAnchorsDataPath();
        if (File.Exists(path))
        {
            File.Delete(path);
        }
        SuccessToExportWorldAnchors(false);
    }

    private void SendExportSucceededToClient()
    {
        Debug.Log("Export succeed");
        SuccessToExportWorldAnchors(true);
    }


    private static void AppendAllBytes(string path, byte[] bytes)
    {
        //argument-checking here.

        using (var stream = new FileStream(path, FileMode.Append))
        {
            stream.Write(bytes, 0, bytes.Length);
        }
    }

感谢您的回复,Luckypon,我今天会检查一下,并给出反馈,无论这对我是否有效!你能告诉我怎么走holens2的路吗?我查了一下,发现您使用的是“KnownFolders.PicturesLibrary”。我可以用Unity的“Application.persistentDataPath”获取路径吗?