필자는 object?.Funtion()문법을 애용한다.
object가 null인지 체크하고, 만약 null이라면 Function()을 실행하지 않아주는, if문을 생략할 수 있는 문법이다.
라고 해서 찾아봤다.
참고로
null propagation은 'null 값을 확인하지 않고도 변수를 안전하게 탐색할 수 있도록 도와주는 기법'이다.
유니티는 학습하기 쉬운 대가로, C# 언어 특징과 덜 일치하게 작동을 한다.
Unity에서 MonoBehaviour나 GameObject에 대해 object == null은 C#의 표준 null 비교가 아니라, Unity에서 오버라이드된 특수 비교 연산을 사용한다. 반면 null propagation 연산자(?.)는 C#의 표준 null 비교 방식만 사용하므로, Unity의 커스텀 동작을 반영하지 못한다..! 출처: Null Propagation Operator and Unity
아래 코드를 예시로 들었는데, Destroy()함수로 삭제를 해줘도 실제 메모리에서는 삭제되지 않았지만, Unity에서의 == 연산자는 이를 고려해서 Destroy() 로 삭제 처리를 했다면 true를 반환하는 것이다! 이토록 놀랍고 아름다운....
public static bool operator ==(Object obj1, Object obj2)
{
// Unity 내부 구현 (간략화)
// C# 레벨에서는 null이 아니더라도,
// Unity 오브젝트가 Destroy되었으면 true를 반환함.
}
GameObject obj = someGameObject;
Destroy(obj);
if (obj == null) // true! (Unity의 operator==가 Destroy 상태도 null로 간주)
?. 연산자를 사용하면, Unity에서 만들어 놓은 == 연산자를 무시하게 되고, C#에서 구현한 == 로직대로 작동을 한다. 즉, Destroy()를 호출해서 삭제된 것 처럼 보이는 오브젝트를 메모리에 있다고 판단하고, 접근한다는 것.
아래는 GPT 피셜이다.
현재(2025년 기준) Unity 측에서는 null propagation(?.) 연산자에 대한 특별한 지원(예: 오버라이딩)을 제공하지 않고 있으며, 앞으로도 공식적으로 지원할 가능성은 낮은 편입니다.
==, != 연산자는 operator overloading이 가능하지만,?. 연산자는 C# 언어 자체에서 컴파일러가 처리하는 기능이라 오버라이딩할 수 없습니다.즉, Unity 입장에서도 ?. 연산자를 가로채거나 커스터마이징할 방법이 없다.
Unity의 GameObject, MonoBehaviour 등은 실제로는:
이 둘이 따로 존재하며, Destroy() 시에는:
이 때문에 Unity는 == null을 오버라이딩해서 Destroy된 객체도 "null처럼" 보이도록 만듦.
하지만 ?. 연산자는 그냥 C# 객체가 null인지만 판단하기 때문에, Unity 구조와 충돌이 난다.
진짜 난 이런게 왜 이렇게 재밌을까..
흥미롭다.. 간단하게 정리하려고 했던건데, 호기심이 그득하여 길이 길어졌지만 유익한 것 같다.
흥미로운 topic이네요