【问题标题】:Problem with foreach loop giving values to a button in Unityforeach 循环给 Unity 中的按钮赋值的问题
【发布时间】:2019-09-06 05:12:30
【问题描述】:

我正在尝试在 Unity 中为我的游戏制作类似 Candy Crush 的地图,我正在尝试将所有按钮收集到一个数组中,然后设置其 onclick 属性,这样当我单击它们时,我就会到达关卡我想。我正在使用 Foreach 循环来实现它。

问题在于,在每个按钮上,我都会加载相同的场景。它确实列出了我从 1 到 N 的级别,但 onclick 似乎无法正常工作!我试过用 for 循环代替 foreach 但它也不起作用。

int i = 0;
        foreach(GameObject level in levels)
        {
            level.GetComponent<Button>().onClick.AddListener(() => SceneManager.LoadScene(i + 1));
            i++;
        }

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    您已经在循环变量上创建了一个闭包。一个常见的陷阱,当然。 StackOverflow 上已经存在suitable explanation and remedy for this kind of problem

    当您使用符号i 时,它本质上是对存在于循环之外的唯一i 的引用。在调用任何侦听器时,它的值将是它在循环结束时的值,在您的情况下,它将是您拥有的 levels 的数量。

    为避免这种情况,您需要使用i,而不是对变量的引用。您可以通过创建一个新变量来做到这一点,该变量的范围对循环的一次迭代是唯一的,并传入该新变量的值。基本上你需要的是i副本

    必要改变的本质是:

    int i = 0;
    foreach(GameObject level in levels)
    {
        int copy_of_i = i;
        level.GetComponent<Button>().onClick.AddListener(() => SceneManager.LoadScene(copy_of_i + 1));
        i++;
    }
    

    【讨论】:

      【解决方案2】:

      我认为问题在于 lambda 表达式: () => SceneManager.LoadScene(i + 1)

      你不是 i 的值,而是变量 i,它将再次递增 在其他迭代上,所以当你点击它时 SceneManager.LoadScene(i + 1);被叫了,但我现在是 25 岁或任何你的级别号码。

      在它之前直接创建一个临时变量,以便每个 lambda 表达式都有自己的变量 int tmp = 我; level.GetComponent().onClick.AddListener(() =>SceneManager.LoadScene(tmp + 1));

      【讨论】:

        猜你喜欢
        • 2015-09-25
        • 1970-01-01
        • 2013-09-17
        • 1970-01-01
        • 2018-05-02
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多