배경
언리얼 엔진에서 C++로 로직을 짤 때 포인터 검사는 필수다.
단순히 if (Pointer)로 Null 체크만 하다가 게임이 크래시(튕김) 나는 경우를 겪었는데, 언리얼 엔진의 가비지 컬렉터(GC) 환경에서는 일반적인 C++ 포인터 검사와는 다른 접근이 필요하다는 것을 알게 되었다.
배운 내용
1. 단순 Null 체크 if (Pointer)의 한계와 사용처
일반적인 C++에서 사용하는 방식이지만, 언리얼에서는 '댕글링 포인터(Dangling Pointer)' 버그를 유발할 수 있다.
어떤 액터가 파괴되어 가비지 컬렉터에 의해 삭제 예정(Pending Kill) 상태가 되더라도, 메모리 주소 자체는 남아있어 if (Pointer)를 통과해버리기 때문이다.
- 언제 써야 할까? (최적화)
- 캐릭터의 기본 메쉬(Mesh)나 캡슐 컴포넌트처럼 액터와 생명주기(Lifecycle)를 완벽하게 함께하는 핵심 컴포넌트일 때.
- 중간에 파괴될 일이 없으므로, 무거운 검사 대신 단순 Null 체크만 하는 것이 성능상 유리하다.
// 내 캐릭터의 기본 메쉬는 도중에 삭제될 일이 없으므로 단순 Null 체크로 충분하다.
if (GetMesh())
{
// 로직 실행
}
2. 언리얼 엔진의 철벽 방어 IsValid()
IsValid()는 언리얼 엔진이 제공하는 강력한 유효성 검사 함수다.
이 함수는 포인터가 nullptr인지 확인하는 것뿐만 아니라, 엔진에 의해 삭제 대기(Pending Kill) 중인 쓰레기 데이터인지까지 이중으로 검사해 준다.
- 언제 써야 할까? (안전성)
- 내가 생성하지 않은 남의 액터 (예: 타겟 몬스터)
- 게임 도중 생성되거나 파괴될 수 있는 동적 객체 (예: 스왑 가능한 무기, 투사체 등)
- GAS(Gameplay Ability System)처럼 비동기 대기(Wait)가 발생하여 그 사이 객체가 파괴될 위험이 있는 경우.
// 공격 도중 무기가 파괴되었을 수도 있으므로 반드시 IsValid로 검사!
if (!IsValid(CachedWeaponMesh))
{
return; // 조기 종료 (Guard Clause) 패턴 적용
}
3. 모던 C++17의 '초기화 구문 포함 if문'
언리얼 엔진 5부터 지원하는 최신 C++17 문법을 활용하면, 변수의 스코프(Scope) 통제와 유효성 검사를 단 한 줄로 아름답게 처리할 수 있다.
if문 안에서 세미콜론(;)을 기준으로 [변수 생성]과 [조건 평가]를 분리한다.- 변수가
if문 블록{ }안에서만 살아있고 끝나면 즉시 소멸하므로, 메모리 오염이나 휴먼 에러를 시스템적으로 원천 차단할 수 있다.
// 1. 변수를 만들고 (할당) ; 2. IsValid로 유효성을 평가한다.
if (AActor* TargetMonster = GetTarget(); IsValid(TargetMonster))
{
// 이 괄호 안에서 TargetMonster는 무적이며 완벽하게 안전하다!
TargetMonster->TakeDamage(10.f);
}
// 괄호를 빠져나오는 순간 TargetMonster 포인터 변수는 증발한다.
🎯 요약 및 결론 (Summary)
- 내 몸의 일부 (생명주기 동일) 👉
if (Pointer) - 남의 것, 뗐다 붙였다 하는 것 👉
IsValid(Pointer) - 안전성과 가독성을 동시에 잡고 싶을 때 👉
if (Type* Var = ... ; IsValid(Var))+ 조기 종료(return) 패턴 적극 활용!
'프로그래밍 > Unreal Engine 5' 카테고리의 다른 글
| [Unreal Engine 5] Module과 Plugin의 차이점 (0) | 2026.04.02 |
|---|---|
| [Unreal Engine 5] 싱글플레이어 vs 멀티플레이어(DedServer) GAS 아키텍처의 결정적 차이 (0) | 2026.03.30 |
| [Unreal Engine5] 멀티플레이 최적화 Relevancy, NetPriority, NetDormancy의 이해 (0) | 2026.03.25 |
| [UnrealEngine 5] 멀티플레이 최적화 : NetUpdateFrequency와 클라이언트 보간 (0) | 2026.03.24 |
| [Unreal Engine] 프로퍼티 레플리케이션 심화: NetLoadOnClient와 RepNotify(OnRep) 이해 (0) | 2026.03.23 |