월드에 속한 액터를 빠르게 검색하는 방법은 두 가지입니다.
하나는 For Ranged Loop 구조에 맞게 추가된 FRangedWorld를 사용하는 방법이 있습니다.
#include "Runtime/Engine/Public/EngineUtils.h"
void UABCGameInstance::Init()
{
....
UWorld* CurrentWorld = GetWorld();
for (const auto& Entry:FActorRange(CurrentWorld))
{
AB_LOG(Warning, TEXT("Actor : %s"), *Entry->GetName());
TArray<UObject*> Components;
Entry->GetDefaultSubobjects(Components);
for (const auto& CEntry : Components) //순회
{
AB_LOG(Warning, TEXT(" -- Component : %s"), *CEntry->GetName());
}
}
}
다른 하나는 TActorIterator를 사용하는 방식입니다.
이 방식은 액터 중에서도 우리가 원하는 타입만 선별해서 목록을 빠르게 뽑아낼 수 있어서
대부분 많이 사용하는 방식입니다.
아래는 현재 월드에서 스태틱메시액터 타입만 뽑아낸 예시입니다.
for (TActorIterator<AStaticMeshActor> It(CurrentWorld); It; ++It)
{
AB_LOG(Warning, TEXT("StaticMesh Actor : %s"), *It->GetName());
}
액터를 포함해 현재 월드에 로딩된 모든 언리얼 오브젝트를 가져오기 위해서는 TObjectIterator를 사용하면 됩니다.
아래 코드를 우리가 생성한 WebConnection가 세 개 로딩되어 있는 것을 확인할 수 있습니다.
하나는 ABGameInstance의 CDO에 있는 객체, 다른 하나는 실제 인스턴스의 기본서브오브젝트로 있는 객체,
나머지는 런타임에서 생성한 객체입니다.
(#include "Runtime/CoreUObject/Public/UObject/UObjectIterator.h"추가해야함)
WebConnection->Host = TEXT("localhost");
WebConnectionNew->Host = TEXT("127.0.0.1");
for (TObjectIterator<UWebConnection> It; It; ++It)
{
UWebConnection* Conn = *It;
AB_LOG(Warning, TEXT("WebConnection Object Host : %s"), *Conn->Host);
}
1. ObjectIterator/ObjectRange
현재 월드에 로딩된 언리얼 오브젝트(UObject)를 순회하기 위해 사용한다.
모든 언리얼 오브젝트를 순회하는 FObjectIterator와 특정 타입의 언리얼 오브젝트를 순회하는 TObjectIterator/TObjectRange로 나눌 수 있다.
Iterator와 Range 클래스는 "Runtime/CoreUObject/Public/UObject/UObjectIterator.h" 파일에 정의되어 있다.
1) FObjectIterator
언리얼 오브젝트(UObject) 타입을 특정짓지 않고, 순회할 때 사용하는데, 이 녀석은 Range 클래스가 별도로 존재하지 않는 점은 참고/유의해야 한다.
아래 예제는 현재 월드에 로딩된 모든 언리얼 오브젝트(UObject)를 순회한다.
// World에 로딩된 모든 UObject 순회
for (FObjectIterator entity; entity; ++entity)
{
UE_LOG(LogABGameInstance, Warning, TEXT("Loaded UObject : %s"), *entity->GetName());
}
2) TObjectIterator/TObjectRange
FObjectIterator/FObjectRange와 달리 TObjectIterator/TObjectRange는 특정 타입의 언리얼 오브젝트를 순회할 수 있기에, 훨씬 더 실용성이 높다.
아래 예제는 현재 로딩된 UStaticMesh만 순회한다.
// 월드에 로딩된 UStaticMesh 오브젝트 순회
// 아래 2문장은 완전히 동일하다
for (TObjectIterator<UStaticMesh> entity; entity; ++entity)
for (const auto& entity : TObjectRange<UStaticMesh>())
{
UE_LOG(LogABGameInstance, Warning, TEXT("Loaded UStaticMesh : %s"), *entity->GetName());
}
2. ActorIterator/ActorRange
Actor는 레벨에 배치된 UObject이므로 순회에 현재 UWorld 객체를 요구한다.
월드 내 레벨에 배치된 모든 Actor를 순회하는 FActorIterator/FActorRange와 특정 타입의 액터를 순회하는 TActorIterator/TActorRage로 나눌 수 있다.
Iterator와 Range 클래스는 "Runtime/Engine/Public/EngineUtils.h" 파일에 정의되어 있다.
1) FActorIterator/FActorRange 예제
ActorType을 특정하기 않고, 모든 Actor를 순회할 때 사용한다.
아래 예제는 월드 내 모든 Actor에 대해 각 Actor들이 어떤 DefaultSubobject들을 가지고 있는지 출력한다.
UWorld* world = GetWorld();
// World의 모든 Actor 순회
// 아래 2문장은 완전히 동일하다
for (FActorInterator(world) entity; entity; ++entity)
for (const auto& entity : FActorRange(world))
{
UE_LOG(LogABGameInstance, Warning, TEXT("Actor : %s"), *(entity->GetName()));
TArray<UObject*> components;
// UObject::GetDefaultSubobjects (Runtime/CoreUObject/Private/UObject/Obj.cpp)
// 해당 UObject의 defaultSubobject들을 out parameter인 TArray에 채워줌
entity->GetDefaultSubobjects(components);
for (const auto& entity : components)
{
UE_LOG(LogABGameInstance, Warning, TEXT(" -- Component : %s"), *(entity->GetClass()->GetName()));
}
}
2) TActorIterator / TActorRange
FActorIterator/FActorRange와 달리 TActorIterator/TActorRange는 ActorType을 지정하여 순회할 수 있어,
개발 과정에서 더 자주 쓰이는 녀석이라 할 수 있다.
아래 예제는 레벨 내 Actor중 StaticMeshActor만 순회한다.
// World의 Actor중 StaticMeshActor 한정 순회
// 아래 2문장은 완전히 동일하다
for (TActorIterator<AStaticMeshActor> entity(world); entity; ++entity)
for (const auto& entity : TActorRange<AStaticMeshActor>(world))
{
UE_LOG(LogABGameInstance, Warning, TEXT("StaticMeshActor : %s"), *(entity->GetName()));
}
'Unreal > Concept' 카테고리의 다른 글
BlueprintImplementableEvent, BlueprintNativeEvent (0) | 2019.05.28 |
---|---|
ConstructorHelpers + 애셋 로딩 시점관련 (0) | 2019.05.28 |
TFieldIterator, NativeFunctionLookupTable (0) | 2019.05.27 |
언리얼 엔진 소스 디버깅 하는 방법 (0) | 2019.05.23 |
깃허브 언리얼엔진 풀소스 C++ 빌드 (0) | 2019.05.23 |