본문 바로가기

언리얼게임프로젝트/RGP Tutorial

2. Hardware Reference vs Software Reference

BP_ThirdPersonCharacter를 우클릭하고 SizeMap을 선택하면 사이즈를 볼수 있다 211MB가 된다.

컨텐츠폴더에 우클릭을 하고 액터를 부모로 블루프린트를 하나만들고 저장하자.

우클릭후 SizeMap을 클릭하면 사이즈를 볼수 있다.

 

블루프린트를 열어 간단힌 노드를 추가하자 단순히

저장하고 컨텐츠폴더에서 다시한번 SaveAll을 하자. 그래야 아이콘의 별표가 사라지고 메모리상의 변경이 저장된다.

다시 우클릭 SizeMap을 선택하면 하드웨어 레퍼런스값이 211MB가 되었다. 헉

Cast는 클래스의 구조를 알기위해 BP_ThirdPersonCharacter를 로드하고 관련 클래스를 전부 로드하기 때문이다.

하드웨어레퍼런스 문제를 만드는 예는  참조하는 경우에도 발생한다.

부모 액터를 상속해서 차일드 액터에 메시를 추가한 경우에도 부모의 메시들이 불필요하게 로딩된다.

하드웨어 레퍼런스는

오브젝트에 쉽게 접근하고 항상 로딩되어 있는 장점이 있지만, 불필요한 메모리 소모와 로딩시간을 길게합니다.

사실 플레이어 캐릭터는 어차피 항상 로딩되어 있어야 하므로 그렇게 문제되지는 않으나

아래와 같이 레퍼런스를 많이 사용하는 블루프린트는 최악입니다.

 

C++에서도 다음과 같이 액터를 참조할때 하드레퍼런스를 만듭니다.

하드레퍼런스에 반대되는 Soft Reference라는 개념도 있습니다.

C++에서 포인터를 사용하거나

블루프린트에서는 SoftObjectReference를 사용하면 됩니다.

이 경우 에셋이 로딩되지 않으므로 수동으로 로딩시켜줘야 합니다.

 

이렇게 하면 하드레퍼런싱을 안하므로 액터의 크기가 작아집니다.

소프트리퍼런스는 필요할때만 에셋이 로드되지만, 코드가 복잡해지고 타이밍컨트롤이 어렵고 주요한 에셋에는 부적합합니다.

 

 

 

TObjectPtr에 대한 설명

TObjectPtr는 언리얼 엔진 5에서 도입된 새로운 포인터 타입으로, UObject 포인터를 안전하게 관리하기 위해 사용됩니다. 기존의 원시 포인터(UObject*)와 달리, TObjectPtr은 포인터가 유효한지(댕글링 포인터가 아닌지)를 더 쉽게 확인할 수 있도록 설계되었습니다. 하지만 언리얼의 가비지 컬렉터에 의해 관리되는 방식에서는 큰 차이가 없습니다.

TObjectPtr는 자체적으로 참조 카운팅을 하지 않기 때문에, 강참조(Strong Reference)로 간주되지 않으며, 이는 기존 원시 포인터와 비슷하게 단순히 객체를 참조하는 역할을 합니다. 그러나, 이를 통해 가비지 컬렉터가 해당 포인터를 추적하는 데 도움을 주는 역할은 합니다.

TSoftObjectPtr와 TWeakObjectPtr의 차이점

  • TSoftObjectPtr: 이 포인터는 리소스의 경로 정보를 저장하고, 실제 객체는 로드되지 않은 상태에서도 포인터를 유지합니다. 경로 정보를 사용하여 필요할 때 객체를 로드할 수 있습니다. 관련된 상세 내용은 아래 링크를 참조하세요:
  • TWeakObjectPtr: 이 포인터는 객체의 소유권을 가지지 않으며, 참조하고 있는 UObject가 가비지 컬렉션에 의해 삭제되는 경우, 해당 포인터는 nullptr로 설정됩니다. 따라서 객체가 유효한지 체크할 때 유용합니다. 관련된 유사한 설명은 아래 링크를 참조하세요:

종합 설명

결론적으로, TObjectPtr는 강참조와 관련이 없으며, 단순히 포인터의 유효성을 좀 더 명확하게 관리하기 위한 도구입니다. 강참조와 약참조 사이의 ‘중간 참조’처럼 애매한 개념은 아니며, 강의에서 이 부분이 혼란스러웠다면 객체 관리 방식에 따라 다르게 사용하시는 것이 중요합니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

 

TObjectPtr (강한 참조) 액터가 로딩될 때 액터의 멤버변수로 TObjectPtr 이 있다면 같이 로딩된다. 유니티에서 인스펙터에 다른 프리팹의 레퍼런스가 있다면 같이 메모리에 로딩되는 것과 같은 구조다. TSoftObjectPtr (느슨한 참조) 액터가 로딩되어도 직접 로드하기 전까지는 메모리에 로딩하지 않는다. 유니티에서 어드레서블 레퍼런스만 물려있다면 직접 로딩할 때 메모리에 올리는 것과 같은 구조이다. TObjectPtr은 내부에 있는 객체를 바로 접근가능했지만 소프트 레퍼런스인 TSoftObjectPtr은 객체가 로딩 되었는지 안되었는지 알 수 없기 때문에 IsPending() 으로 확인하고, LoadSynchronous() 로 로딩하고, Get() 으로 가져와야한다. if (WeaponItemData->WeaponMesh.IsPending()) { WeaponItemData->WeaponMesh.LoadSynchronous(); } Weapon->SetSkeletalMesh(WeaponItemData->WeaponMesh.Get()); TWeakObjectPtr (약한 참조) C++의 스마트 포인터에서도 있었던 Weak 참조이다. 객체의 수명에 영향을 주지 않아 순환 참조 문제를 해결하기 위해 만들어졌다. 하위 오브젝트로 다른 액터를 참조하는 경우 해당 액터들이 삭제되어도 참조 때문에 메모리에서 내리지 않는 문제가 있는데 WeakObjectPtr은 수명에 영향을 주지 않아 메모리에서 해제가 가능하다. IsValid() 로 확인하고 Get()으로 사용한다. if (MyTestClassRef.IsValid()) { MyTestClass* ValidItemBox = MyTestClassRef.Get(); }