对象被破坏但仍在尝试访问

问题描述 投票:0回答:1

我遵循了教程(https://youtube.com/playlist?list=PLcRSafycjWFegXSGBBf4fqIKWkHDw_G8D&si=DVRPU6bpo64DfPlN)并出现了此错误。

'MissingReferenceException:'UnityEngine.UI.Image'类型的对象已被销毁,但您仍在尝试访问它。 您的脚本应该检查它是否为空,或者您不应该销毁该对象。 UnityEngine.Object+MarshalledUnityObject.ThrowNullExceptionObjectImpl(System.Object obj)(位于:0) UnityEngine.Component.get_gameObject ()(位于:0) Inventory.UI.InventoryItemUI.ResetData ()(位于 Assets/Scripts/UI/InventoryItemUI.cs:42) Inventory.UI.inventoryMainPage.ResetAllItems ()(位于 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)(位于 Assets/Scripts/UI/Item Scripts/SO/InventorySO.cs:49) Inventory.Model.InventorySO.AddItem(Inventory.Model.InventoryItem 项)(位于 Assets/Scripts/UI/Item Scripts/SO/InventorySO.cs:131) Inventory.InventoryController.PrepareInventoryData ()(位于 Assets/Scripts/UI/InventoryController.cs:37) Inventory.InventoryController.Awake ()(位于 Assets/Scripts/UI/InventoryController.cs:25)'

库存在每个场景上都工作正常,但一旦我尝试在它们之间切换,就会出现此错误,并且不确定如何修复。

这是我的库存控制器脚本

    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);
            }
        }
    }

这是我的 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);
    }

这是我的 inventoryMainPage 脚本

    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();
    }
}

这是我的库存SO 脚本

 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();
 }

我评论了这个

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

错误消失了,我可以在每个场景中看到库存,但库存中的对象不会随之转移。感谢任何帮助!

c# unity-game-engine unityscript inventory
1个回答
0
投票

使用前检查 inventoryState 是否为 null

© www.soinside.com 2019 - 2024. All rights reserved.