0

created an inventory system and while each item worked the button that uses the item would always be the same regardless of what item it was. to fix this I used this

public class InventoryManager : MonoBehaviour
{
    public static InventoryManager Instance;
    public List<InventoryItem> inventoryItems = new List<InventoryItem>();
    public Transform itemContent;
    public GameObject inventoryItemObject;
  public void ListItems()
    {
        foreach (var InventoryItem in inventoryItems)
        {
            GameObject obj = Instantiate(inventoryItemObject, itemContent);
            var item_name = obj.transform.Find("inventory/Item_name").GetComponent<Text>();
            var item_icon = obj.transform.Find("inventory/Item_icon").GetComponent<Image>();

            item_name.text = InventoryItem.item_name;
            item_icon.sprite = InventoryItem.item_icon;
        }
     
    }

the issue is it doesn't work and I get the error: NullReferenceException: Object reference not set to an instance of an object InventoryManager.ListItems () (at Assets/Scripts/InventoryManager.cs:47)

the names Item_name and Item_icon do match with the varibles each item has enter image description here

and the items are in the inventory folder

enter image description here

so I don't know how this isn't working

  • 1
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – madreflection Apr 27 '22 at 16:03
  • unfortunately not. my issue is that it should be pointing to the correct variables and I don't know why it isn't. the naming is correct – programstudent1 Apr 27 '22 at 16:11
  • What line is 47? Where do inventoryItemObject and itemContent get set? – michaela112358 Apr 27 '22 at 16:22
  • I've got a whole long answer in the works here, but as I'm writing it I don't understand quite what you've got going on here. Is `GameObject obj = Instantiate(inventoryItemObject, itemContent);` instantiating a prefab? Does it have an `InventoryItem` script attached or are there actually child GameObjects attached? – Chuck Apr 27 '22 at 16:23
  • It could be that `inventoryItemObject` is null and you're not able to instantiate a null prefab, or it could be that you don't have child GameObjects attached and `transform.Find` is returning null, or it could be that the `Text` and/or `Image` components don't exist and trying to set their values is what's throwing. You've got a lot going on here that could all throw the same error lol. – Chuck Apr 27 '22 at 16:25
  • 1
    @Chuck: `NullReferenceException` is solved by an existing answer. There's a [canonical question](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) with answers for that problem because it's so common. OP has to do more debugging. Plain and simple. No need to waste your time answering such questions. – madreflection Apr 27 '22 at 16:25
  • @Chuck there is an inventoryItem script attached. I'll try and figure out which of those is flagging this error. thanks – programstudent1 Apr 27 '22 at 16:34
  • @michaela112358 line 47 is: var item_name = obj.transform.Find("inventory/Item_name").GetComponent(); inventoryitemobject and itemcontent get set at the start of the class. I have edited the question to reflect this – programstudent1 Apr 27 '22 at 16:52
  • @madreflection - As I try to point out in my answer below, I think this is an issue where OP has misunderstood how to access script fields. Unity programming isn't vanilla C# and there are lots of ways to screw up. A NRE is pretty common, but understanding *why* you have one can be difficult. – Chuck Apr 27 '22 at 18:33
  • 1
    @Chuck: OP first needs to figure out *what* is returning `null`. They stopped short of that, and so they had no way of digging into the aspects of the problem that more narrowly relate to the root cause. Unity programming may be different from vanilla C#, but the same debugging and documentation-reading skills apply and yet rarely seem to be employed. – madreflection Apr 27 '22 at 18:40
  • @madreflection fair point lol – Chuck Apr 27 '22 at 19:11

1 Answers1

0

You shared the error, that lists a line number, but you only gave us a snippet of the code, so I can't tell where exactly your error is occurring.

That said, I'm willing to bet it's on the following line:

var item_name = obj.transform.Find("inventory/Item_name").GetComponent<Text>();

What I think you're trying to do is to get the string Item_name from the newly-instantiated InventoryItem.

Here's what you're code is actually doing:

  1. When you call transform.Find(), Unity is going to look for GameObjects that are children of the obj transform.
  2. I believe that you're actually trying to reference a field of the InventoryItem and not a child GameObject, so I believe the transform.Find() is returning null.
  3. When the transform.Find() returns null, you're then trying to perform null.GetComponent<>(); which is throwing the exception.

So, that said, I think it's an easy fix! I'm assuming you're instantiating a prefab here that already has an InventoryItem attached, so instead of trying to search the GameObject hierarchy to find the fields you should instead be getting the InventoryObject MonoBehaviour and then you can get the fields from there. NOTE: Those fields have to be public to access them. If you don't want other classes to be able to modify the values then you can use Properties.

Consider the following changes:

public void ListItems()
{
    foreach (var InventoryItem in inventoryItems)
    {
        GameObject prefabInstance = Instantiate(inventoryItemObject, itemContent);
        var instanceInventoryItem = prefabInstance.GetComponent<InventoryItem>();

        instanceInventoryItem.Item_name = InventoryItem.item_name;
        instanceInventoryItem.Item_icon = InventoryItem.item_icon;
    }
 
}
Chuck
  • 1,977
  • 1
  • 17
  • 23