我遵循了教程(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);
}
错误消失了,我可以在每个场景中看到库存,但库存中的对象不会随之转移。感谢任何帮助!
使用前检查 inventoryState 是否为 null