월드에 속한 액터를 빠르게 검색하는 방법은 두 가지입니다.

하나는 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()));
}

 

+ Recent posts