1. UnityEngine.Object null 체크란? UnityEngine.Object는 Unity 네이티브 오브젝트와 C# 관리 객체의 상태를 동기화하기 위해 커스텀 null 비교 연산자를 제공합니다. 이는 C#의 기본 null 비교와 다르게, 객체가 Destroy된 상태인지도 확인하는 추가 로직을 포함합니다.

따라서 UnityEngine.Object를 상속받은 객체(TextMeshPro, Transform, GameObject 등)에서 null 비교를 수행할 때, Unity는 내부적으로 추가적인 연산을 실행하여 성능 비용이 증가할 수 있습니다.


2. 성능 비용이 높아지는 이유 Unity의 커스텀 null 연산자(==, !=)는 다음과 같은 작업을 포함합니다:
  • Unity 네이티브 오브젝트 확인: C++ 네이티브 객체와 C# 객체 간 동기화 상태를 점검함.
  • 객체 상태 확인: 객체가 Destroy된 경우에도 null로 간주하는 로직을 포함함.
  • 추가 연산 발생: 단순 참조 비교가 아닌, 내부 상태 점검으로 인해 성능 비용이 증가함.

특히 Update 함수나 빈번히 호출되는 루프에서 null 비교를 반복적으로 수행할 때 주의해야함


3. 최적화 방법 UnityEngine.Object의 null 비교 비용을 줄이기 위해 다음 방법을 사용할 수 있습니다

 

1) Object.ReferenceEquals 사용 (C#)

Unity의 커스텀 null 비교를 우회하고 C#의 기본 null 비교를 강제합니다

if (!Object.ReferenceEquals(skillPointText, null))
{
    skillPointText.text = "스킬포인트: 5";
}

2) Object.IsDestroyed 사용 (Unity 2023.1 이상)

Unity 2023.1 이상에서는 Object.IsDestroyed 메서드를 사용하여 객체가 파괴되었는지 확인할 수 있습니다

if (!Object.IsDestroyed(skillPointText))
{
    skillPointText.text = "스킬포인트: 5";
}

3) 명시적 UnityEngine.Object null 비교

UnityEngine.Object로 캐스팅하여 명시적으로 null 비교를 수행합니다

if (skillPointText != (UnityEngine.Object)null)
{
    skillPointText.text = "스킬포인트: 5";
}

 

버전이 높으면 1,2번을 사용하여 성능을 개선할 수 있다.

 

하지만 버전이 낮으면 C#객체는 개선이 가능하지만 유니티 객체는 개선은 불가하다.

 

하지만 3번처럼 명시적으로 다른 개발자들에게 이건 유니티 엔진 객체입니다 ! 이렇게 알려주는 방법도 좋은 방법이다.

 

요즘엔 유니티 엔진 객체는 (skillPointText) 혹은 (!skillPointText) 이렇게 사용하는 경우가 보이는 것 같다.

 

아래는 C# 객체와 UnityEngine.Object를 함께 검사하는 예제

2022.3.17 버전 기준

using TMPro;
using UnityEngine;

public class SkillPointManager : MonoBehaviour
{
    public TextMeshProUGUI skillPointText;
    public object generalObject;

    void UpdateSkillPoints(int points)
    {
        // C# 일반 객체 검사
        if (!Object.ReferenceEquals(generalObject, null))
        {
            Debug.Log("C# 일반 객체가 유효합니다.");
        }
        else
        {
            Debug.LogWarning("C# 일반 객체가 null입니다.");
        }

        // UnityEngine.Object 검사
        if (skillPointText != (UnityEngine.Object)null)
        {
            skillPointText.text = $"스킬포인트: {points}";
        }
        else
        {
            Debug.LogWarning("UnityEngine.Object가 null이거나 Destroy된 상태입니다.");
        }
    }
}

 

이 코드는 C# 객체와 UnityEngine.Object를 각각 검사하여 두 가지 경우를 모두 처리함


요약

  • UnityEngine.Object는 기본 C# 객체와 다르게 커스텀 null 비교를 수행하며, 추가적인 상태 점검 로직으로 인해 성능 비용이 발생함.
  • 빈번한 null 체크가 필요할 경우 Object.ReferenceEquals를 사용하여 C# 객체를 검사하고, UnityEngine.Object는 명시적으로 캐스팅하여 검사하는 것이 적합함.
  • Unity 버전에 따라 적합한 방법을 선택하여 성능과 안정성을 확보할 수 있도록 주의해야 함!