获取对动态实例化按钮的 OnClick 从统一检查器执行的函数的引用

Get reference to a function to execute from the unity inspector for OnClick of a dynamically instantiated Button

我想知道如何通过统一检查器在任何其他脚本上获取对特定函数的引用,以便将其添加到动态实例化按钮的单击侦听器中。我尝试了 public UnityEvent 来获取对函数的引用(就像在静态按钮的点击中一样)但我不确定如何将它添加到点击监听器(button.onClick.AddListener(函数名称))作为一个听众寻找一个动作。 有什么我想念的吗?或者还有其他方法吗? 谢谢。 这就是想法 -

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class DynamicButton : MonoBehaviour
{
    public Button MainButton;
    public GameObject ButtonPrefab;

    [System.Serializable]
    public class ButtonInfo
    {
        public Sprite sprite;
        public UnityEvent ButtonEvent; //take reference to a particular function
    }
    public ButtonInfo[] ButtonCount;

    void Start()
    {
        PlaceButtons();

    }

    void PlaceButtons()
    {

        int NoButton = ButtonCount.Length;

        for (int i = 0; i < NoButton; i++)
        {           
            Vector3 newPos = new Vector3(i*10, i*10,0);   
            GameObject go = Instantiate(ButtonPrefab, newPos, Quaternion.identity);
            go.GetComponent<Image>().sprite = ButtonCount2To6[i].sprite;
            go.GetComponent<Button>().onClick.AddListener();  //This is where I want to add the  particular function that i want to execute when the button is clicked
            go.transform.parent = MainButton.transform;
            go.transform.localPosition = newPos;
        }
    }
}

您要做的是 Invoke 事件,而不是将其添加到 onClick 事件。您不必找出/复制每个 UnityEvent 的侦听器,而是调用 UnityEvent 就足够了。 UnityEvent 然后调用您分配的所有听众,例如在检查器中。这可以通过一个简单的 lambda 函数来完成:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class DynamicButton : MonoBehaviour
{
    public Button MainButton;
    public GameObject ButtonPrefab;

    [Serializable]
    public class ButtonInfo
    {
        public Sprite sprite;
        public UnityEvent ButtonEvent; //take reference to a particular function
    }

    public ButtonInfo[] ButtonCount;

    private void Start()
    {
        PlaceButtons();
    }

    private void PlaceButtons()
    {
        int NoButton = ButtonCount.Length;

        for (int i = 0; i < NoButton; i++)
        {           
            Vector3 newPos = new Vector3(i*10, i*10, 0);   
            GameObject go = Instantiate(ButtonPrefab, newPos, Quaternion.identity);

            // What is ButtonCount2To6?? It probably should rather be ButtonCount[i] ?
            go.GetComponent<Image>().sprite = ButtonCount2To6[i].sprite; 


            // since the lambda will have no acces to i you have to get the reference to the according ButtonInfo first
            var accordingButtonInfo = ButtonCount[i];

            // Add the Invoke call as lambda method to the buttons
            go.GetComponent<Button>().onClick.AddListener(() => {
                accordingButtonInfo .ButtonEvent.Invoke();
            });  

            go.transform.parent = MainButton.transform;
            go.transform.localPosition = newPos;
        }
    }
}

另见 this post