Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

NullReferenceException

Discussion in 'Scripting' started by Ben_Kregor, Feb 14, 2016.

  1. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    I'm trying to allow my player to pick up items.

    Error: NullReferenceException: Object reference not set to an instance of an object

    It brings me to this line:

    Code (CSharp):
    1.             if (itemToAdd.Stackable && CheckIfItemIsInInventory(itemToAdd))
    2.             {
    Here's the rest of my code:

    Pickup Item Class:
    Code (CSharp):
    1. void Update()
    2.         {
    3.             Vector3 fwd = transform.TransformDirection(Vector3.forward);
    4.             RaycastHit hit;
    5.  
    6.             if (Physics.Raycast(transform.position, fwd, out hit))
    7.             {
    8.                 canHover = true;
    9.  
    10.                 if (hit.distance <= 5 && hit.collider.gameObject.CompareTag("Item"))
    11.                 {
    12.                     if (Input.GetKeyDown(KeyCode.F))
    13.                     {
    14.                         gameObj = hit.collider.gameObject;
    15.                         inv.AddItem(gameObj.GetComponents<Data>().id);
    16.                         Destroy(gameObj);
    17.                      
    18.                          
    19.  
    20.                     }
    21.  
    22.                 }

    Add Item Class:

    Code (CSharp):
    1.         public void AddItem(int id)
    2.         {
    3.  
    4.             Item itemToAdd = dataBase.FetchItemByID(id);
    5.  
    6.             if (itemToAdd.Stackable && CheckIfItemIsInInventory(itemToAdd))
    7.             {
    8.                 for (int i = 0; i < items.Count; i++)
    9.                 {
    10.                     if (items[i].ID == id)
    11.                     {
    12.                         ItemData data = slots[i].transform.GetChild(0).GetComponent<ItemData>();
    13.                         data.amount++;
    14.                         data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
    15.                         break;
    16.  
    17.  
    18.                     }
    19.  
    20.                 }
    21.  
    22.             }
    23.             else
    24.             {
    25.  
    26.                 for (int i = 0; i < items.Count; i++)
    27.                 {
    28.  
    29.                     if (items[i].ID == -1)
    30.                     {
    31.  
    32.                         items[i] = itemToAdd;
    33.                         GameObject itemObj = Instantiate(inventoryItem);
    34.                         itemObj.GetComponent<ItemData>().item = itemToAdd;
    35.                         itemObj.GetComponent<ItemData>().amount = 1;
    36.                         itemObj.GetComponent<ItemData>().slot = i;
    37.                         itemObj.transform.position = Vector2.zero;
    38.                         itemObj.transform.SetParent(slots[i].transform, false);
    39.                         itemObj.GetComponent<Image>().sprite = itemToAdd.Sprite;
    40.                         itemObj.name = itemToAdd.Title;
    41.                         break;
    42.  
    43.  
    44.                     }
    45.                 }
    46.             }
    47.           }
     
  2. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    this is just a guess. In your AddItem Class, edit this line (line 33 in your quoted code)
    Code (CSharp):
    1. GameObject itemObj = Instantiate(inventoryItem);
    into this
    Code (CSharp):
    1. GameObject itemObj = Instantiate(inventoryItem) as GameObject;
     
  3. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    thanks for your reply but that didn't fix it I still have the same error pop up.
     
  4. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    What exactly is "inventoryItem" though. This is a reference, but there is no creation of it in the script you show here.
     
  5. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine.UI;
    5.  
    6. namespace Outlived
    7. {
    8.  
    9.     public class Inventory : MonoBehaviour
    10.     {
    11.  
    12.         GameObject inventoryPanel;
    13.         GameObject slotPanel;
    14.         ItemDatabase dataBase;
    15.         public GameObject inventorySlot;
    16.         public GameObject inventoryItem;
    17.  
    18.         private int slotAmount;
    19.  
    20.         public List<Item> items = new List<Item>();
    21.         public List<GameObject> slots = new List<GameObject>();
    22.  
    23.         void Start()
    24.         {
    25.             dataBase = GetComponent<ItemDatabase>();
    26.             slotAmount = 10;
    27.             inventoryPanel = GameObject.Find("Inventory Panel");
    28.             slotPanel = inventoryPanel.transform.FindChild("Slot Panel").gameObject;
    29.             for(int i = 0; i < slotAmount; i++)
    30.                 {
    31.  
    32.                 items.Add(new Item());
    33.                 slots.Add(Instantiate(inventorySlot));
    34.                 slots[i].GetComponent<Slot>().id = i;
    35.                 slots[i].transform.SetParent(slotPanel.transform, false);
    36.  
    37.                 }
    38.  
    39.             AddItem(0);
    40.             AddItem(1);
    41.             AddItem(2);
    42.             AddItem(2);
    43.  
    44.  
    45.         }
    46.  
    47.  
    48.         public void AddItem(int id)
    49.         {
    50.  
    51.             Item itemToAdd = dataBase.FetchItemByID(id);
    52.  
    53.             if (itemToAdd.Stackable && CheckIfItemIsInInventory(itemToAdd))
    54.             {
    55.                 for (int i = 0; i < items.Count; i++)
    56.                 {
    57.                     if (items[i].ID == id)
    58.                     {
    59.                         ItemData data = slots[i].transform.GetChild(0).GetComponent<ItemData>();
    60.                         data.amount++;
    61.                         data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
    62.                         break;
    63.  
    64.  
    65.                     }
    66.  
    67.                 }
    68.  
    69.             }
    70.             else
    71.             {
    72.  
    73.                 for (int i = 0; i < items.Count; i++)
    74.                 {
    75.  
    76.                     if (items[i].ID == -1)
    77.                     {
    78.  
    79.                         items[i] = itemToAdd;
    80.                         GameObject itemObj = Instantiate(inventoryItem);
    81.                         itemObj.GetComponent<ItemData>().item = itemToAdd;
    82.                         itemObj.GetComponent<ItemData>().amount = 1;
    83.                         itemObj.GetComponent<ItemData>().slot = i;
    84.                         itemObj.transform.position = Vector2.zero;
    85.                         itemObj.transform.SetParent(slots[i].transform, false);
    86.                         itemObj.GetComponent<Image>().sprite = itemToAdd.Sprite;
    87.                         itemObj.name = itemToAdd.Title;
    88.                         break;
    89.  
    90.  
    91.                     }
    92.                 }
    93.             }
    94.           }
    95.  
    96.  
    97.  
    98.         bool CheckIfItemIsInInventory(Item item)
    99.         {
    100.             for (int i = 0; i < items.Count; i++) {
    101.  
    102.             if (items[i].ID == item.ID)
    103.                 return true;
    104.  
    105.          }
    106.  
    107.             return false;
    108.         }
    109.  
    110.  
    111.     }
    112.  
    113. }
    114.  
     
  6. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    could i have a look at the FetchItemById() function in database
     
  7. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    Code (CSharp):
    1.  
    2.         public Item FetchItemByID(int id)
    3.         {
    4.             for (int i = 0; i < dataBase.Count; i++)
    5.             {
    6.                 if (dataBase[i].ID == id)
    7.                 return dataBase[i];
    8.             }
    9.             return null;
    10.  
    11.         }
     
  8. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Looks like FetchItemByID might be returning null, and when it passes the null value over to itemToAdd, itemToAdd becomes null. So if itemToAdd is null, CheckIfItemIsInInventory has nothing to work with. You should put a print statement in 2 places:
    1) the for-loop of FetchItemByID to see if the ID you gave is a valid ID inside database.
    2) the for-loop of CheckIfItemIsInInventory to see if your script even enters the for-loop.
     
  9. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    It gets passed

    Code (CSharp):
    1.             if (itemToAdd.Stackable && CheckIfItemIsInInventory(itemToAdd))
    2.             {
    but not passed the for loop
     
  10. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    What do you mean by "It gets passed"? Where does print get called, in FetchItemByID, in the forloop inside FetchItemByID, or the "if" statement inside the forloop in FEtchItemByID?
     
  11. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
    It gets passed the for loop and the if statement
    Code (CSharp):
    1.         public Item FetchItemByID(int id)
    2.         {
    3.             for (int i = 0; i < dataBase.Count; i++)
    4.             {
    5.                 if (dataBase[i].ID == id)
    6.                 {
    7.                     Debug.Log("hey");
    8.                     return dataBase[i];
    9.                 }
    10.             }
    11.             return null;
    12.  
    13.         }
     
  12. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
  13. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
  14. Ben_Kregor

    Ben_Kregor

    Joined:
    Aug 21, 2015
    Posts:
    54
  15. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    you're testing in the wrong place the problem is in the Inventory class, not the Database class you need to add a null check in case the add method passed in an invalid id

    Code (CSharp):
    1.         Item itemToAdd = dataBase.FetchItemByID(id);
    2.  
    3.         if(itemToAdd == null || ReferenceEquals(itemToAdd,null) || itemToAdd.Equals(null) )
    4.         {
    5.             return;
    6.         }
    7.  
    8.         if (itemToAdd.Stackable && CheckIfItemIsInInventory(itemToAdd))