我正在设置一个UI系统来帮助描绘我的播放器广告资源。我创建了一个由UI面板组成的预制件,图标的图像组件和一些文本。
当启用UI或玩家的广告资源发生变化时,我使用UI_InventoryManager类重新绘制插槽。但是,插槽还有一个Button组件,我想用它来进行事件处理。
到目前为止,这是我的设置:
这是UI_InventoryManager中的RedrawUI函数 - 此函数在视觉上正常工作。它使用预期的项填充UI。请忽略它的低效率,我只想让整体互动先行:
private void RedrawUI()
{
// The ItemSlot prefab to be added to the grid layout.
Transform slot;
// The item information we are appending to the slot.
InventoryItem itemInfo;
// Image representing item icon. Acquired from InventoryItem metadata.
Image itemIcon;
// Text UI to display the item name. Acquired from InventoryItem metadata.
Text itemName;
// Text UI to display the item stack count. Acquired from the InventorySlot object in PlayerInventory class.
Text itemCount;
ClearUI();
foreach(KeyValuePair<int, InventorySlot> item in playerInventory.Inventory)
{
// Places the Slot UI prefab inside the Group Box for proper layout.
slot = (GameObject.Instantiate(inventorySlotPrefab, itemGroupBox.transform));
// Attach an InventoryItem component that will hold the information of the item.
itemInfo = slot.gameObject.AddComponent<InventoryItem>();
// Use the ItemFactory to abstract the initialization of the item.
itemInfo.InitInventoryItem(item.Key);
itemIcon = slot.transform.GetChild(0).GetComponent<Image>();
itemName = itemIcon.transform.GetChild(0).GetComponent<Text>();
itemCount = itemIcon.transform.GetChild(1).GetComponent<Text>();
itemIcon.sprite = itemInfo.ItemIcon;
itemName.text = itemInfo.ItemName;
itemCount.text = item.Value.Amount.ToString();
// Get the Button script from the instance of the prefab.
// Handle the button click of each UI slot via the UpdateGUI function of the InfoPanelManager.
Button button = slot.GetComponent<Button>();
button.onClick.AddListener(() => { itemInfoPanel.UpdateGUI(itemInfo); });
}
}
这里的主要焦点是最后一行 - 我被告知你是如何订阅的 - 或者为一个事件添加一个监听器。在这种情况下按钮单击。 ItemInfoPanel管理器按如下方式处理UpdateGUI函数:
/// <summary>
/// Update GUI:
/// Triggered when an Item Slot from the UI_Inventory Manager gets selected.
/// Redraws the Info panel and populates it with information from the newly selected item.
/// </summary>
public void UpdateGUI(InventoryItem _inventoryItem)
{
Debug.Log("Entered UpdateGUI");
// Set the passed item to be our currently selected item.
_selectedItem = _inventoryItem;
if (_inventoryItem != null)
{
itemIconSlot.sprite = _inventoryItem.ItemIcon;
itemName.text = _inventoryItem.ItemName;
itemDescription.text = _inventoryItem.ItemDescription;
if (ItemFactory.IsPlaceableItem(_inventoryItem.GetItemID()))
{
placeButton.enabled = true;
}
else
{
placeButton.enabled = false;
}
}
}
结果:
点击事件适用于我选择广告资源中任何项目的第一个项目。但是,当我再次单击或单击任何不同的项目插槽时 - 不会调用UpdateGUI函数。我把Debug.Log放在检查中;它永远不会在那里。在设置此邮件系统时我忽略了什么?
我最初认为预制件的所有实例都可以“共享”事件处理代码。也许当我为一个实例设置它时,它会为所有其他实例设置它。也就是说,事件对于每个槽都不是唯一的。我无法确认。我尝试使用以下方法,希望是这样的:
// Places the Slot UI prefab inside the Group Box for proper layout.
slot = (GameObject.Instantiate(inventorySlotPrefab, itemGroupBox.transform));
UnityEditor.PrefabUtility.DisconnectPrefabInstance(slot);
这没有任何效果 - 我现在有点无能为力,有什么提示吗?
修改 经过进一步检查,我注意到信息面板上显示的项目描述无论如何都是错误的。它似乎显示添加到库存中的第一个项目的信息。从那里,无论点击哪个插槽,都会显示第一个项目信息。这使我进一步认为使用Prefabs是一个问题 - 共享资源。