DontDestroyOnLoad() 사용시 Awake에서 컴포넌트 할당 후 씬을 리로드 했을때의 문제점과 해결방안.

BackgroundMusic 을 담당하는 오브젝트와 SoundManager 가 존재했을때, 

기존에는 둘다 Awake에서 DontDestroyOnLoad(gameObject); 를 이용해서 씬이 변경되거나 리로드 되더라도 파괴되지 않도록 설정했었는데, 게임을 재시작 했을때 현재 리로드 하는 형식으로( 차후에 모든 오브젝트를 풀로 돌리는 형태로 수정할 예정) 구현되어 있어서 리로드시에 BGM 을 처음부터 다시 시작하기 위해서 BackgroundMusic 오브젝트도 파괴되도록 DontDestroyOnLoad() 메서드를 비활성화 해둔 상태이다. 

 

그렇게 하고나니 SoundManager에서 bgMusic이라는 이름으로 Awake 에서 할당한 BackgroundMusic을 씬을 리로드 하고는 찾을 수 없는 상태가 되었다. 

 

그 상황에서의 SoundManager 의 Awake 코드는 아래와 같다. 

 

   private void Awake()
   {
       if (instance != null)
       {
           Destroy(gameObject);
           return;
       }
       instance = this;
       //DontDestroyOnLoad(gameObject);

       soundPool = GetComponent<ObjectPool>();

       bgMusic = GameObject.Find("BackgroundMusic").GetComponent<BackgroundMusic>();
   }

 

이 경우 씬이 재시작 될 시에 생성된 오브젝트는 새로운 오브젝트이고, SoundManager의 Awake에서 할당한 bgMusic의 경우 처음 있던 오브젝트를 나타내는 것으로 보인다. 

 

이와 같은 상황에서의 해결법으로 현재 생각해볼 수 있는 것으로는, 

 

둘다 다시 DondestroyOnLoad 를 사용해서 구현하고, BGM 의 경우 BackgroundMusic 오브젝트의 재생산이 아니라 음악 자체의 재시작으로 구현을 하던지, 

혹은 SoundManager 에서의 DontDestroyOnLoad 도 제거해서 SoundManager 도 씬을 리로드 했을때 다시 Awake 에서 재할당 하는 형식으로 구현하는 것이다. 

 

현재는 다른 로직들을 구현하는게 우선이고 현재 하나의 씬으로 이루어진 단순한 구조의 로직을 가지고 있기 때문에 SoundManager 자체도 DontDestroyOnLoad 를 제거하고 씬을 리로드 할시에 다시 생성되도록 수정하였다. 

 

다음에도 이런 경우에는 DontDestroyOnLoad 의 경우 서로 Awake 에서 할당하는 오브젝트 끼리는 일관성있게 유지하고 

씬을 리로드 할 시에 파괴하고 새로 만드는 것이 아니라 연관되어있는 것들을 초기화 후 재사용 하는 형태로 구현해보도록 하자. 

 

  Comments,     Trackbacks