DontDestroyOnLoad와 중복 객체

양규빈·2023년 11월 23일
0

디버깅

목록 보기
3/6

DontDestroyOnLoad란 유니티 엔진에서 제공하는 함수로서, 게임 오브젝트는 씬(Scene) 전환이 발생해도 파괴되지 않고 유지되도록 하는 코드입니다.

이러한 DontDestroyOnLoad가 설정된 오브젝트의 경우, 보통 프로그램 상에서 정적 선언되어, 여러 객체에서 참조하는 객체에 자주 사용됩니다.

다만, DontDestroyOnLoad 로직이 추가된 경우, 씬 전환이 이루어졌음에도 불구하고 자연적으로 객체가 파괴되지 않는다는 문제가 발생하므로,

불필요한 쓰레기 데이터가 쌓이거나, 중복 데이터로 인한 예기치 못한 에러가 발생할 수도 있습니다.

문제 개요

    private static DontDestroyer instance;

    void Awake()
    {
        if (instance != null)
        {
            Destroy(gameObject);
            return;
        }

        instance = this;
        DontDestroyOnLoad(gameObject);
    }

처음에는 static 변수를 이용하여, 중복되는 데이터가 이미 존재한다면 자기자신을 파괴하는, 보호 코드를 이용하여 프로그램을 구현했었습니다만, DontDestroyer 소스를 여러 컴포넌트가 함께 사용하기에 필요한 객체를 중복으로 판단하여 제거해버리는 문제가 발생했습니다.

따라서, 위와 같이 심플한 파괴 보호 코드를 추가한 DontDestroyer 클래스를 컴포넌트로 붙여서, 정적으로 활용되는 객체를 비파괴 설정했었습니다.

상단의 이미지는 던전 씬에 있을 때의 상태입니다.
보다시피 DontDestroyOnLoad 씬에 정상적으로 들어가 있는 것을 확인할 수 있습니다.

이후 던전 씬 → 게임 필드 씬으로 복귀하였을 때,
게임 필드에서 생성하는 각종 매니저들과 캔버스 등이 또다시 부착되는 걸 확인할 수 있습니다.

더군다나 매니저들의 경우에는 싱글턴 패턴을 이용하여, 게임의 흐름을 관리하는 중요한 기능을 담당하기에, 중복 컴포넌트를 허용하면 안 됐습니다.

해결

DontDestroyer 객체 자체를 static으로 저장할 수는 없었기에, List를 활용하여, 비파괴 객체를 관리하는 방법을 생각했습니다.

처음에는 GameObject 객체를 저장하는 리스트를 활용해 비파괴 객체를 관리하는 로직을 구현했지만, 정상적으로 작동하지 않은 것을 확인 했습니다.

게임 플레이 간, 각 객체에 변동점이 생기기 때문으로 추측됩니다.

이에, 각 컴포넌트의 이름을 이용하여, 객체를 구별하고 중복 데이터를 판단하는 쪽으로 방향을 바꾸었습니다.

이렇게 코드를 수정한 결과 문제를 해결할 수 있었습니다.

└던전 진입 전

└던전 진입

└던전 진입 후 복귀
(문제 없음)

profile
훌륭한 개발자를 꿈꾸는 중입니다

0개의 댓글