繁体   English   中英

将导入数据存储在变量中的最佳方法

[英]Best way to store imported data in variables

我正在 Unity 中创建一个应用程序,在其中我在运行时从 web 导入 JSON 数据库并在 AR 环境中显示信息。

我首先为该鱼创建了一个名为“Collezione”(意大利语中的集合)的存储 class,因为我试图让一切尽可能有条理。 该系列有一个名称和一个陈列柜列表,每个陈列柜都有一个标识符和一个对象列表:

using System.Collections.Generic;
using UnityEngine;

public class Collezione : MonoBehaviour
{
    public string nome;
    public List<Vetrina> collezione;
}

public class Vetrina
{
    public string nome;
    public List<ObjectClass> vetrina;
}

public class ObjectClass
{
    public string id;
    public Vector3 posizione;
    public string denominazione;
    public string materiale;
    public string forma;
    public string cronologia;
    public string da;
    public string a;
}

由于它是一个 MonoBehaviour class,我需要将它附加到一个 object 并在所有其他脚本中实例化它的引用。 我想知道是否有更有效的方法来做到这一点。 我试图将它转换为 static class 并且它似乎有效,但我想知道是否有更好的解决方案。
这是 static 版本。

public static class Collezione
{
    public static string nome;
    public static List<Vetrina> collezione;
}

public class Vetrina
{
    public string nome;
    public List<ObjectClass> vetrina;
}

public class ObjectClass
{
    public string id;
    public Vector3 posizione;
    public string denominazione;
    public string materiale;
    public string forma;
    public string cronologia;
    public string da;
    public string a;
}

从您的Collection消费者的角度来看,我想说为他们提供一种最干净的方法是使用依赖注入。 但是您的两个示例都可以,因为在 Unity 中实现依赖注入并不是一件容易的事。 static class 方法可能会更好一些,因为当您在其他脚本中使用GetComponent时,测试起来会稍微困难一些。

所以如果你想 go 进行依赖注入,你需要一些组件,负责组合其他组件并注入它们的依赖项。 不使用任何会有点棘手的 DI 容器框架,但仍然如此。

首先,您可能会引入一个界面来轻松找到您的组件,这需要您的Collection

public interface IConsumatoreDelCollezione
{
    public Collezione Collezione { get; set; }
}

只需让所有需要Collection的组件实现该接口,包括将数据存储到Collection的组件。 因此该组件将存储数据,其他读取。

你的Collection的实际实现并不重要。 它可以是MonoBehaviourScriptableObject 但最好的测试只是普通的 C# object。 而您的MonoBehaviour组件只会包装该 object。 例如像这样:

public class CollezioneComponent : MonoBehaviour
{
    public Collezione collezione;

    public void Awake()
    {
        name = "ContenitoreDelCollezione"; // To easily find the container.
    }
}

而且你需要一些CompositionRoot来自动将它们连接在一起:

public class CompositionRoot : MonoBehaviour
{
    public void Awake()
    {
        var contenitore = Find("ContenitoreDelCollezione").GetComponent<CollezioneComponent>();

        var tutti = FindObjectsOfType<GameObject>();
        foreach (var obj in tutti)
        {
            var consumatori = obj.GetComponents<IConsumatoreDelCollezione>();
            foreach (var consumatore in consumatori)
            {
                consumatore.Collezione = contenitore.collezione;
            }
        }
    }
}

重要的是你不应该在消费者的唤醒事件期间使用Collection ,因为它可能还没有被注入。 至少在Start中使用它等等。

此外,使用 DI 容器框架(例如 Zenject)可能更容易实现所有这些。 所以你可以看看这个。

希望这会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM