본문 바로가기
유니티/기초

유니티 DontDestroyOnLoad

by 노튜 2025. 2. 13.
728x90
반응형
반응형

1. Scene

유니티는 Scene의 단위로 화면 전환이 이루어진다. Scene의 전환이 발생하여 Scene이 소멸하게 되면 Scene에 존재하는 모든 오브젝트는 소멸된다. Scene은 다양한 오브젝트로 구성된다. 이러한 오브젝트 중에서 다음 Scene이 로드되어도 소멸되지 않아야 하는 경우, 프로그래밍되는 경우가 있다. 이때 사용할 수 있는 함수가 유니티의 DontDestroyOnLoad이다.

 

2. DontDestroyOnLoad

DontDestroyOnLoad는 Scene의 전환이 발생하더라도 오브젝트가 소멸되지 않고 유지하도록 하는 함수이다. 유니티 최상위 클래스는 Object이다. DontDestroyOnLoad는 Object 클래스의 함수이다. Object를 상속받은 모든 클래스는 사용이 가능하다. DontDestroyOnLoad의 매개 변수는 Object이다. 

DontDestroyOnLoad(Object target);

DontDestroyOnLoad는 this 키워드(Keyword)와 함께 사용된다. this는 클래스의 현재 인스턴스를 가리키는 키워드이다. 

DontDestroyOnLoad(this);

 

DontDestroyOnLoad를 사용하는 경우 반드시 최상위 게임 오브젝트여야 한다. 다른 게임 오브젝트의 Child로 존재하는 경우에는 해당 게임 오브젝트의 DontDestroyOnLoad는 수행되지 않는다. 아래는 Child 게임 오브젝트에서 DontDestroyOnLoad를 호출하였을 경우에 출력되는 메시지이다. 

// DontDestroyOnLoad only works for root GameObjects or componets on root GameObjects.

 

DontDestroyOnLoad는 유니티의 함수 Awake(), Start()에서 주로 구현한다. 

using UnityEngine;

public class TestDontDestroy : MonoBehaviour
{
  // Awake is called once.
  void Awake()
  {
    DontDestroyOnLoad(this);
  }

  // Start is called before the first frame update 
  void Start()
  {
    // DontDestroyOnLoad(this);
  } 
}

 

728x90

3. Static Member(정적 멤버) 그리고 DontDestroyOnLoad

DontDestroyOnLoad는 정적 멤버와 함께 주로 사용된다. 일반적으로 DontDestoryOnLoad와 함께 A Scene에서 생성된 오브젝트는 B Scene이 있는 오브젝트에서 접근할 수 없다. A Scene에 있던 오브젝트를 B Scene으로 드래그를 하여 연결하기 등의 방법을 사용할 수 없기 때문이다. 클래스에 접근할 수 있도록 클래스가 생성될때 클래스의 정적 멤버를 생성한다.

using UnityEngine;

public class Test : MonoBehaviour
{
  private static Test instance; 
  public static Test Instance{get {return instance;} set {}}
  
  public int testValue = 10;
  // Start is called before the first frame update
  void Start()
  {
    instance = this;
    DontDestroyOnLoad(this);
  {
}

 

using UnityEngine;

public class UseTest : MonoBehaviour
{
  static readonly float timeRate = 1.0f;
  float time;
  
  // Start is called before the first frame update
  void Start()
  {
    time = 0.0f;
  }
 
  // Update is called once per frame
  void Update()
  {  
     time += Time.deltaTime; 
     if(timeRate > time)
     {
       return;
     }
     time = 0.0f;
     Debug.Log("Value:"+ Test.Instance.testValue);
 }
}

 

※ 또 다른 접근 방법으로는 GameObject.Find("")가 있다. 본 글의 작성자는 선호하지 않는 방법이므로 여기에서 자세한 설명은 하지 않는다.

 

4. Scene Lobby 그리고 DontDestroyOnLoad

Scene Lobby는 Splah Image (Logo) 다음에 처음으로 로딩되는 Scene이다. 프로그램은 우선 Scene Lobby가 실행되도록 구현한다. Scene Lobby → Scene Transition, Scene Main, Scene Stage 등을 순차적으로 실행이 되도록 구성한다. Scene Lobby에서 프로그램이 실행되기에 필요한 데이터의 다운로드, 데이터의 준비 등을 하도록 구현한다. 

Scenes in Build

 

Lobby Scene을 만들고, Scene Main, Scene Stage, Scene Level 등을 실행하기 전에  필요한 데이터를 미리 로드한다. 이를 위해 DontDestroyOnLoad를 사용한다.  

 

Lobby GameManager

using UnityEngine;

public class GameManager : MonoBehaviour
{
  public static GameManager Instance;
  
  // Data
  
  // Awake Called once
  void Awake()
  {
   if(Instance != null)
     return;
   
   Instance = this;
   DontDestroyOnLoad(this);
   
   LoadData();
  }
  
  void LoadData()
  {
    // Do something 
  }
}

 

 

reference

[1] DontDestroyOnLoad

https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Object.DontDestroyOnLoad.html

 

Unity - Scripting API: Object.DontDestroyOnLoad

The load of a new Scene destroys all current Scene objects. Call Object.DontDestroyOnLoad to preserve an Object during scene loading. If the target Object is a component or GameObject, Unity also preserves all of the Transform’s children. Object.DontDest

docs.unity3d.com

 

[2] 정적 생성자

https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

 

정적 생성자 - C#

C#의 정적 생성자는 정적 데이터를 초기화하거나 한 번만 수행되는 작업을 수행하며 첫 번째 인스턴스가 만들어지거나 정적 멤버가 참조되기 전에 실행됩니다.

learn.microsoft.com

 

728x90
반응형