게임 개발

LateUpdate가 중요한 이유

백진암 2024. 4. 25. 19:35

Awake 다음에 Start가 호출된다면

Update 다음에는 LateUpdate가 호출된다.

 

LateUpdate와 Update의 차이점은 Update가 호출된 이후에 LateUpdate가 호출된다는 것 밖에 없다.

두 함수 모두 매 프레임 호출되며 순서는 항상 보장된다.


Update가 호출된 후에 호출되는 LateUpdate가 왜 중요한지 완벽하게 대답할 수 있는 사람은 많지 않을 것 같다.

 

이 글에서는 LateUpdate를 언제 그리고 왜 사용하는지 까지 적어보려고 한다.

 

언제 LateUpdae를 사용해야 할까


LateUpdate는 코드 실행을 단계적으로 진행하기 위해 사용된다.

이를 통해 다른 함수의 결과에 의존하는 함수들이 완료된 후에 실행될 수 있다.

 

이 점이 중요하다.

다른 스크립트 및 다른 객체의 Update 함수는 무작위 순서로 호출되기 때문이다.

 

보통 이 점은 문제가 되지 않는다. 

 

하지만 만약 스크립트가 동일한 객체와 상호 작용하거나, 동일한 프레임에서 서로의 데이터에 의존하는 경우, Update에서 두 스크립트를 동시에 실행하면 예측할 수 없는 동작이 발생하게 된다

 

간단한 예시를 보자.

각 블록은 색을 바꾸려는 두개의 스크립트를 자식으로 가지고 있다.

여러개의 칸이 있고 각 칸은 두개의 자식 오브젝트를 가지고 있다.

각각 부모의 이미지를 빨간색과 파란색으로 바꾸는 코드를 가지고 있다고 하자.

public class TurnRed : MonoBehaviour
{
    public Image image;
    bool isChanged;

    void Update()
    {
        if (!isChanged)
        {
            isChanged = true;
            image.color = Color.red;
        }
    }
}

(파랑도 동일)

 

만약 TurnRed 스크립트가 늦게 실행되면 빨간색으로 TurnBlue 스크립트가 늦게 실행되면 파란색으로 바뀔 것이다. 

 

실행 결과는 이렇다.

각 블록에서 두 Update가 경쟁을 하고 있어 각 블록을 빨간색 또는 파란색으로 변경하려 하고 있다.

이 순서는 랜덤은 아니지만, 각 스크립트가 동일한 시간에 색을 변경하려고 하기 때문에 예측할 수 없는 결과를 보여주는 것이다.

 

이로 인해 각 스크립트의 성공이 실행 순서에 따라 결정되는 상황이 만들어지며, 이는 신뢰할 수 없는 결과로 이어진다.

 

이를 해결하려면 LateUpdate를 사용하면 된다.

 

public class TurnRed : MonoBehaviour
{
    public Image image;
    bool isChanged;

    void LateUpdate()
    {
        if (!isChanged)
        {
            isChanged = true;
            image.color = Color.red;
        }
    }
}

 

모든 칸을 빨간색으로 만들고 싶다면 TurnRed의 Update를 LateUpdate로 바꿔주기만 하면 된다.

TurnRed를 LateUpdate로 바꾸면 TurnBlue보다 늦게 실행되므로 모든 블록이 빨간색이 된다.

그러면 또 언제 LateUpdate를 사용해야 할까?

 

그리고 왜 중요할까?

 

 

LateUpdate를 왜 사용해야 할까?


많은 프로젝트에서 물체를 따라가는 카메라에 LateUpdate를 적용시킨다.

따라가려는 오브젝트의 Update에서 매번 바뀌는 위치값과 회전값에 따라 카메라의 위치를 바꿔야 하기 때문이다.

 

하지만 카메라 외에도 다양하게 사용될 수 있다.

그중 하나가 게임 로직에 따라 버그를 방지할 수 있다는 점이다.

 

예를 들어, 플레이어가 그리드 위에 물건을 집고 놓을 수 있는 기능이 있다고 하자.

플레이어는 커서로 화분을 집고, 바닥 타일을 눌러 놓을 수 있다.

화분 스크립트에는 화분을 놓읗 수 있는 지 확인하는 로직이, 커서 스크립트에는 마우스 클릭을 기다리는 코드와 설치 가능한 타일일 경우 화분을 설치하는 코드가 담겨있다.

 

만약 두 스크립트가 동시에 Update에서 진행이 된다면 화분을 놓는 기능이 설치 가능한 타일을 체크하는 기능보다 먼저 발생할 수도 있다.

 

그렇게 되면 딱 한 프레임에서 놓을 수 없는 타일에 화분이 놓아지는 상황이 발생할 수도 있다.

확률은 희박하지만, 이런 에러를 발생 시킬 수도 있다.

하지만 Update대신 LateUpdate에 화분을 놓는 코드를 담는다면 에러를 피할 수 있을 것이다.

 

이런 버그가 발생할 가능성이 적어 보이지만, 가능성이 없는 버그는 아니다.

더 나쁜 점은 버그 발생을 예측할 수 없고, 발생했을 때 에러를 확인하기 위해 제현하는데 어려움을 겪을 수 있다.

 

그래서 이러한 버그가 발생할 경우 버그를 찾아 수정하는데 꽤 애를 먹을 수도 있다.

 

 

마치며


Update와 LateUpdate의 기능을 완벽히 숙지하고 있어야 처음 코드를 짤 때부터 로직을 에러없이 구현할 수 있다.

여러 상황에 대입해보면서 익숙해지고 나면 어느 순간부터 자연스레 두 함수를 구분하고 있을 것이라고 생각한다.

참고자료
https://gamedevbeginner.com/how-to-use-late-update-in-unity/
 

How to use Late Update in Unity (and why it’s so useful) - Game Dev Beginner

Learn how to use Late Update in Unity, what it's for, how it works and what could happen if you don't use it, in my in-depth beginner guide.

gamedevbeginner.com

해외 블로그에 너무 좋은 글이 있어서 많은 사람들이 읽었으면 하는 마음으로 번역하며 글을 써봤다.

도움이 됐으면 좋겠다.