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.我们可以通过创建变量,让不同的按钮捕捉不同的上下文,或引用不同的变量。
至此:为按钮动态添加点击事件并传递参数就可以通过以上方式实现,大家还有别的好的方法可以留言一起讨论。