Null ref exception

Hi there, I’m creating an inventory/equipment system and i get a null ref exception when dragging an item from the equipment to the inventory. I have been stuck on this for weeks trying different things but i cannot find what is causing the error. Here are some parts of different scripts. if there’s something more needed whether its code or explanation ill try to reply asap.

using UnityEngine;
public enum ItemType
{
    Equipment,
    Consumable
}
public enum EquipmentType
{
    None,
    Weapon,
    Shield,
    Armor
}

public enum ArmorType
{
    None,
    Head,
    Chest,
    Hands,
    Legs,
    Feet
}
public enum StatToChange
{
    None,
    Health
}

[CreateAssetMenu(fileName = "New Item")]
public class ItemSO : ScriptableObject
{
    public string itemName;
    public ItemType itemType;
    public EquipmentType equipmentType;
    public EquipmentSlotType equipmentSlotType;
    public ArmorType armorType;
    public Attribute attributeToChange;
    public StatToChange statToChange;
    public int minValue;
    public int maxValue;
    public int valueConsumable;
    public Sprite itemSprite;
    public bool isStackable;
    [Range(0,100)]public float dropChance;
    //public GameObject model; add if you want 3D

    [TextArea] public string itemDescription;

    public int startingAmount = 1;


    public void UseHealingItem()
    {
        FindObjectOfType<Player>().GetComponent<Stats>().currentHealth += valueConsumable;
        Debug.Log("Healed for " + valueConsumable);
        //update ui
    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class ItemData
{
    public ItemSO itemSO;
    public int itemAmount;
    public int value;
    public EquipmentSlotType equipmentSlotType;


    public ItemData(ItemSO itemSO, EquipmentSlotType equipmentSlotType, int valueConsumable = 0, bool calcValue = true)
    {
        this.itemSO = itemSO;
        itemAmount = itemSO.startingAmount;
        this.equipmentSlotType = equipmentSlotType;


        if (calcValue)
        {
            if (itemSO.itemType == ItemType.Equipment)
            {
                value = UnityEngine.Random.Range(itemSO.minValue, itemSO.maxValue);
            }
            else value = valueConsumable;
        }
    }


    public void ResetEquipData()
    {
        itemSO = null;
        value = 0;
    }
}
//ITEM SLOT SCRIPT

public void OnDrop(PointerEventData eventData)
{
    if (eventData.pointerDrag == null)
    {
        Debug.LogError("OnDrop: eventData.pointerDrag is null");
        return;
    }

    var equipmentSlot = eventData.pointerDrag.GetComponent<EquipmentSlot>();


 
    else if (equipmentSlot != null) // if item from equip slot is dropped on this
    {
        Debug.Log("OnDrop from Equipment slot to InventorySlot");

        if (equipmentSlot == null)
        {
            Debug.LogError("OnDrop: equipmentSlot is null");
            return;
        }

        if (equipmentSlot.itemEquipped == null)
        {
            Debug.LogError("OnDrop: equipmentSlot.itemEquipped is null");
            return;
        }

        if (equipmentSlot.itemEquipped.itemSO == null)
        {
            Debug.LogError("OnDrop: equipmentSlot.itemEquipped.itemSO is null");
            return;
        }

        //if theres an item, do nothing.
        if (itemDataInsideSlot.itemSO != null)
        {
            return;
        }


        inventoryUI.DeselectAllSlots();
        inventoryUI.DeselectAllEquipSlots();
        selectedPanel.SetActive(true);

    
        InventorySlotManager.instance.RemoveItemFromEquipmentAndAddToInventorySlot(this, equipmentSlot.equipmentSlotType);

    }
    else
    {
        Debug.Log("OnDrop: Not dropped on a valid slot");
    }
}
//INVENTORY SLOT MANAGER SCRIPT

public class InventorySlotManager : MonoBehaviour
{
    [SerializeField] EquipmentSlot equipmentSlotHead;
    [SerializeField] EquipmentSlot equipmentSlotChest;
    [SerializeField] EquipmentSlot equipmentSlotWeapon;
    [SerializeField] EquipmentSlot equipmentSlotShield;
    [SerializeField] EquipmentSlot equipmentSlotLegs;
    [SerializeField] EquipmentSlot equipmentSlotFeet;

    [SerializeField] Sprite transparentImage;

    public static InventorySlotManager instance;

    private void Awake()
    {
        instance = this;
    }


public void RemoveItemFromEquipmentAndAddToInventorySlot(InventorySlotMainMenu inventorySlot, EquipmentSlotType equipmentSlotType)
    {

        ItemData itemToRemove = null;

        switch (equipmentSlotType)
        {
            case EquipmentSlotType.Head:
                itemToRemove = equipmentSlotHead.itemEquipped;
                itemToRemove.itemSO = equipmentSlotHead.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotHead.itemEquipped.itemSO.itemSprite;

                equipmentSlotHead.itemEquipped.itemSO = null;
                equipmentSlotHead.itemEquipped.value = 0;
                equipmentSlotHead.image.sprite = transparentImage;
                break;

            case EquipmentSlotType.Chest:
                itemToRemove = equipmentSlotChest.itemEquipped;
                itemToRemove.itemSO = equipmentSlotChest.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotChest.itemEquipped.itemSO.itemSprite;

                equipmentSlotChest.itemEquipped.itemSO = null;
                equipmentSlotChest.itemEquipped.value = 0;
                equipmentSlotChest.image.sprite = transparentImage;
                break;

            case EquipmentSlotType.Weapon:
                itemToRemove = equipmentSlotWeapon.itemEquipped;
                itemToRemove.itemSO = equipmentSlotWeapon.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotWeapon.itemEquipped.itemSO.itemSprite;

                Debug.Log(itemToRemove.itemSO.itemSprite.name);
                Debug.Log(equipmentSlotWeapon.itemEquipped.itemSO.itemName);

                equipmentSlotWeapon.itemEquipped.itemSO = null;
                equipmentSlotWeapon.itemEquipped.value = 0;
                equipmentSlotWeapon.image.sprite = transparentImage;
                break;

            case EquipmentSlotType.Shield:
                itemToRemove = equipmentSlotShield.itemEquipped;
                itemToRemove.itemSO = equipmentSlotShield.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotShield.itemEquipped.itemSO.itemSprite;
                equipmentSlotShield.itemEquipped.itemSO = null;

                equipmentSlotShield.itemEquipped.value = 0;
                equipmentSlotShield.image.sprite = transparentImage;
                break;

            case EquipmentSlotType.Legs:
                itemToRemove = equipmentSlotLegs.itemEquipped;
                itemToRemove.itemSO = equipmentSlotLegs.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotLegs.itemEquipped.itemSO.itemSprite;

                equipmentSlotLegs.itemEquipped.itemSO = null;
                equipmentSlotLegs.itemEquipped.value = 0;
                equipmentSlotLegs.image.sprite = transparentImage;
                break;

            case EquipmentSlotType.Feet:
                itemToRemove = equipmentSlotFeet.itemEquipped;
                itemToRemove.itemSO = equipmentSlotFeet.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotFeet.itemEquipped.itemSO.itemSprite;

                equipmentSlotFeet.itemEquipped.itemSO = null;
                equipmentSlotFeet.itemEquipped.value = 0;
                equipmentSlotFeet.image.sprite = transparentImage;
                break;
        }

        // Add the item to the inventory slot
        inventorySlot.itemDataInsideSlot.itemSO = itemToRemove.itemSO;
        inventorySlot.itemDataInsideSlot.value = itemToRemove.value;

        if (itemToRemove == null) Debug.Log("itemtoremove data is null");
        if (itemToRemove.itemSO == null) Debug.Log("itemso is null");
        if (itemToRemove.itemSO.itemSprite == null) Debug.Log("itemso sprite is null");
        Debug.Log(itemToRemove.itemSO.itemSprite.name);

        inventorySlot.image.sprite = itemToRemove.itemSO.itemSprite;

        Debug.Log(itemToRemove.itemSO.itemSprite.name);

    }


}

//DEBUG:
Added to weapon
UnityEngine.Debug:Log (object)
InventorySlotManager:AddItemFromInventoryToEquipmentSlot (ItemData,InventorySlotMainMenu,EquipmentSlot) (at Assets/InventorySlotManager.cs:56)
EquipmentSlot:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/EquipmentSlot.cs:159)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

Sword2
UnityEngine.Debug:Log (object)
EquipmentSlot:OnLeftClick () (at Assets/Scripts/EquipmentSlot.cs:69)
EquipmentSlot:OnBeginDrag (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/EquipmentSlot.cs:99)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

OnDrop from Equipment slot to InventorySlot
UnityEngine.Debug:Log (object)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:201)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

Sword_v2_10
UnityEngine.Debug:Log (object)
InventorySlotManager:RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu,EquipmentSlotType) (at Assets/InventorySlotManager.cs:116)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

Sword2
UnityEngine.Debug:Log (object)
InventorySlotManager:RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu,EquipmentSlotType) (at Assets/InventorySlotManager.cs:117)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

itemso is null
UnityEngine.Debug:Log (object)
InventorySlotManager:RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu,EquipmentSlotType) (at Assets/InventorySlotManager.cs:160)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

NullReferenceException: Object reference not set to an instance of an object
InventorySlotManager.RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu inventorySlot, EquipmentSlotType equipmentSlotType) (at Assets/InventorySlotManager.cs:161)
InventorySlotMainMenu.OnDrop (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IDropHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:92)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

You know from the error message what line the error is on (“at Assets/InventorySlotManager.cs:161” means line 161) and you have a debugger that lets you walk through your code and see all the values and how they change as the code runs.

yes i understand that, i just dont understand why this fires

        if (itemToRemove.itemSO == null) Debug.Log("itemso is null");

because i’m setting the itemToRemove.itemSO here

case EquipmentSlotType.Weapon:
                itemToRemove = equipmentSlotWeapon.itemEquipped;
                itemToRemove.itemSO = equipmentSlotWeapon.itemEquipped.itemSO;
                itemToRemove.itemSO.itemSprite = equipmentSlotWeapon.itemEquipped.itemSO.itemSprite;
                Debug.Log(itemToRemove.itemSO.itemSprite.name);
                Debug.Log(equipmentSlotWeapon.itemEquipped.itemSO.itemName);
                equipmentSlotWeapon.itemEquipped.itemSO = null;
                equipmentSlotWeapon.itemEquipped.value = 0;
                equipmentSlotWeapon.image.sprite = transparentImage;
                break;

and inside this, the debu.log states that it exists

Sword_v2_10
UnityEngine.Debug:Log (object)
InventorySlotManager:RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu,EquipmentSlotType) (at Assets/InventorySlotManager.cs:116)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

Sword2
UnityEngine.Debug:Log (object)
InventorySlotManager:RemoveItemFromEquipmentAndAddToInventorySlot (InventorySlotMainMenu,EquipmentSlotType) (at Assets/InventorySlotManager.cs:117)
InventorySlotMainMenu:OnDrop (UnityEngine.EventSystems.PointerEventData) (at Assets/Scripts/InventorySlotMainMenu.cs:249)
UnityEngine.EventSystems.EventSystem:Update () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)

Step through the code and check where it turns null. :wink:

There are other objects in question which may be null too. Such as inventorySlot.image for example.

yeah i dont know i’ve been looking for a while, cannot find the issue at all. thinking about just rewriting the whole thing

This just means you THINK you have done Step #1 but you actually haven’t.

The NullRef is in another Castle, just like the Princess.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that
                itemToRemove = equipmentSlotWeapon.itemEquipped;
<snip>
                equipmentSlotWeapon.itemEquipped.itemSO = null;

You set the itemToRemove reference to point at the same ItemData as equipmentSlotWeapon.itemEquipped. So when you modify equipmentSlotWeapon.itemEquipped.itemSO, it is modifying the thing that itemToRemove is pointing to as well.

2 Likes

i tested it and made modifications, it works now. did not know that it works like this. thank you very much