Develog
OnDisable( )의 발동 시점 본문

1. OnDisable( )
OnDisable( ) 메서드는 객체가 파괴(Destroy)되거나, 비활성화(SetActive(false))되는 상황처럼 대상이 '사라질 때' 발동되는 이벤트 메서드입니다.
이 때문에 OnDisable( )은 객체가 사라지면서 가지고 있던 참조나 변수 값들을 '정리'하기 위해 주로 사용됩니다.
이벤트 리스너를 삭제하거나, 변경되었던 변수의 값들을 초기화하는 것이 대표적입니다.
그렇다면 OnDisable( ) 메서드가 호출되는 시점을 어떻게 이해해야 할까요?
2. OnDisable( )이 발동되는 시점
아래와 같이 싱글턴 타입의 클래스를 간단히 생성하고, OnDisable( )을 다른 클래스에서 호출합니다.
public class GameControlApplicationQuitChecker : GameControlSingleton<GameControlApplicationQuitChecker> {
public bool IsQuit { get; private set; }
public void OnApplicationQuit() {
IsQuit = true;
}
}
public class VehicleTrainInvestigationBehaviour : MonoBehaviour {
private void OnDisable() {
#if UNITY_EDITOR
if (!Application.isPlaying) {
return;
}
#endif
if (GameControlApplicationQuitChecker.Instance.IsQuit) {
return;
}
...
}
...
위 코드는 '간헐적'으로 Null 참조 오류가 발생합니다.
OnApplicationQuit( ) 이벤트 메서드는 플레이모드가 종료되기 직전, 즉 게임이 종료되기 직전에 호출됩니다.
하지만 OnDisable( )은 오브젝트가 파괴 또는 비활성화될 때 호출됩니다.
그러므로 만약 싱글턴 클래스로 선언된 GameControlApplicationQuitChecker 오브젝트가 먼저 파괴되었다면 싱글턴 인스턴스 참조는 Null이 되어버립니다.
또한 이는 확정적으로 벌어지는 순서가 아니기 때문에 '간헐적'이라는 끔찍한 수식어까지 붙게 됩니다.
3. 해결법
해결법은 간단합니다.
public class VehicleTrainInvestigationBehaviour : MonoBehaviour {
private bool isQuit;
private void OnApplicationQuit() {
this.isQuit = true;
}
private void OnDisable() {
#if UNITY_EDITOR
if (!Application.isPlaying) {
return;
}
#endif
if (this.isQuit) {
return;
}
...
}
...
위와 같이 VehicleTrainInvestigationBehaviour 클래스 내부에서 직접 애플리케이션 종료를 검사하는 메서드를 추가하면 됩니다.
이는 자기 클래스 내부 필드는 삭제 순서가 동일하므로 문제가 발생하지 않기 때문입니다.
또는 IsQuit 변수를 클래스 차원에서 취급하여 파괴 순서와 무관한 정적(Static) 변수로 선언하는 것도 하나의 방법이 될 수 있습니다.
수고하셨습니다!
'Technology > Unity' 카테고리의 다른 글
| 겹쳐진 UI 오브젝트, 게임 오브젝트가 동시에 클릭될 경우 (0) | 2024.12.21 |
|---|---|
| C# EventHandler 중복 호출 방지법 (0) | 2024.10.22 |
| 움직임(물리)을 구현하자 (0) | 2024.10.15 |
| Unity Event vs Delegate Event (0) | 2024.10.06 |
| SerializeField 속성과 변수 초기화, Null 참조 에러 (0) | 2024.07.28 |