Use “TActorIterator” for that , this may help you
https://wiki.unrealengine.com/Iterators:Object%26_Actor_Iterators,_Optional_Class_Scope_For_Faster_Search
Use “TActorIterator” for that , this may help you
https://wiki.unrealengine.com/Iterators:Object%26_Actor_Iterators,_Optional_Class_Scope_For_Faster_Search
Hi,
I’m looking for something similar to this blueprint node (“Get All Actors Of Class”) in C++.
Thanks
Thanks! exactly what i need
Or you can try this:
Searching for actors of C++ classes:
(Thanks gjudkins for reminding about it
TArray<AActor*> FoundActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), YourClass::StaticClass(), FoundActors);
Searching for actors of BP classes:
TSubclassOf<AActor> ClassToFind; // Needs to be populated somehow (e.g. by exposing to blueprints as uproperty and setting it there
TArray<AActor*> FoundActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ClassToFind, FoundActors);
I found that this doesn’t work as-is. To get it to work you need to replace ‘ClassToFind’ with ‘{YourClassName}::StaticClass()’
Then it works beautifully.
Yeah, the StaticClass function should work here as well.
I didn’t make it very clear in my answer, but the ClassToFind needs to be populated somehow (for example by exposing it to blueprints as property and setting it there).
If a class of actors you want to search for is a C++ class, then sure you can use that.
However, if you want to narrow down the search to specific BP class, then TSubclassOf is what you need here (although I myself never had to do such thing yet).
Here is a simple convenience function for collecting all actors of a given class into a TArray:
#include "EngineUtils.h"
template<typename T>
void FindAllActors(UWorld* World, TArray<T*>& Out)
{
for (TActorIterator<T> It(World); It; ++It)
{
Out.Add(*It);
}
}
An example of finding all of the ATriggerBox instances would be:
TArray<ATriggerBox*> Boxes;
FindAllActors(GetWorld(), Boxes);
Nice and very neat Function thank you!
Thanks for sharing this guys.
To get UGameplayStatics to work I needed this include
#include “Runtime/Engine/Classes/Kismet/GameplayStatics.h”
If you need to get all UObjects of a certain class (not just Actors) here is a nifty function I wrote:
template<typename T>
void GetObjectsOfClass(TArray<T*>& OutArray)
{
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FAssetData> AssetData;
AssetRegistryModule.Get().GetAssetsByClass(T::StaticClass()->GetFName(), AssetData);
for (int i = 0; i < AssetData.Num(); i++) {
T* Object = Cast<T>(AssetData[i].GetAsset());
OutArray.Add(Object);
}
}
Use it like this:
TArray<UAnimSequence*> AnimSequences;
GetObjectsOfClass(AnimSequences);
I know this has already been answered, but I wanted to provide my solution as I was looking for this for a long time myself. As I am fairly new to UE I am not sure if this is the “correct” way, but it works for me and may be useful to others, at least for debugging purposes if for nothing else.
Mainly I simply wanted to get a list of all the Actors, not just of a specific class such as provided by the solutions above. The following was based on looking at the implementation of GetAllActorsOfClass:
using ActorVec = std::vector<AActor *>;
ActorVec
ActorFunctions::getAllActors(UWorld* world)
{
if ( !world ) {
return ActorVec();
}
// Initial traversal to collect number of actors so can reserve vector.
int numActors = 0;
for ( ULevel * level : world->GetLevels() ) {
numActors += level ? level->Actors.Num() : 0;
}
ActorVec actors;
actors.reserve( numActors );
for ( ULevel * level : world->GetLevels() ) {
for ( AActor * actor : (level ? level->Actors : TArray<AActor *>())) {
if ( actor ) {
actors.push_back( actor );
}
}
}
return actors;
} // ActorFunctions::getAllActors
From here, I also wanted to get an actor with a specific name. The implementation is very similar of course:
AActor *
ActorFunctions::getActorWithName( UWorld * world, char const * const name )
{
if ( !world || !name ) {
return nullptr;
}
for ( ULevel * level : world->GetLevels() ) {
for ( AActor * actor : (level ? level->Actors : TArray<AActor *>())) {
if ( actor && actor->GetName() == name ) {
return actor;
}
}
}
return nullptr;
} // ActorFunctions::getActorWithName
This could be made more generic by accepting a search predicate. Or if you really want to go crazy and get all C++/STL-like, the following ActorIterator is compatible with STL algorithms:
class ActorIterator
{
public:
using difference_type = std::size_t;
using value_type = AActor *;
using pointer = AActor *;
using reference = AActor &;
using iterator_category = std::input_iterator_tag;
ActorIterator( UWorld * world = nullptr )
: mWorld( world )
, mLevelIndex( 0 )
, mActorIndex( 0 )
{
}
AActor* operator*()
{
if ( mWorld && ( mLevelIndex < mWorld->GetLevels().Num() ) &&
mWorld->GetLevel( mLevelIndex ) &&
( mActorIndex < mWorld->GetLevel( mLevelIndex )->Actors.Num() ) ) {
return mWorld->GetLevel( mLevelIndex )->Actors[mActorIndex];
}
return nullptr;
}
ActorIterator& operator++() // pre-increment
{
ULevel * level = mWorld ? mWorld->GetLevel(mLevelIndex) : nullptr;
if (level && (++mActorIndex >= level->Actors.Num())) {
mActorIndex = 0;
if (++mLevelIndex >= mWorld->GetLevels().Num()) {
mLevelIndex = 0;
// This iterator only supports single pass (InputIterator), so when it
// has been completely iterated through, we want to be able to compare
// it to a default constructored iterator for the range end condition.
mWorld = nullptr;
}
}
return *this;
}
ActorIterator& operator++(int) // post-increment
{
return ++(operator=(*this));
}
bool operator==(ActorIterator const& other) const
{
return ( mWorld == other.mWorld ) && ( mLevelIndex == other.mLevelIndex ) &&
( mActorIndex == other.mActorIndex );
}
bool operator!= (ActorIterator const& other) const
{
return !operator==(other);
}
static ActorIterator end()
{
return ActorIterator();
}
private:
UWorld * mWorld;
int mLevelIndex;
int mActorIndex;
}; // class ActorIterator
So getActorWithName() becomes:
AActor *
ActorFunctions::getActorWithName( UWorld * world, char const * const name )
{
ActorIterator ait = std::find_if(
ActorIterator( world ), ActorIterator::end(), [name]( AActor * actor ) {
return actor && actor->GetName() == name;
} );
return ait != ActorIterator::end() ? *ait : nullptr;
} // ActorFunctions::getActorWithName
and getAllActors() can be implemented simply with:
ActorVec actors;
std::copy(ActorIterator(world), ActorIterator::end(), std::back_inserter(actors));
Whether that is more clear or faster is debatable, but at least you can also use it on other algorithms.