[Unity] Fake Null

spixychz·2026년 6월 2일

Unity

목록 보기
14/15

C#의 null

MyClass go = new MyClass();

go = null;

Debug.log($"A = {go == null}");
Debug.log($"B = {ReferenceEquals(go, null)}");
  • 결과
    • A = true
    • B = true
  • 이후 객체를 참조하는 참조가 없어져 GC 대상이 된다

UnityEngine.Object

  • 상속받은 자식 클래스
    • GameObject
    • Component
    • MonoBehaviour
    • ScriptableObject
    • Texture
    • Material
    • AudioClip
  • C++ Native 객체와 이를 가리키는 C# Wrapper 객체

Destroy가 호출되면 ?

GameObject go = new GameObject();

Destory(go);

Debug.log($"A = {go == null}");
Debug.log($"B = {ReferenceEquals(go, null)}");

yield return null;

Debug.log($"C = {go == null}");
Debug.log($"D = {ReferenceEquals(go, null)}");
  • 결과
    • A = false
    • B = false
    • C = true
    • D = false
  • Destroy는 C++ Native 객체 삭제를 예약하고, 실제 삭제는 해당 프레임이 끝날 때

Fake Null

C++ Native 객체는 삭제되었지만, C# Wrapper 객체는 아직 남아 있는 상태이다. Unity는 UnityEngine.Object의 == 연산자를 오버로딩하여 이를 null로 취급한다.

  • null 은 어떤 객체도 참조하지 않는 실제 C# null
  • Destroy 후에는 "null" 로 보이도록 fake null 처리
  • UnityEngine.Object의 == 연산자 오버로딩
    • C++ Native 객체 제거 후에도 실제 참조는 남아있지만, 이를 null 처럼 취급하도록
    • UnityEngine.Object의 == 연산자는 일반 C# 참조 비교보다 조금 더 비싸다
  • 주의 사항
    • ?? 이나 ?. 연산을 사용할 때 주의가 필요하다

Fake Null이 없었다면 ?

GameObject go = new GameObject();

Destroy(go);

yield return null;

if (go != null)
{
		go.transform.position = Vector3.zero;
}
  • 삭제된 엔진 객체에 접근하게 되므로 MissingReferenceException 발생
  • Unity에서는 이를 방지하기 위해 실제 null이 아니더라도 삭제된 엔진 객체를 null로 취급하는 Fake Null 발동
  • if ((object)go == null)== 연산자 오버로딩 우회 가능
profile
UNITY로 게임 개발하는 사람

0개의 댓글