Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Last item in my inventory can't be dropped.

Discussion in 'Scripting' started by berndunity, Jul 12, 2018.

  1. berndunity

    berndunity

    Joined:
    Feb 14, 2018
    Posts:
    6
    [Question] Can't instantiate the last object
    Bernd · 9 uur geleden


    I'm trying to create a inventory, which is working fine, but when I press the button to remove a item from my inventory it does, but for the last object it doesn't instatiate a item to drop. When I try to remove the last object from my inventory it says, object reference not set to instance of a object. I have tried a lot, but nothing worked. Hopefully someone can help me.

    With last item in the inventory I mean the item at the end of the row, so not the last object that stays in the inventory. Think about it like there are three items in the inventory, the first and second item in the inventory can be dropped and instantiate, but the third one can't. It can be removed, but it doesn't drop anything even if it's the first item you drop. The error isn't only for the last item in the inventory it's for every item, but they just instatiate a object where the third item don't.

    Because I don't know what is exactly causing the error, I paste all the code related to error. (the error is in the OnRemoveButton method with Instantiate(item.objectToDrop, player.position, player.rotation))

    This is my code:
    1. Code (CSharp):
      1. public class InventorySlot : MonoBehaviour {
      2.     public Image icon;
      3.     public Button removeButton;
      4.     public Transform player;
      5.     private Item item;
      6.     private void Start()
      7.     {
      8.         item = FindObjectOfType<Item>();
      9.     }
      10.     public void AddItem(Item newItem) {
      11.         item = newItem;
      12.         icon.sprite = item.icon;
      13.         icon.enabled = true;
      14.         removeButton.GetComponent<Image>().enabled = true;
      15.     }
      16.     public void ClearSlot() {
      17.         item = FindObjectOfType<Item>();
      18.         item = null;
      19.         icon.sprite = null;
      20.         icon.enabled = false;
      21.         removeButton.GetComponent<Image>().enabled = false;
      22.     }
      23.     public void OnRemoveButton() {
      24.         PlayerInventory.instance.Remove(item);
      25.         Instantiate(item.objectToDrop, player.position, player.rotation);
      26.     }
      27. }
    2. Code (CSharp):
      1. public class InventoryUI : MonoBehaviour {
      2.     public Transform itemsParent;
      3.     private PlayerInventory inventory;
      4.     private InventorySlot[] slots;
      5.     void Start () {
      6.         inventory = PlayerInventory.instance;
      7.         inventory.onItemChangedCallBack += UpdateUI;
      8.         slots = itemsParent.GetComponentsInChildren<InventorySlot>();
      9.     }
      10.     private void Update()
      11.     {
      12.         UpdateUI();
      13.     }
      14.     private void UpdateUI()
      15.     {
      16.         for (int i = 0; i < slots.Length; i++)
      17.         {
      18.             if (i < inventory.items.Count)
      19.             {
      20.                 slots[i].AddItem(inventory.items[i]);
      21.             }
      22.             else
      23.             {
      24.                 slots[i].ClearSlot();
      25.             }
      26.         }
      27.     }
      28. }
    3. Code (CSharp):
      1. [code=CSharp][CreateAssetMenu(fileName = "new item", menuName = "Inventory/Item")]
      2. public class Item : ScriptableObject {
      3.  
      4.     new public string name = "new item";
      5.     public Sprite icon = null;
      6.     public bool isDefaultItem = false;
      7.     public GameObject objectToDrop;
      8. }
    4. public bool Add(Item item) {
      if (!item.isDefaultItem) {
      if (items.Count >= inventorySpace) {
      Debug.Log("not enough space to pickup");
      return false;
      }
      items.Add(item);
      if (onItemChangedCallBack != null) {
      onItemChangedCallBack.Invoke();
      }
      }
      return true;
      }
      public void Remove(Item item) {
      items.Remove(item);
      if (onItemChangedCallBack != null)
      {
      onItemChangedCallBack.Invoke();
      }
      }
      }[/code]
    The last code is from the playerinventory.
    If someone sees what is causing the error let me know.

    P.S. If you see something I have to change to make the code easier or smaller or something else, say it please.

    Thanks for helping!
    (I'm not good at english).
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,116
    It sounds like you're calling ClearSlot(), causing `item` to be set to null, thus the NullReferenceException in your OnRemoveButton method. That error just means you're trying to access a property or a method of something that's null. Your ClearSlot function sets `item` to null, and I'd assume that's getting called some time before you press the remove button.

    In any case, you should probably look at whether ClearSlot() is clearing out the item before you remove it.

    Also, having an OnRemoveButton method that doesn't accept a parameter seems fragile to me. I'd recommend that the method pass in at least the index of the item to remove maybe.
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Some thoughts on your code:

    I don't think you should update the UI in Update(). Simply update the UI when your inventory changes (add/remove/move an item).

    I do not think that FindObjectOfType is what you want. I would imagine that you want to have the variable in the inventory's slot set to whatever's added, or to null on removal.

    Since you have an array of InventorySlot, you may not need a list of Items; since the items should be variables as part of the InventorySlot class.
     
  4. berndunity

    berndunity

    Joined:
    Feb 14, 2018
    Posts:
    6
    You both were right, the item = null should be behind the instatiate method and I shouldn't have used FindObjectOfType. Also the UpdateUI didn't need to be in the Update().

    Tanks for helping me.