UI Button добавление событий через скрипт
Всем добрый день! Создаю игру на Unity, в ней есть окно с номерами уровней. Проблема в том, что при нажатии на кнопку определённого уровня открывается не выбранный уровень, а уровень с последним значением итерируемой переменной i. Заранее спасибо
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
public class LevelButtonController : MonoBehaviour
{
private int _levelToLoad;
public int _LevelToLoad
{
get
{
return _levelToLoad;
}
set
{
_levelToLoad = value < 1 ? 1 : value;
}
}
void Start()
{
_LevelToLoad = PlayerPrefs.GetInt("NextLevel");
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetComponent<Button>().interactable = i < _levelToLoad ? true : false;
transform.GetChild(i).GetComponent<Button>().onClick.AddListener(delegate { PrintButtonNumber(i); });
transform.GetChild(i).GetComponent<Button>().onClick.Invoke();
}
//PlayerPrefs.DeleteAll();
}
void PrintButtonNumber(int i)
{
Debug.Log(i);
}
}
Ответы (1 шт):
Ты передаешь i как параметр, а в конце итерации и на момент нажатия на кнопку она равна transform.childCount
Решить можно через локальный параметр
for (int i = 0; i < transform.childCount; i++)
{
...
int p = i;
transform.GetChild(i).GetComponent<Button>()
.onClick.AddListener(()=> { PrintButtonNumber(p); });
...
}
The following rules apply to variable scope in lambda expressions:
A variable that is captured will not be garbage-collected until the delegate that references it becomes eligible for garbage collection.
Это значит что делегат будет ссылаться на i, а она будет существовать, пока существует делегат. Так как это ссылка, то любые изменения i до вызова делегата повлияют на его результат.
В то время как int p создается заново каждую итерацию и не может быть изменен.
И еще одно onClick устарел: https://docs.unity3d.com/ScriptReference/UIElements.Button-onClick.html