Object destroyed but still trying to access

127 Views Asked by At

I followed a tutorial (https://youtube.com/playlist?list=PLcRSafycjWFegXSGBBf4fqIKWkHDw_G8D&si=DVRPU6bpo64DfPlN) and this error appeared.

'MissingReferenceException: The object of type 'UnityEngine.UI.Image' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Object+MarshalledUnityObject.ThrowNullExceptionObjectImpl (System.Object obj) (at <f4a03f0013404226841ac46b59a6815d>:0)
    UnityEngine.Component.get_gameObject () (at <f4a03f0013404226841ac46b59a6815d>:0)
    Inventory.UI.InventoryItemUI.ResetData () (at Assets/Scripts/UI/InventoryItemUI.cs:42)
    Inventory.UI.inventoryMainPage.ResetAllItems () (at Assets/Scripts/UI/inventoryMainPage.cs:69)
    Inventory.InventoryController.UpdateInventoryUI (System.Collections.Generic.Dictionary`2[TKey,TValue] inventoryState) (at Assets/Scripts/UI/InventoryController.cs:43)
    Inventory.Model.InventorySO.InformAboutChange () (at Assets/Scripts/UI/Item Scripts/SO/InventorySO.cs:162)
    Inventory.Model.InventorySO.AddItem (Inventory.Model.ItemSO item, System.Int32 quantity, System.Collections.Generic.List`1[T] itemState) (at Assets/Scripts/UI/Item Scripts/SO/InventorySO.cs:49)
    Inventory.Model.InventorySO.AddItem (Inventory.Model.InventoryItem item) (at Assets/Scripts/UI/Item Scripts/SO/InventorySO.cs:131)
    Inventory.InventoryController.PrepareInventoryData () (at Assets/Scripts/UI/InventoryController.cs:37)          
    Inventory.InventoryController.Awake () (at Assets/Scripts/UI/InventoryController.cs:25)'

Inventory works fine on each scene but as soon as I try to switch between them this error appears and unsure how to fix.

this is my inventorycontroller script

    public void Awake()
    {
        PrepareUI();
        PrepareInventoryData();
        inventoryUI.Show();
    }

    private void PrepareInventoryData()
    {
        inventoryData.Initialize();
        inventoryData.OnInventoryUpdated += UpdateInventoryUI;
        foreach (InventoryItem item in initialItems)
        {
            if (item.IsEmpty)
                continue;
            inventoryData.AddItem(item);
        }
    }

    private void UpdateInventoryUI(Dictionary<int, InventoryItem> inventoryState)
    {
        inventoryUI.ResetAllItems();
        foreach (var item in inventoryState)
        {
            inventoryUI.UpdateData(item.Key, item.Value.item.ItemImage, item.Value.quantity);
        }
    }


    private void PrepareUI()
    {
        inventoryUI.InitializeInventoryUI(inventoryData.Size);
        inventoryUI.OnDescriptionRequest += HandleDescriptionRequest;
        inventoryUI.OnSwapItems += HandleSwapItems;
        inventoryUI.OnStartDragging += HandleDragging;
        inventoryUI.OnItemActionRequested += HandleItemActionRequired;
    }

    private void HandleItemActionRequired(int itemIndex)
    {
        InventoryItem inventoryItem = inventoryData.GetItemAt(itemIndex);
        if (inventoryItem.IsEmpty)
            return;

        IItemAction itemAction = inventoryItem.item as IItemAction;
        if (itemAction != null)
        {
      
            inventoryUI.ShowItemAction(itemIndex);
            inventoryUI.AddAction(itemAction.ActionName, () => PerformAction(itemIndex));
        }

        IDestroyableItem destroyableItem = inventoryItem.item as IDestroyableItem;
        if (destroyableItem != null)
        {
            inventoryUI.AddAction("Drop", () => DropItem(itemIndex, inventoryItem.quantity));
        }

    }

    private void DropItem(int itemIndex, int quantity)
    {
        inventoryData.RemoveItem(itemIndex, quantity);
        inventoryUI.ResetSelection();
    }

    public void PerformAction(int itemIndex)
    {
        InventoryItem inventoryItem = inventoryData.GetItemAt(itemIndex);
        if (inventoryItem.IsEmpty)
            return;

        IDestroyableItem destroyableItem = inventoryItem.item as IDestroyableItem;
        if (destroyableItem != null)
        {
            inventoryData.RemoveItem(itemIndex, 1);
        }

        IItemAction itemAction = inventoryItem.item as IItemAction;
        if (itemAction != null)
        {
            itemAction.PerformAction(gameObject, inventoryItem.itemState);
            if (inventoryData.GetItemAt(itemIndex).IsEmpty)
                inventoryUI.ResetSelection();
        }
    }

    private void HandleDragging(int itemIndex)
    {
        InventoryItem inventoryItem = inventoryData.GetItemAt(itemIndex);
        if (inventoryItem.IsEmpty)
            return;
        inventoryUI.CreatedDraggedItem(inventoryItem.item.ItemImage, inventoryItem.quantity);
    }

    private void HandleSwapItems(int itemIndex1, int itemIndex2)
    {
        inventoryData.SwapItems(itemIndex1, itemIndex2);
    }

    private void HandleDescriptionRequest(int itemIndex)
    {
        InventoryItem inventoryItem = inventoryData.GetItemAt(itemIndex);
        if (inventoryItem.IsEmpty)
        {
            inventoryUI.ResetSelection();
            return;
        }
        ItemSO item = inventoryItem.item;
        string description = PrepareDescription(inventoryItem);
        inventoryUI.UpdateDescription(itemIndex, item.ItemImage, item.Name, description);
    }

    public string PrepareDescription(InventoryItem inventoryItem)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append(inventoryItem.item.Description);
        sb.AppendLine();
        for (int i = 0; i < inventoryItem.itemState.Count; i++)
        {
            sb.Append($"{inventoryItem.itemState[i].itemparameter.ParameterName} " + $": {inventoryItem.itemState[i].value} / {inventoryItem.item.DefaultParametersList[i].value}");
        }
        return sb.ToString();
    }

    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.I))
        {
            if (inventoryUI.isActiveAndEnabled == false)
            {
                inventoryUI.Show();
                foreach (var item in inventoryData.GetCurrentInventoryState())
                {
                    inventoryUI.UpdateData(item.Key, item.Value.item.ItemImage, item.Value.quantity);
                }
                eventHandler.InventoryChangeState.Invoke(true);
            }
            else
            {

                inventoryUI.Hide();
                eventHandler.InventoryChangeState.Invoke(false);
            }
        }
    }

this is my inventoryItemUIscript

private bool empty = true;


    public void Awake()
    {
        ResetData();
        Deselect();
    }

   public void ResetData()
   {
       itemImage.gameObject.SetActive(false);
       empty = true;
   }

   public void Deselect()
   {
       borderImage.enabled = false;
   }

   public void SetData(Sprite sprite, int quantity)
   {
       itemImage.gameObject.SetActive(true);
       itemImage.sprite = sprite;
       quantityTxt.text = quantity + "";
       empty = false;
   }

    public void Select()
    {
        borderImage.enabled = true;
    }

    // https://youtu.be/geq7lQSBDAE?si=nyx-AL0fl1oXcjaf
    public InventoryItemUI(ItemSO item)
    {
        AddToStack();
    }

    public InventoryItemUI()
    {
        item = null;
        quantity = 0;
    }

    public void AddToStack()
    {
        quantity++;
    }

    public void RemoveFromStack()
    {
        quantity--;
    }

    public void OnPointerClick(PointerEventData pointerData)
    {
        if (pointerData.button == PointerEventData.InputButton.Right)
        {
            OnRightMouseBtnClick?.Invoke(this);
        }
        else
        {
            OnItemClicked?.Invoke(this);
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (empty)
            return;
        OnItemBeginDrag?.Invoke(this);
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        OnItemEndDrag?.Invoke(this);
    }

    public void OnDrag(PointerEventData eventData)
    {

    }

    void IDropHandler.OnDrop(PointerEventData eventData)
    {
        OnItemDropped?.Invoke(this);
    }

this is my inventoryMainPage script

    private void Awake()
    {
        Hide();
        mouseFollow.Toggle(false);
        itemDescription.ResetDescription();
    }

    public void InitializeInventoryUI(int inventorySize)
    {
        for (int i = 0; i < inventorySize; i++)
        {
            InventoryItemUI UIItem = Instantiate(itemPrefab, Vector3.zero, Quaternion.identity);
            UIItem.transform.SetParent(contentPanel);
            listOfUiItems.Add(UIItem);

            UIItem.OnItemClicked += HandleItemSelection;
            UIItem.OnItemBeginDrag += HandleBeginDrag;
            UIItem.OnItemDropped += HandleSwap;
            UIItem.OnItemEndDrag += HandleEndDrad;
            UIItem.OnRightMouseBtnClick += HandleShowItemActions;
        }
    }

    internal void ResetAllItems()
    {
        foreach (var item in listOfUiItems)
        {
            item.ResetData();
            item.Deselect();
        }
    }

    internal void UpdateDescription(int itemIndex, Sprite itemImage, string name, string description)
    {
        itemDescription.SetDescription(itemImage, name, description);
        DeselectAllItems();
        listOfUiItems[itemIndex].Select();
    }

    public void UpdateData(int itemIndex, Sprite itemImage, int itemQuantity)
    {
        if (listOfUiItems.Count > itemIndex)
        {
            listOfUiItems[itemIndex].SetData(itemImage, itemQuantity);
        }
    }

    private void HandleShowItemActions(InventoryItemUI inventoryItemUI)
    {
        int index = listOfUiItems.IndexOf(inventoryItemUI);
        if (index == -1)
        {
            return;
        }
        OnItemActionRequested?.Invoke(index);
    }

    private void HandleEndDrad(InventoryItemUI inventoryItemUI)
    {
        ResetDraggedItem();
    }

    private void HandleSwap(InventoryItemUI inventoryItemUI)
    {
        int index = listOfUiItems.IndexOf(inventoryItemUI);
        if (index == -1)
        {
            return;
        }
        OnSwapItems?.Invoke(currentlyDraggedItemIndex, index);
    }

    private void ResetDraggedItem()
    {
        mouseFollow.Toggle(false);
        currentlyDraggedItemIndex = -1;
    }

    private void HandleBeginDrag(InventoryItemUI inventoryItemUI)
    {
        int index = listOfUiItems.IndexOf(inventoryItemUI);
        if (index == -1)
            return;
        currentlyDraggedItemIndex = index;

        OnStartDragging?.Invoke(index);

    }
    public void CreatedDraggedItem(Sprite sprite, int quantity)
    {
        mouseFollow.Toggle(true);
        mouseFollow.SetData(sprite, quantity);
    }

    private void HandleItemSelection(InventoryItemUI inventoryItemUI)
    {
        int index = listOfUiItems.IndexOf(inventoryItemUI);
        if (index == -1)
            return;
        OnDescriptionRequest?.Invoke(index);
    }

    public void Show()
    {
        gameObject.SetActive(true);
        ResetSelection();
    }

    public void ResetSelection()
    {
        itemDescription.ResetDescription();
        DeselectAllItems();
    }

    public void AddAction (string actionName, Action performAction)
    {
        itemAction.AddButton(actionName, performAction);
    }

    public void ShowItemAction(int itemIndex)
    {
        itemAction.Toggle(true);
        itemAction.transform.position = listOfUiItems[itemIndex].transform.position; 
    }

    private void DeselectAllItems()
    {
        foreach (InventoryItemUI item in listOfUiItems)
        {
            item.Deselect();
        }
        itemAction.Toggle(false);
    }

    public void Hide()
    {
        itemAction.Toggle(false);
        gameObject.SetActive(false);
        ResetDraggedItem();
    }
}

this is my inventorySO script

 private int currentlyDraggedItemIndex = 1;
 private InventoryItemUI inventoryItemUI;

 public event Action<int> OnDescriptionRequest, OnItemActionRequested, OnStartDragging;

 public event Action<int, int> OnSwapItems;

 [SerializeField]
 public ItemAction itemAction;

 private void Awake()
 {
     Hide();
     mouseFollow.Toggle(false);
     itemDescription.ResetDescription();
 }

 public void InitializeInventoryUI(int inventorySize)
 {
     for (int i = 0; i < inventorySize; i++)
     {
         InventoryItemUI UIItem = Instantiate(itemPrefab, Vector3.zero, Quaternion.identity);
         UIItem.transform.SetParent(contentPanel);
         listOfUiItems.Add(UIItem);

         UIItem.OnItemClicked += HandleItemSelection;
         UIItem.OnItemBeginDrag += HandleBeginDrag;
         UIItem.OnItemDropped += HandleSwap;
         UIItem.OnItemEndDrag += HandleEndDrad;
         UIItem.OnRightMouseBtnClick += HandleShowItemActions;
     }
 }

 internal void ResetAllItems()
 {
     foreach (var item in listOfUiItems)
     {
         item.ResetData();
         item.Deselect();
     }
 }

 internal void UpdateDescription(int itemIndex, Sprite itemImage, string name, string description)
 {
     itemDescription.SetDescription(itemImage, name, description);
     DeselectAllItems();
     listOfUiItems[itemIndex].Select();
 }

 public void UpdateData(int itemIndex, Sprite itemImage, int itemQuantity)
 {
     if (listOfUiItems.Count > itemIndex)
     {
         listOfUiItems[itemIndex].SetData(itemImage, itemQuantity);
     }
 }

 private void HandleShowItemActions(InventoryItemUI inventoryItemUI)
 {
     int index = listOfUiItems.IndexOf(inventoryItemUI);
     if (index == -1)
     {
         return;
     }
     OnItemActionRequested?.Invoke(index);
 }

 private void HandleEndDrad(InventoryItemUI inventoryItemUI)
 {
     ResetDraggedItem();
 }

 private void HandleSwap(InventoryItemUI inventoryItemUI)
 {
     int index = listOfUiItems.IndexOf(inventoryItemUI);
     if (index == -1)
     {
         return;
     }
     OnSwapItems?.Invoke(currentlyDraggedItemIndex, index);
 }

 private void ResetDraggedItem()
 {
     mouseFollow.Toggle(false);
     currentlyDraggedItemIndex = -1;
 }

 private void HandleBeginDrag(InventoryItemUI inventoryItemUI)
 {
     int index = listOfUiItems.IndexOf(inventoryItemUI);
     if (index == -1)
         return;
     currentlyDraggedItemIndex = index;

     OnStartDragging?.Invoke(index);

 }
 public void CreatedDraggedItem(Sprite sprite, int quantity)
 {
     mouseFollow.Toggle(true);
     mouseFollow.SetData(sprite, quantity);
 }

 private void HandleItemSelection(InventoryItemUI inventoryItemUI)
 {
     int index = listOfUiItems.IndexOf(inventoryItemUI);
     if (index == -1)
         return;
     OnDescriptionRequest?.Invoke(index);
 }

 public void Show()
 {
     gameObject.SetActive(true);
     ResetSelection();
 }

 public void ResetSelection()
 {
     itemDescription.ResetDescription();
     DeselectAllItems();
 }

 public void AddAction (string actionName, Action performAction)
 {
     itemAction.AddButton(actionName, performAction);
 }

 public void ShowItemAction(int itemIndex)
 {
     itemAction.Toggle(true);
     itemAction.transform.position = listOfUiItems[itemIndex].transform.position; 
 }

 private void DeselectAllItems()
 {
     foreach (InventoryItemUI item in listOfUiItems)
     {
         item.Deselect();
     }
     itemAction.Toggle(false);
 }

 public void Hide()
 {
     itemAction.Toggle(false);
     gameObject.SetActive(false);
     ResetDraggedItem();
 }

I commented this out

        foreach (InventoryItem item in initialItems)
        {
            if (item.IsEmpty)
                continue;
            inventoryData.AddItem(item);
        }
    

and error disappeared and i could see inventory in each scene when going between then but objects in inventory do not transfer with it. any help is appreciated!

2

There are 2 best solutions below

1
robotrage On

check if inventoryState is null before using it

0
Raheel Zahid On

This error is referring to reference of GO from scene when switching back to that scene from another. Reference is lost as Object is destroyed with the scene .Reassign values after loading scene again GO are assigned ids when referred from scene, when a scene unloaded they are not there anymore. On Reload GOs have new ids so you are getting this reference error