✔ 다음 포인터 유형 사용

TSoftObjectPtr : 해당 경로를 통해 로드되거나 로드되지 않을 수 있는 개체를 참조하는데 사용된다.

로드되지 않더라도 다른 레벨에 있는 액터를 가리킬 수 있다. 특별한 목적을 위해서 메시와 같은 애셋을 비동기 로딩하는 함수에서 사용된다. 블루프린트에서의 Soft Object Reference 블루프린트 변수 타입과 같은 역할이다.

 

TSoftClassPtr : 해당 경로를 통해 로드되거나 로드되지 않을 수 있는 클래스를 참조하는데 사용된다.일단 로드되면 사용자는 이것을 이용해 인스턴스를 만들 수 있다. 이것들을 비동기로 로드하는 함수에서 사용된다. 블루프린트에서의 Soft Class Reference 블루프린트 변수 타입과 같은 역할이다.

 

TWeakObjectPtr : 이미 인스턴스화된 객체를 참조하는데 사용된다. 객체가 사라지거나 가비지 컬렉팅되는 경우 Null값을 가지게 된다.

 

❌ 이러한 포인터 유형을 사용하지 마십시오.

  • FSoftObjectPath : 다른 포인터 유형 에서 내부적으로 사용됩니다. 결과를 캐시하지 않기 때문에 느립니다. 에디터에서 설정하면 UBlueprintGeneratedClass 대신 UBlueprint 클래스를 가리킬 것인데, 이는 일반적으로 게임플레이 코드가 원하는 것이 아닙니다. 하지만 Editor Plugins 제작자는 해당 기능을 원할 수 있습니다.
  • FSoftClassPath : FSoftObjectPath와 동일하지만 클래스 로딩과 관련된 일부 도우미 함수가 있습니다. 지금은 대부분 레거시 유형입니다.
  • FSoftObjectPtr : TSoftObjectPtr의 비템플릿 및 비-BP 노출 버전입니다.

 

Weak Pointer vs Soft Pointer

Weak Pointer는 존재하는 UObject를 대상으로 만들어진다. 이 UObject는 GUObjectArray 인덱스에 의해 이미 만들어진 UObject이다. 

Weak Pointer는 가리키는 대상이 가비지 컬렉팅 되었는지 알 필요가 없기 때문에 UPROPERTY로 지정하지 않아도 된다.

 

Soft Pointer는 로드되거나 로드되지 않을 수 있는 객체 또는 애셋에 대한 경로의 문자열 표현입니다. 개체가 쿼리되고 발견된 후 개체를 추적하기 위해 추가 Weak Pointer를 내부에 저장합니다

 

Soft Pointer

FSoftObjectPath

게임플레이 코드용 FSoftObjectPath 변수를 직접 만들지 마세요 . 그들은 확인된 개체를 캐시하지 않으므로 모든 쿼리는 개체를 다시 검색합니다. 또한 생성된 클래스( UBlueprintGeneratedClass , 경로 이름의 " _C ") 대신 블루프린트 클래스 애셋( UBlueprint ) 을 가리킵니다 . UBlueprint는 패키지 빌드에서 제거됩니다. TSoftObjectPtr 또는 TSoftClassPtr 을 사용하십시오 .

 

FSoftObjectPath는 모든 타입의 Soft 포인터에서 내부적으로 사용된다. 소프트 오브젝트 경로 변수는 블루프린트에서 생성할 수 있지만, 수행 중인 작업을 알고 있고 , UBlueprintGeneratedClass 클래스를 가리키고 싶지 않으며 캐싱이 필요하지 않은 에디터 유틸리티에서만 수행해야 한다.

 

블루프린트에서 사용하는 경우 개체 인스턴스가 아닌 디스크 상의 애셋만 선택할 수 있습니다. 인스턴스를 가리키려면  TSoftObjectPtr 을 사용하십시오

 

FSoftObjectPath는 템플릿이 아닙니다. 애셋 유형으로 선택을 제한하려면 MetaClass UProperty 메타데이터를 사용할 수 있습니다 (또는 해당 종류의 기능 대신 TSoftClassPtr 사용).

 

개체를 resolve 할 때 해쉬를 사용해 검색한다. 일반 혹은 WeakPointer에 비해 약간의 오버헤드가 있다. 확장 클래스는 일반적으로 그것들을 캐시하므로 다시 검색할 때 한번 resolve하면 다시 검색하지 않는다.

 

FSoftClassPath

FSoftObjectPath와 거의 동일하지만 로딩 관련 헬퍼 함수를 갖고 있다. 대부분 오래된 시스템이기 때문에 직접 만들어 샤용하는 대신에 TSoftClassPtr을 사용하자

 

FSoftObjectPtr

소프트 개체 및 클래스 포인터의 기본 클래스입니다. 내부적으로 오브젝트를 찾기 위한 FSoftObjectPath 와 찾은 후 캐싱하기 위한 FWeakObjectPtr을 유지합니다.

많은 기능이 있는 TPersistentObjectPtr을 확장합니다 .

USTRUCT가 아니므로 블루프린트에서는 사용할 수 없으며 C++에서만 사용할 수 있습니다.

TSoftObjectPtr 또는 TSoftClassPtr 의 두 가지 확장 유형이 있습니다 . 이 유형은 각각 개체 인스턴스 또는 애셋(CDO)을 가리키는 템플릿, 블루프린트에 Visible 되는 방식을 제공합니다. 이것들이 대신 사용되어야 한다.

Get()을 호출하면 기본 클래스에서 호출하여 내부 WeakPtr이 이전에 캐시되었는지(비 PIE 세션에서) 먼저 확인하고, 그렇지 않으면 FSoftObjectPath.ResolveObject를 호출하여 객체를 찾습니다.

 

TSoftObjectPtr

FSoftObjectPtr의 템플릿화된 Wrapper 이다. 블루프린트에서 사용될 수 있다.

경로 이름이 있는 모든 항목을 가리키는 데 사용할 수 있습니다. 디스크에 있는 애셋이든 레벨에 있는 개체든 로드되지 않을 수 있는 항목을 가리키는 데 가장 적합합니다.

 

액터가 현재 로드되지 않은 다른 레벨에 있어도 경로 값을 유지한다.

 

이미 인스턴스화된 액터를 참조하려면 TSoftObjectPtr 대신 TWeakObjectPtr을 사용하십시오.

기본값은 블루프린트 타입으로 설정할 수 없습니다 (블루프린트 타입을 사용하려면 TSoftClassPtr 사용). 하지만 Data Assets을 가리킬 수 있습니다.

 

이 값은 로드된 액터를 선택하여 인스턴스 Detail 창에서 설정하거나 현재 열려 있는 맵의 액터에 대한 Class Defaults에서 설정할 수 있습니다.

 

가리키는 객체가 로드되지 않았을 때 Get()이 호출되면 nullptr  반환 합니다 . 일단 로드되면 일치하는 전체 이름을 가진 액터를 반환하고 미래의 쿼리를 위해 캐시합니다.

 

TSoftClassPtr

TSubclassOf 처럼 작동하는 FSoftObjectPtr 주변의 템플릿 래퍼로 , 블루프린트 서브클래스용 UProperties 에서 사용할 수 있습니다 .

로드 여부를 쿼리할 수 있는 블루프린트 유형( UBlueprintGeneratedClass ) 을 가리키는 데 사용됩니다 . 클래스를 비동기적으로(또는 동기적으로, 장애가 발생하더라도) 로드하는 데 사용할 수도 있습니다. 

DataAssets는 인스턴스화하면 안 되므로 DataAsset에 대해서는 작동하지 않는다. 이것들에 대해서는 TSoftObjectPtr을 대신 사용해야 한다.

 

WeakPointers

소프트 포인터처럼 경로를 저장하지 않고, 이미 인스턴스화된 개체에 대해서 참조만 한다.

weak pointer는 int32 ObjectIndex와 int32 ObjectSerialNumber 두 값만 저장한다.

 

Get을 호출하면 먼저 ObjectIndex를 사용하여 GUObjectArray 에서 객체를 가져옵니다 (존재하는 경우).

 

"하지만 ObjectIndex는 32비트에 불과합니다. 액터를 계속 생성하고 제거하면 쉽게 숫자가 부족하지 않습니까 ? " 훌륭한 질문입니다. 예, 이론적으로는 그럴 수 있지만 항상 기껏해야 수십만 개의 객체만 살아 있기 때문에 해당 인덱스가 재사용됩니다.

 

그 때문에 인덱스 재사용의 경우 우리가 원하는 개체인지 확인하기 위해 ObjectSerialNumber가 있습니다. ObjectSerialNumber는 Weak 포인터가 UObject 를 처음 가리킬 때만  할당되며 , 그렇지 않으면 0입니다. 스레드 안전 증분 int32 카운터 입니다 .

 

" 일련 번호가 다 떨어지면 어떻게 됩니까? " 그것은 게임에 크래시를 일으킨다.  즉 , 일련 번호가 소진되기 전에 최대 2,147,483,647개의 고유 UObject 에 대한 새로운 약한 포인터를 만들 수 있습니다 . 대부분의 사용 사례에는 충분하지만 매우 오래 실행되는 프로세스 또는 약한 포인터의 이상한 사용을 고려하십시오.

 

일련 번호를 비교한 후 최종적으로 UObject IsValid() 가 아닌지 확인하고 , 그렇지 않으면( PendingKill 의 경우 ) null 을 반환하고 , 그렇지 않으면 객체를 반환합니다. 이 때문에 약한 포인터를 역참조하면 항상 유효한 UObject 또는 그렇지 않은 경우 nullptr이 반환된다는 것을 확신할 수 있습니다 .

 

모든 델리게이트는 AddUObject / BindUObject 함수를 사용할 때 Weak Pointer를 통해 UObject 에 대한 참조를 유지하므로 파괴 중 구독 취소에 대한 걱정 없이 델리게이트를 안전하게 구독할 수 있습니다. 이는 관리되지 않는 C++ 포인터를 사용하는 AddRaw / BindRaw 함수를 사용하는 것과는 반대이므로 UObject 를 다룰 때 이를 신중하게 다루고 전혀 사용하지 않으려고 합니다 . 

UObject가 아닌 C++ 클래스의 멤버함수를 등록하는 경우에는 AddRaw / BindRaw 사용

 

요약

요약하자면, 약한 포인터는 역참조할 때 약간의 오버헤드가 있는 UObject를 가리키는 훌륭하고 안전한 방법입니다 . 결국 그렇게 약하지 않습니다! UObject 가져오기 및 유효성 검사의 모든 내부를 처리하기 때문에 UPROPERTY 일 필요도 없습니다 

 

FWeakObjectPtr

메모리의 UObject에 대한 약한 포인터입니다. USTRUCT가 아니므 로 블루프린트에서 사용할 수 없습니다. C++에서만 가능합니다. 

TWeakObjectPtr 의 Base 클래스입니다 .

 

TWeakObjectPtr

일반 FWeakObjectPtr 의 템플릿 버전입니다. 블루프린트에서 사용할 수 있지만 C++에서 선언해야 합니다.

개체의 문자열 표현을 내부적으로 사용하지 않더라도 인스턴스 Detail 창(Class Defaults 말고) 에서 값을 설정할 수 있습니다 .

 

문자열 경로를 사용하지 않기 때문에 애셋을 찾는 오버헤드를 건너뛰지만 이미 인스턴스화된 개체로만 설정할 수 있습니다. 

 

C++에서는 인스턴스화된 UObject 가 어느 레벨에 있든 상관없이 이미 로드되어 있는 한 가리킬 수 있습니다 .

 

 

https://dev.epicgames.com/community/learning/tutorials/kx/all-about-soft-and-weak-pointers

 

 

All about Soft and Weak pointers | Tutorial

A deep dive into the different soft and weak pointer types in Unreal Engine.

dev.epicgames.com

 

 

+ Recent posts