본문 바로가기
Unity 끄적임

fake null 관련한 이야기

by Dev_Cat 2024. 6. 14.
728x90
반응형

이 이야기에 앞서 c++를 조금 하셨던 분들이라면 댕글링 포인터에 대해 들어봤을 겁니다.

댕글링 포인터란 포인터가 해제된 메모리 영역을 가키고 있는걸 의미한다.

 

그렇다면 unity에서 fake null은 뭐냐? 말 그대로 실제로는 null인데 unity에서 null이 아니에요. 라고 하고 있는 상황입니다.

Unity에서 모든 GameObject들은 UnityEngine.Object를 상속 받는다.

 

UnityEngine.Object란 엔진 내부는 c++이기에 c++ 객체인 native object객체애 대한 포인터를 지니고 있는 한번 감싸진 (저는 이걸 wrapper class라고 부름) 클래스다. (아래 이미지로 생각하면 됩니다.)

UnityEngine.Object와 NativeObject 관계

문제는 Destory(gameObject)를 하면 이게 사진에 보이는 nativeObjPtr 해제되는데 문제는 UnityEngine.Object는 wrapper class 인데 gameObject로 c# 객체이기에 해제될 수 없는 상황이 됩니다. 왜냐면 GC만이 C# 객체를 해제할 수 있음

그래서 이런 상황을 fake null인 상황입니다.


gameObject == null 이게 값이 비싼 이유는 아래 코드처럼 대충 처보고 ==에 f12눌러서 가보면 내부 구현을 볼 수 있다.

1) Native Object가 null인지 체크함.

2) UnityEngine.Object는 System.Object를 상속받아 이걸 다시 업 캐스팅해서 System.Object가 null인지 체크해 fake null 상태로 만든다.

딱 봐도 난 한번 null 체크인데 내부적으론 2번 일어남. (component == null 도 비슷하게 비쌈)

void CheckGameObject(GameObject gameObject)
{
    if(gameObject == null)
        return;
    Debug.Log("null이 아니네");
}

 

 


협업에서 인스펙터에 미리 바인딩 되어야 할 GameObject에 대해서도 null체크를 하는 경우가 많다.

 

나는 이런 경우엔 null 체크는 안하는게 맞다고 생각한다.
왜냐 null이 아니어야 하는 상황인데 이를 if문으로 예외처리 해버리면 이슈가 생겼을 때 추적이 어렵기 때문이다.

이럴땐 Assert등으로 알리면 어떨지 이 또한 하나의 코드 습관이 될 수 있지 않을까 생각한다.

 

아래 코드는 예시임. (그냥 어떤 느낌인지 참고만)

public GameObject playerBullet;

public void Shoot()
{
    Log.Assert(playerBullet != null, "playerBullet은 당연히 null이면 안됩니다. null이면 인스펙터 바인딩 안한겁니다");
    
    // 어떤 과정들을 걸치고
    var isReloading = myBulletCount == 0;
    playerBullet.SetActive(isReloading);
}

 

항상 정답은 없기에 그냥 저는 이런 코딩 스타일을 추구하니 여러분 의견은 어떤지 좋은 의견이 있다면 댓글에도 알려주세요. 그러면 다들 즐코!

728x90
반응형

'Unity 끄적임' 카테고리의 다른 글

Array와 List 그리고 IList  (0) 2024.07.20
Unity IL2CPP, JIT, AOT  (0) 2024.05.05
코루틴(Coroutine)  (0) 2023.11.20
[게임수학] 내적, 외적 이야기  (0) 2023.11.17
월드 공간과 UI 공간  (0) 2023.10.17