1.unit3d给按钮添加函数一般有两方式:

①直接在Button按钮下面添加函数;

②直接代码添加点击事件,如下:

btn.onClick.AddListener(A);

void A(){

}

void B(int index){

}

2.通过以上案例,对于不带参数的A函数可以直接添加,但是函数B是不能直接被添加的,可以通过委托Delegate进行添加

//btn.onClick.AddListener(A);
//为按钮添加带参函数B
btn.onClick.AddListener(delegate { B(Index); })
void A(){
}

void B(int index){
}

3.好多时候我们需要批量给B函数传递参数,如下:

void Function(){
    for (int i = 0; i < 3; i++)
    {
        Button btn = Instantiate(buttonCD, P);
        btn.onClick.AddListener(delegate { B(i); });
    }
}
void B(int index) {
        Debug.Log(index);
}

//打印结果
3,3,3

通过上面的函数运行后我们会惊奇的发现,没有我们预期的结果打印出0,1,2而是打印出了3,3,3

4.通过上面的打印会很惊奇,为什么不是我们预期的结果0,1,2 ????

------------------------------------------------------ 分割线 ---------------------------------------------------------------

5.通过查询资料,发现C#中,当使用匿名委托时,会捕捉本地调用方法的完整上下文,原因是:

匿名委托在创建时会自动捕获其外部作用域中的变量,这样做的目的是为了确保在委托执行时,可以访问到委托创建时的上下文状态:

匿名委托捕获本地调用方法的完整上下文有以下几个原因:

①.闭包行为:匿名委托实际上是一个闭包,它可以访问其创建时所在作用域中的变量。为了实现这种闭包行为,编译器会将这些变量的引用保存在委托对象中,以便在委托执行时可以访问它们。

②.数据共享:通过捕捉本地调用方法的完整上下文,匿名委托可以共享和修改其外部作用域中的变量。这使得在异步编程和多线程编程中能够方便地共享数据状态。

③.灵活性和方便性:通过捕捉本地调用方法的完整上下文,匿名委托可以轻松地访问并使用其外部作用域中的变量,无需显式传递参数。

6.知道了原因,那么我们应该怎样改进上面代码才能达到我们想要的结果,如下:

void Function()
    {
        for (int i = 0; i < 3; i++)
        {
            int Index = new();
            Index = i;
            Button btn = Instantiate(buttonCD, P);
            btn.onClick.AddListener(delegate { B(Index); });
        }
    }
    void B(int index)
    {
        Debug.Log(index);
    }
    //打印结果 0,1,2

 7.我们可以通过创建变量,让不同的按钮捕捉不同的上下文,或引用不同的变量。

至此:为按钮动态添加点击事件并传递参数就可以通过以上方式实现,大家还有别的好的方法可以留言一起讨论。