본문 바로가기

프로그래밍/Unreal

[UE4] C++ 에셋, 오브젝트 레퍼런싱/객체생성

UObject 생성

액터의 경우 스폰을 통해 생성됨

T* UWorld::SpawnActor( 
    FVector const& Location,
    FRotator const& Rotation,
    const FActorSpawnParameters& SpawnParameters
)

 

UClass

LoadClass<T>(NULL, TEXT("Game/....", NULL, LOAD_None, NULL);

 

UObject

// NewObject 메쏘드를 통해 생성.
template<class T>
T* NewObject(
    UObject* Outer = (UObject*)GetTransientPackage(),
    UClass* Class = T::StaticClass()
)

// NewNamedObject : deprecated 4.8
// ConstructObject : deprecated 4.8

 

에셋 PATH

에셋 위치

예를 들어 실제 에셋의 물리적 위치가 아래에 있고, 엔진상에서 해당 에셋에 접근해야 하는 상황을 예를 들어보면,
ProjectRoot/Content/Character/MyCharacter.uasset

위 MyCharacter.uasset 에 접근하기 위한 path 규칙은 아래와 같은 형태이다.

Description'LongPackageName.AssetName'
// 디스크립션'패키지명.에셋명

 

디스크립션

해당 에셋의 형식을 나타내는 문자열로 asset의 종류를 나타낸다

Texture2D'
StaticMesh'
Class'
WidgetBlueprint'
    .
    .
    .

 

LongPackageName

확장자인 .uasset을 제외한 게임 경로상의 이름으로 논리적 path 이다.
단 앞의 /Game/ 은 실제 /Content/ path를 의미한다.

즉 위 MyCharacter.uasset의 패키지명은 아래와 같음

/Game/Character/MyCharacter

 

Asset Name

에셋파일의 오브젝트로 컨텐츠 브라우저에서 표시되어지는 이름
일반적으로 에셋 파일명과 같으나 서로 다를 수 있음

MyCharacter

결국, 물리적 path와 엔진에서 사용하는 레퍼런스 path 형식은 아래처럼 표현된다.

물리적 path : ProjectRoot/Content/Character/MyCharacter.uasset
ref path : Description'/Game/Character/MyCharacter.MyCharacter'

 

만약 위의 MyCharacter 에셋이 블루프린트 클래스인 경우에는 다른 오브젝트와 구분하기 위해 에셋명에 _C 가 붙는다.

Class'/Game/Character/MyCharacter.MyCharacter\_C

 

 

 

레퍼런스 생성

물리적 path를 알지 못하는 경우 이미 존재하는 오브젝트로 부터 path 를 얻을 수 있다.

static FORCEINLINE FName GetObjetPath( const UObject* obj)
{
    if(!obj)
    {
        return NAME_None;
    }

    FStringAssetReference AssetRef = FStringAssetReferece(obj);
    // FSoftObjectPath &AssetRef = FStringAssetReferece(obj);

    if( !AssetRef.IsValid() ) {
        return NAME_None;
    }

    FString str = obj->GetClass()->GetDescription();
    str += "'";
    str += AssetRef.ToString();
    str += "'";

    return FName(*str);
}

 

에셋 로딩

생성자에서 로드

등록된 에셋을 static하게 가져오기 위해서는 ConstructorHelpers 클래스를 사용한다.

이름부터가 생성자 도우미????? -_-;;

메모리에서 에셋을 찾고 없으면 path에서 얻어온다. 해당 에셋이 경로에 없으면 nullptr 로 설정.
해당 함수들은 생성자에서만 사용할 수 있다.

ConstructHelpers::FObjectFinder
ConstructHelpers::FClassFinder

런타임 직접 로드

UObject* StaticLoadObject( 
    UClass* Class,
    UObject* InOuter,
    const TCHAR* Name,
    const TCHAR* FileName,
    uint32 LoadFlags,
    UPackageMap* Sandbox,
    bool bAllowObjectRecociliation
)

UObject* LoadObjectFromPath(const FName& path)
{
    if( path == NAME_None) return NULL;
        return Cast<UObject>(StaticLoadObject( UObject::StaticClass(), NULL, *path.ToString());
    }
    LoadObject<T>(NULL, TEXT("Game/....", NULL, LOAD_None, NULL);
}

 

이미 로드된 오브젝트 검색

UObject::FindObject : 이미 로드된 오브젝트 찾기

 

프로퍼티 레퍼런싱

FSoftObjectPath(4.17 -> FStringAssetReference) : 애셋의 참조 정보와 생성 메쏘드들을 포함
애셋의 전체 이름이 들어있는 단순한 구조체로 에디터에는 UObject처럼 표시됨.

TSoftObjectPtr (4.17 -> TAssePtr ) : FSoftObjectPath 의 약한 참조 포인터,
블루프린트에서 에셋의 soft reference로 표시

// .h
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TSoftObjectPtr<UStaticMesh> MyMesh;
// TAssetPtr<UStaticMesh> MyMesh;


// .cpp
if( MyMesh.IsPending() )
{
    const FSoftObjectPath& AssetRef = MyMesh.ToStringReference();
    //const FStringAssetReference& AssetRef = MyMesh.ToStringReference();
    MyMesh = Cast<UStaticMesh>(Streamable.SynchronousLoad(AssetRef));
    UStaticMesh* mesh = MyMesh.Get();
}

서브오브젝트(콤포넌트)

서브 오브젝트를 생성하고 난뒤 서브 오브젝트 목록은 아래 메쏘드를 사용해 얻을 수 있다.

TArray<UObject*> ObjectArray;
GetDefaultSubObjects(ObjectArray);

 

FActorRange

에디터에서 사용되는 기본 오브젝트인 액터들만 얻을 경우 조금더 간편하게 목록을 얻어올 수 있는데, FActorRange 클래스를 사용한다.

UWorld* world = GetWorld();
FActorRange range(world);
for( const auto& actor : range ) {

}

 

이터레이터

액터의 종류나 수가 많은 경우 TActorIterator 에 타입을 지정해 필요한 액터만 얻을 수도 있다.

TActorIterator<타입> iter(world);

액터만이 아닌 모든 언리얼 오브젝트의 경우

TObjectIterator<타입> iter(world)

 

액터 특정 상황에 따른 레퍼런싱

예를 들어 특정 오브젝트에 포함된(겹친) 액터 얻기 위해서는 GetOverlappingActors() 함수를 사용한다.

TArray<AActor*> ObjectArray;
TargetObject->GetOverlappingActors(ObjectArray);

액터의 컴포넌트 검색

Actor->FindComponentByClass<UMovementComponent>();

'프로그래밍 > Unreal' 카테고리의 다른 글

[UE4] 디버그 로그 출력  (0) 2017.11.13
[UE4] 유리 매터리얼  (0) 2017.10.15
[UE4] 레벨 스트리밍  (0) 2017.10.15
[UE4] UI 관련 내용  (0) 2017.09.26
[UE4] 폰트  (0) 2017.09.26
[UE4] CSV 파일  (0) 2017.09.24
[UE4] unreal delegate  (0) 2017.09.24
[UE4] 마우스 입력  (0) 2017.09.17
[UE4] 아웃라인 : 스텐실  (0) 2017.09.16
[UE4] 메쉬 외곽선 효과  (0) 2017.09.15