Unity:如何处理Prefab实例的唯一事件

时间:2017-10-06 16:04:46

标签: c# user-interface events unity3d

我正在设置一个UI系统来帮助描绘我的播放器广告资源。我创建了一个由UI面板组成的预制件,图标的图像组件和一些文本。

当启用UI或玩家的广告资源发生变化时,我使用UI_InventoryManager类重新绘制插槽。但是,插槽还有一个Button组件,我想用它来进行事件处理。

到目前为止,这是我的设置:

  • InventoryManager检测到更改 - >重绘UI以包含新插槽。
  • 点击任何广告位时 - >发信号通知InfoPanel管理员使用点击的插槽项信息更新和重绘信息面板。

这是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是一个问题 - 共享资源。

0 个答案:

没有答案