【问题标题】:How i can destroy an GameObject but also store the gameobject in a variable我如何销毁游戏对象但也将游戏对象存储在变量中
【发布时间】:2017-06-11 03:03:44
【问题描述】:

当我在场景中选择一个项目时,它会调用 AddItem() 方法,该方法会将项目添加到列表中并从场景中销毁游戏对象,但是当我尝试访问列表中的游戏对象时,出现错误。

“MissingReferenceException:'GameObject' 类型的对象已被销毁,但您仍在尝试访问它。”

public class Inventory : MonoBehaviour
{
    public List<GameObject> itemsGOInInventory = new List<GameObject>();

    public void AddItem(GameObject itemToBeAdded)
    {
        itemsGOInInventory.Add(itemToBeAdded);
        Destroy(itemToBeAdded);
    }

    public void FindItem(string name)
    {
        foreach (GameObject item in itemsGOInInventory)
        {
            if (item.GetComponent<Item>().itemName == "pistol")
            {
                Instantiate(item.GetComponent<Item>().itemObject, this.transform);
            }
        }
    }
}

【问题讨论】:

  • "此方法会将项目添加到列表并从场景中销毁游戏对象,但是当我尝试访问列表中的游戏对象时会出现此错误".. .这回答了你的问题......你正试图访问一个被破坏的对象。当您销毁并尝试访问它时,您期望会发生什么?
  • Destroy() 相当于一个碎纸机。你不能把东西放进去然后保存它。这是一个吃蛋糕/吃它的问题。

标签: c# unity3d gameobject


【解决方案1】:

一旦你摧毁了游戏对象,它就消失了。

您可以做的是持有对该对象的引用,然后将其存储在某处并使其不可见。它称为对象池。

Unity 在这里有一个教程:https://unity3d.com/learn/tutorials/topics/scripting/object-pooling

您需要将游戏对象 SetActive 设置为 false 或使用其他方式使其不可见。 https://docs.unity3d.com/ScriptReference/GameObject.SetActive.html

你已经有了对象列表,所以不要使用 Destroy(),而是使用 SetActive(false);

itemToBeAdded.SetActive(false);

希望这会有所帮助。

【讨论】:

  • 谢谢,这真的很有帮助
  • @NicolasPereiraCoutinho np 很高兴我能帮上忙 =) 如果是,你能把它标记为答案吗? xP 谢谢
  • 我该怎么做?我是新来的,我现在真的不知道该怎么做
  • @NicolasPereiraCoutinho Here 你去
【解决方案2】:

你说一旦它被拾起你就摧毁了游戏对象。一旦被销毁,它就不存在并且对 GameObject 的所有引用都是空的。在您的情况下保留游戏对象列表是一个坏主意。相反,您应该有一个用于库存项目的模型类。

public class InventoryItem
{
    string name;
    string description;
    string spritePath;
    // other variables
}

您应该创建一个单独的类来表示场景中的 InventoryItem。你可以在你的游戏对象上有这样的东西:

public class InventoryItemView : MonoBehaviour
{
    public InventoryItem item;
    // ...
}

现在将项目脚本放在场景中的“项目”上。每当您选择一个项目时,从游戏对象中获取 InventoryItem 脚本并将其添加到您的 Inventory 中的 InventoryItems 列表中。然后销毁游戏对象。现在,即使您的游戏对象被销毁,您仍然拥有您的 InventoryItem 对象。

public class Inventory : MonoBehaviour
{
    public List<InventoryItem> itemsGOInInventory = new List<InventoryItem>();

    public void AddItem(GameObject itemToBeAdded)
    {
        itemsGOInInventory.Add(itemToBeAdded.GetComponent<InventoryItemView>().item);
        Destroy(itemToBeAdded);
    }
//...
}

您可能想要检查 GameObject 上是否有 InventoryItemView 脚本。

理想情况下,您的清单类不应该是 MonoBehaviour,一个可序列化的类就足够了,但这不是主题。

【讨论】:

  • 它们是一些简单的 oop 概念
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-25
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多