unity3d 如何在Unity中创建MutableRuntimeReferenceImageLibrary?

pgx2nnw8  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(133)

我使用的是Unity 2021.3.22f1和AR Foundation 4.2.7版本。我已经在场景中添加了AR Session和AR Session Origin,以及AR Tracked Image Manager作为AR Session Origin的组件。
我想创建一个MutableRuntimeReferenceImageLibrary,它在运行时动态地添加包含在项目文件夹中的图像。
我写了这段代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ImageLibraryManager : MonoBehaviour
{
    public ARTrackedImageManager trackedImageManager;
    public string imageFolderPath;

    void Start()
    {
        // Create a list to hold XRReferenceImage objects
        var imageList = new List<XRReferenceImage>();

        // Get the files in the image folder
        var imageFiles = System.IO.Directory.GetFiles(imageFolderPath);

        // Loop through the image files and add them to the list
        foreach (var imageFile in imageFiles)
        {
            // Load the image from the file
            var imageBytes = System.IO.File.ReadAllBytes(imageFile);
            var texture = new Texture2D(2, 2);
            texture.LoadImage(imageBytes);

            var newGuid = System.Guid.NewGuid();
            var guidBytes = newGuid.ToByteArray();
            var image = new XRReferenceImage(
                // Use a new guid for each image
                new SerializableGuid(
                    (ulong)(guidBytes[3] << 24 | guidBytes[2] << 16 | guidBytes[1] << 8 | guidBytes[0]),
                    (ulong)(guidBytes[7] << 24 | guidBytes[6] << 16 | guidBytes[5] << 8 | guidBytes[4])
                ),
                // Use an empty guid for the second parameter
                SerializableGuid.empty,
                // Set the size of the image in meters
                new Vector2(texture.width, texture.height) / 1000f,
                // Set the name of the image
                System.IO.Path.GetFileNameWithoutExtension(imageFile),
                // Set the texture of the image
                texture
            );

            imageList.Add(image);
        }

        // Create a new MutableRuntimeReferenceImageLibrary and assign it to the ARTrackedImageManager
        var imageLibrary = trackedImageManager.CreateRuntimeLibrary() as MutableRuntimeReferenceImageLibrary;
        foreach (var image in imageList)
        {
            // Add each image to the image library
            imageLibrary.AddReferenceImage(image);
        }
        trackedImageManager.referenceLibrary = imageLibrary;
    }
}

然而,这给了我这个错误:Assets/ImageLibraryManager.cs(53,26): error CS1061: 'MutableRuntimeReferenceImageLibrary' does not contain a definition for 'AddReferenceImage' and no accessible extension method 'AddReferenceImage' accepting a first argument of type 'MutableRuntimeReferenceImageLibrary' could be found (are you missing a using directive or an assembly reference?)
我已经尝试过其他方法,如“添加”或“添加图像”,但它总是给我同样的错误。
你能帮助我解决我的问题,并创建这种类型的MutableRuntimeReferenceImageLibrary吗?
谢谢你

cgyqldqp

cgyqldqp1#

Unity中的图像库似乎有一个层次结构的类。进一步阅读后请注意,RuntimeReferenceImageLibrary和XRReferenceImageLibrary都实现了IReferenceImageLibrary接口。一个用于编辑时。另一个用于运行时。混淆?绝对!这是我回答过的最棘手的问题!

Object
  RuntimeReferenceImageLibrary - create at run-time (but must be casted from Mutable*)
    MutableRuntimeReferenceLibrary - mutable at runtime (add images)
  XRReferenceImageLibrary - create at edit-time; immutable at run-time (don't add images).

还请注意,Unity使用了术语“runtime”。当程序从通过.NET公共语言运行时执行程序的Angular 运行时,请不要将其与公共编程术语“runtime”混淆。从应用程序内部的Angular 考虑Unity术语,因为您可以编辑或运行。因为他们有另一个术语称为“edit-time”。请参阅下面的链接。应用程序的“编辑时”和“运行时”状态会影响这些图像库的功能。我认为开发人员没有使用连字符,所以他们会把人们弄糊涂!他们应该把它重命名为“运行时”!
https://docs.unity.cn/Packages/com.unity.xr.arfoundation@4.1/api/UnityEngine.XR.ARFoundation.ARTrackedImageManager.html?q=RuntimeReferenceImageLibrary
请参见接口文档。
IReferenceImageLibrary可以是XRReferenceImageLibrary或RuntimeReferenceImageLibrary。XRReferenceImageLibrary只能在编辑时构造,并且在运行时不可变。RuntimeReferenceImageLibrary是XRReferenceImageLibrary的运行时表示,并且在运行时可能是可变的(请参见MutableRuntimeReferenceImageLibrary)。
https://docs.unity.cn/Packages/com.unity.xr.arfoundation@4.1/api/UnityEngine.XR.ARFoundation.ARTrackedImageManager.html?q=RuntimeReferenceImageLibrary#UnityEngine_XR_ARFoundation_ARTrackedImageManager_referenceLibrary
CreateRuntimeLibrary(XRReferenceImageLibrary)从现有的UnityEngine.XR.ARSubsystems.XRReferenceImageLibrary创建UnityEngine.XR.ARSubsystems.RuntimeReferenceImageLibrary,如果serializedLibrary为null,则创建空库。使用此函数可在运行时构造引用映像库。如果库的类型为MutableRuntimeReferenceImageLibrary,则可在运行时修改。
将MutableRuntimeReferenceImageLibrary强制转换为RuntimeReferenceImageLibrary。但由于MutableRuntimeReferenceLibrary类是抽象的,因此它需要一个子类来示例化对象。ARTrackedImageManager类上已经有一个名为referenceLibrary的属性。因此使用它,而不是在这种情况下调用CreateRuntimeLibrary方法。(这就是框架的问题所在--除非你读了四个小时,否则东西都是这样隐藏的)在上面链接的右边找到属性链接。你会看到referenceLibrary。

RuntimeReferenceImageLibrary runtimeLibrary = trackedImageManager.referenceLibrary as MutableRuntimeReferenceImageLibrary;

在这之后,我不知道还需要什么。
据我所知,类XRReferenceImageLibrary是唯一一个内部有List方法的图像库,这意味着它包含一个图像集合。所以你可能需要首先构建这个,然后将其转换为另一个图像库类型/类对象。请参阅上面的IReferenceImageLibrary文档。所以你可能需要在构建XRReferenceImageLibrary(添加图像)后两次转换对象。
定义有很多很多的功能!:在C#中用来表示类继承或接口实现。你可以枚举,你可以利用接口功能,它有一个回调接收器,等等。我知道这些是什么意思吗?不太清楚,除了枚举。这意味着你可以访问对象的列表/集合(在这种情况下是图像)。

public class XRReferenceImageLibrary : ScriptableObject, IReferenceImageLibrary, ISerializationCallbackReceiver, IEnumerable<XRReferenceImage>, IEnumerable

https://docs.unity3d.com/Packages/com.unity.xr.arsubsystems@4.2/api/UnityEngine.XR.ARSubsystems.XRReferenceImageLibrary.html#methods
看起来开发人员隐藏了一些信息,所以你要花钱去培训学习框架。相信我,我已经编程18年了。许多软件公司不会分享他们代码的细节,除非你付钱。当你花钱去培训时,你会学得很快。
如果您确实希望源代码能够确认您自己的代码,您可以下载此代码。作为类库(DLL)进行编译。然后在C#应用程序项目中添加对DLL的引用。然后,当您编译和执行代码时,您可以在IDE中逐行读取它们的代码,以通过堆栈跟踪来回答您自己的问题。
https://github.com/needle-mirror/com.unity.xr.arfoundation
祝你好运!如果我有更多的时间,我会多看看这个。

相关问题