C#/게임 제작 + TIL
Dotween OnComplete() - 람다에서 루프 변수 참조시 변수 값 캐싱
Toa_
2025. 4. 8. 15:26
오늘은 Dotween의 OnComplete()을 사용하던 중 발생한 버그와 이를 해결하며 배운 올바른 활용 법이다.
for(int i = 0; i < cardsInHand.Count; i++)
{
// 각도 설정
float angle = 0f;
angle = (oddeven * -2.5f) + (i * 2.5f);
cardsInHand[i].GetComponent<RectTransform>().DORotate(new Vector3(0, 0, angle), 0.5f).SetEase(Ease.OutSine);
// 카드의 좌표 설정
Vector2 targetPos = new Vector2(0, 0);
int distance = Mathf.Abs(i - oddeven);
targetPos.x =(oddeven * -100) + (i * 100);
targetPos.y = (- yOffset * distance * (distance + 1) / 2f) - cardMidPosY;
cardsInHand[i].GetComponent<RectTransform>()
.DOAnchorPos(targetPos, 0.5f)
.SetEase(Ease.OutSine)
.OnComplete(() => cardsInHand[i].SetOriginalPos());
}
위와 같이 For 문에서 루프 변수 i를 OnComplete에서 사용하려 했다.
그러나 실제로는 해당 방식을 사용하면 루프 안의 OnComplete에 있는 모든 람다들은 마지막 i 값을 참조하여 작동한다.
따라서 만약 For 문에서 루프 변수를 사용해서 OnComplete 등의 람다를 사용할때는 계속 변하는 루프 변수가 아닌, 루프변수를 한번 캐싱하여 사용해 주는 것이 좋다.
for(int i = 0; i < cardsInHand.Count; i++)
{
int cash = i;// 카드의 인덱스를 캐싱해서 OnComplete에서 사용
// 각도 설정
float angle = 0f;
angle = (oddeven * -2.5f) + (i * 2.5f);
cardsInHand[i].GetComponent<RectTransform>().DORotate(new Vector3(0, 0, angle), 0.5f).SetEase(Ease.OutSine);
// 카드의 좌표 설정
Vector2 targetPos = new Vector2(0, 0);
int distance = Mathf.Abs(i - oddeven);
targetPos.x =(oddeven * -100) + (i * 100);
targetPos.y = (- yOffset * distance * (distance + 1) / 2f) - cardMidPosY;
cardsInHand[i].GetComponent<RectTransform>()
.DOAnchorPos(targetPos, 0.5f)
.SetEase(Ease.OutSine)
.OnComplete(() => cardsInHand[cash].SetOriginalPos());
}
이처럼 i 를 한번 int cash로 받아주어 사용하니 정상적으로 작동하였다.