【问题标题】:Unity: How to not add references into List with GetComponent()?Unity:如何不使用 GetComponent() 将引用添加到列表中?
【发布时间】:2018-10-02 02:29:41
【问题描述】:

我有一个组件列表,我想给它一些像这样的值。

public LoadButtonData loadButtonData;

GameObject clone = Instantiate(buttonPrefab, transform);
LoadButtonProperties properties = clone.GetComponent<LoadButtonProperties>();
properties.filePath = filePath;
properties.Date.text = time.ToShortDateString();
properties.Name.text = fileName;
properties.Place.text = DataLoaded.sceneName;
properties.Thumbnail.sprite = newSprite;
loadButtonData.loadButtons.Add(properties);

LoadButtonData 是使用 DontDestroyOnLoad() 包含在另一个对象中的对象,并在多个场景中使用。但是,切换场景后,会发生这种情况:

我知道这是因为属性作为引用添加到列表中,并且在更改场景时,按钮克隆被破坏并且不能再被引用。

是否有解决方法,让我在整个场景中重用我的值作为实际值而不是引用?如何添加克隆的LoadButtonProperties 数据的副本,而不是对克隆的引用?

编辑:重新表述上述问题以进行澄清

编辑:这是 LoadButtonProperties 类

public class LoadButtonProperties : MonoBehaviour
{
    /// <summary>
    /// Path to the json file for loading
    /// </summary>
    public string filePath;

    [Tooltip("Place Date here")]
    public TextMeshProUGUI Date;
    [Tooltip("Place Name here")]
    public TextMeshProUGUI Name;
    [Tooltip("Place Place here")]
    public TextMeshProUGUI Place;
    [Tooltip("Place Thumbnail here")]
    public Image Thumbnail;
}

尝试进行深度克隆,但由于Image 变量,我无法做到这一点

【问题讨论】:

  • 你有没有研究过附加关卡加载?
  • 是否建议为 VR 应用加载多个关卡?仅加载 1 占用接近 1gb 的内存
  • 附加加载关卡是避免这种情况的一种已知方法!拆分您的关卡,加载您现在正在使用的部分,并卸载您不使用的部分。你会在 AAA 游戏中看到很多这种情况,通常会有电梯之类的东西来拆分关卡并允许异步加载。您可以在冒险游戏教程youtube.com/watch?v=Vi8S2PgMvds 中找到持久关卡的示例

标签: list unity3d pass-by-reference gameobject cloning


【解决方案1】:

你(实际上)不能

保持这些引用“活动”的唯一方法是首先防止这些对象被破坏(在处理场景变化时这是不可行的)。

在对象从内存中删除并重新创建时保持...“保持”对象实际上是不可能的。您可能可以设置一些奇怪的序列化/反序列化步骤,但是您必须将列表设置为某种 UUID,当您更改场景时,对象会计算出它们的 UUID,并且列表会在场景中查询具有该 UUID 的对象,但是……会很乱。甚至可能不会一直工作。

您最好说“这些数据是不稳定的”并牢记这一点。让事物过期并在场景发生变化时重新创建(如果需要)它们。

【讨论】:

  • 看来我的问题的最后几句话没有正确表达。我想将这些值用作缓存数据而不是引用
  • @Ryolu 你不能。当场景改变并且那些物体被破坏时,它们就消失了。如果你想缓存他们的data,缓存他们的data。
  • 我应该怎么做呢?我尝试了深度克隆,但我似乎无法让它工作,因为我有 Image 变量
  • GameObject != Data, Component != Data。创建一个你控制的类来存储相同的信息并将那个推到你的列表中。
  • 该课程正在编辑中。但是,它是要销毁的GameObject 的一个组件
【解决方案2】:

你的问题有点自相矛盾,因为你问如何在场景之间保留引用,然后又问如何不在场景之间保留它们。

至于如何在场景之间清除它们,您可以使用新列表重置按钮列表。这将使您在场景之间从头开始。

如果你想在场景之间保留数据和对象,你可以使用序列化和 DontDestroyOnLoad

查看本教程:https://unity3d.com/learn/tutorials/topics/scripting/persistence-saving-and-loading-data,了解有关数据持久性的更多信息。

编辑: 要在场景之间切换时销毁所有按钮,您可以按照以下方式进行操作:

foreach (LoadButtonProperties buttonToDelete in loadButtons) {
    Destroy(buttonToDelete.gameObject);
}

【讨论】:

  • 对不起,如果我的措辞不正确。这些按钮是特定于场景的,必须在改变场景时销毁。我正在尝试将数据作为对象传递而不是引用
  • 查看编辑。您可以通过 .gameObject 属性访问组件的对象。
  • 按钮破坏了。我担心的是,如果有任何其他方式来存储这些按钮所持有的信息而不实际保留按钮本身
  • 我认为您需要编辑您的问题以提高清晰度。这里的两个答案都完全误解了你的目标。
  • 我不知道如何表达它,我的英语水平不够。有什么建议吗?
【解决方案3】:

它不漂亮,但你必须复制/克隆所有元素(如果其中一个是列表,如果你克隆列表,它不会是相同的,但列表中的元素将是参考)。

您可以尝试使用只传递数据的临时对象。

【讨论】:

  • 我试过这个,但我无法克隆Thumbnail,因为它是Image
  • 这个question 解决了如何实例化一个图像。
猜你喜欢
  • 2020-01-30
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
  • 2014-08-22
  • 2022-11-24
  • 2014-12-29
  • 1970-01-01
相关资源
最近更新 更多