목차
3D 방치형 RPG Idle Adventure 3일차
for 반복문과 람다식에서 발생하는 IndexOutOfRangeException
for 루프를 사용하여 동적으로 게임 오브젝트를 생성하고, 각 오브젝트의 이벤트에 람다식을 통해 인덱스를 전달하는 과정에서 IndexOutOfRangeException이 발생했다.
private void Start()
{
for(int i = 0; i < slots.Length; i++)
{
GameObject newSlot = Instantiate(slotPrefab, transform);
slots[i] = newSlot.GetComponent<ConsumableSlot>();
slots[i].slotButton.onClick.AddListener(slots[i].OnButtonClicked);
slots[i].OnItemUsed += () => UseItem(i); //이부분
slots[i].SetItem(null);
}
}
UseItem 함수가 slots 배열의 범위를 벗어난 인덱스로 호출된 것이다.
for 루프 내에서 i값을 바로 람다식으로 넘겨주려고 했다.
루프가 돌때마다 증가하는 i를 UseItem에 전달하려는 것이었다.
private void Start()
{
for(int i = 0; i < slots.Length; i++)
{
GameObject newSlot = Instantiate(slotPrefab, transform);
slots[i] = newSlot.GetComponent<ConsumableSlot>();
slots[i].slotButton.onClick.AddListener(slots[i].OnButtonClicked);
int index = i;
slots[index].OnItemUsed += () => UseItem(index);
slots[index].SetItem(null);
}
}
정말로 단순하게 i를 새로운 변수에 넣어 초기화하는 것으로 해결할 수 있었다.
이렇게 하면 매번 초기화 되는 변수 index를 참조하게 된다.
위 상황은 클로저 현상 때문이었다.
클로저 (Closure) 현상
람다식이나 익명 함수가 자신이 선언된 외부 환경의 변수를 참조(Capture)하고, 그 참조를 기억하는 연상을 말한다.
문제의 경우, for 루프 안에서 람다식이 i 변수를 캡쳐할때, i의 값이 아닌 i라는 변수 자체에 대한 참조를 캡쳐하게 된다.
루프는 매우 빠르게 종료되고, i의 값은 최종적으로 3이 된다.
이후 버튼이 클릭되는 시점에 람다식은 캡처했던 변수 i의 최종 값인 3을 사용하게 되면서 에러가 발생한다.
해결 방법의 원리는 int index = i의 코드는 i의 현재 값을 index라는 새로운 변수에 값으로 복사하고, 이는 for 루프의 반복마다 새로운 변수로 간주된다.
따라서 람다식이 index를 캡쳐하면, 각 람다식은 고유한 0, 1, 2 값을 안전하게 가지게 된다.
for 루프 내에서 람다식, 델리게이트, 또는 이벤트에 루프 변수를 사용할 때는 클로저 현상을 항상 인지해야함을 배웠다.
루프 변수의 현재 값을 람다식에 전달하려면, 반드시 루프 내부에 별도의 로컬 변수를 선언하여 값을 복사하는 습관이 있어야겠다.
이 원칙은 C#의 다른 비동기 코드나 이벤트 기반 프로그래밍에서도 아주 중요한 설계 원칙이라고 한다.
느낀점
오늘은 마음이 급해서 이거하려다가 저거하려다가 헛짓거리를 많이 해서 많이 못했다.
내일 제출 4시까지일줄 알았는데 1시까지였다!
일단 지금 몸 상태가 안좋아서 일찍 들어가고, 내일 아침 일찍 일어나서 진행해야할 것 같다.
내일 학습 할 것은 무엇인지
장비아이템이.. 어디서부터 시작해야할지 모르겠네.
일단은 상점에서 구매하고 장착하는 것부터 하자.
'부트캠프 > 본캠프' 카테고리의 다른 글
| [내일배움캠프_2025SEP01] Cooking Knight 1일차 (0) | 2025.09.01 |
|---|---|
| [내일배움캠프_2025AUG29] Idle Adventure 제출, 구조에 대한 아이디어 (0) | 2025.08.29 |
| [내일배움캠프_2025AUG27] 3D 방치형 RPG Idle Adventure 2일차 (0) | 2025.08.27 |
| [내일배움캠프_2025AUG26] 3D 방치형 RPG Idle Adventure 1일차 + 팀의 위기.. (0) | 2025.08.26 |
| [내일배움캠프_2025AUG25] 유니티 심화 주차 팀 편성 및 프로젝트 준비 (0) | 2025.08.25 |