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 버전에 따라 적합한 방법을 선택하여 성능과 안정성을 확보할 수 있도록 주의해야 함!