Iterating over UObjects
The function below can be used for all Run-Time instances of UObject. Iterators in Unreal Engine are always accurate. More info about Iterators in the Iterators handbook
#include "EngineUtils.h"
void AExampleClass::PrintAllObjectsNamesAndClasses()
{
for (TObjectIterator<UObject> Itr; Itr; ++Itr )
{
ClientMessage(Itr->GetName());
ClientMessage(Itr->GetClass()->GetDesc());
}
}
- Object iterator is going to iterate over objects in the Pre-PIE world / the Editor World. This is not an issue when the game is running as an independent Game Instance / the editor is closed. Otherwise it can lead to unexpected results.
- Object Iterator does not require a
UWorld*Context - so Object Iterator is the way to get the proper context and access the entire living game world even when there's not possible to obtain theWorld(). UObjectiterator can contain as well as iterate over all components that are inherited from this class, see Get Asset based of Class example. It can also iterate overTObjectIterator<AActor> Itr;,TObjectIterator<ACharacter> Itr;and others.
Get the names of all objects
.h
#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
* Get the names of all objects
*
* @param bOutSuccess If the action was a success or not
* @param OutInfoMsg More information about the action's result
*
* @return Names of all the objects
*/
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Get All Actors Of Class")
static TArray<FString> GetNamesOfAllObjects(bool& bOutSuccess, FString& OutInfoMsg);
.cpp
#include "Kismet/GameplayStatics.h" // Engine
#include "EngineUtils.h" // Engine
#include "Engine/StaticMeshActor.h" // Engine
TArray<FString> UExampleClass::GetNamesOfAllObjects(bool& bOutSuccess, FString& OutInfoMsg)
{
// New list of names
TArray<FString> Names = TArray<FString>();
// Loop through all the objects using TObjectIterator
// The class in <> is used as filter when getting the objects. This can be any class you want (as long as it's an Object)
// In this case, we simply use the UObject class directly to get all the possible objects.
// Also, for objects you don't need to specify a world as they're not only in a world. They're everywhere.
// But that also means there are a lof of them, you probably want to filter the class you're looking for.
for (TObjectIterator<UObject> It; It; ++It)
{
// Get the real UObject from the Iterator
UObject* Object = *It;
// Get the Object's name
Names.Add(Object->GetName());
}
// Return the names
bOutSuccess = true;
OutInfoMsg = FString::Printf(TEXT("Get Names Of All Objects Succeeded"));
return Names;
}
Get Asset based of Class
As UObject is a class from which many Classes is inherited, it may be used for a parameter that allow to transfer any type of its inherited assets, see the code below:
#include "Engine/StaticMesh.h" // Engine
#include "Engine/SkeletalMesh.h" // Engine
#include "Engine/Texture.h" // Engine
#include "Animation/AnimSequence.h" // Engine
#include "Engine/DataTable.h" // Engine
#include "Sound/SoundWave.h" // Engine
UAssetImportData* UExampleClass::GetAssetImportData(UObject* Asset)
{
if (Cast<UStaticMesh>(Asset) != nullptr) // UStaticMesh
{
return Cast<UStaticMesh>(Asset)->AssetImportData;
}
else if (Cast<USkeletalMesh>(Asset) != nullptr) // USkeletalMesh
{
return Cast<USkeletalMesh>(Asset)->GetAssetImportData();
}
else if (Cast<UTexture>(Asset) != nullptr) // UTexture
{
return Cast<UTexture>(Asset)->AssetImportData;
}
else if (Cast<UAnimSequence>(Asset) != nullptr) // UAnimSequence
{
return Cast<UAnimSequence>(Asset)->AssetImportData;
}
else if (Cast<UDataTable>(Asset) != nullptr) // UDataTable
{
return Cast<UDataTable>(Asset)->AssetImportData;
}
else if (Cast<USoundWave>(Asset) != nullptr) // USoundWave
{
return Cast<USoundWave>(Asset)->AssetImportData;
}
// .. any other asset type inherited from UObject
return nullptr;
}