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!
check if inventoryState is null before using it