Download

How to put character contained in TArray<AActor*> into TArray<ACharacter*>

I’m attempting to use UGameplayStatistics::GetAllActorsOfClass, which seems to accept only a TArray<AActor*>. I think there’s two ways to do this, but I’m not sure how to go about either one.

1.) If I can make GetAllActorsOfClass() output to a TArray<ACharacter*>, then I can use that.
2.) If not the former, I can do something that takes characters from TArray<AActor*> and puts them into a TArray<ACharacter*>

Here’s what I have so far:



TArray<ACharacter*> UServerCharacterRegistry::GetAllCharactersInWorld()
{
    TSubclassOf<ACharacter> ActorClass = ACharacter::StaticClass();
    TArray<AActor*> FoundActors;
    UGameplayStatics::GetAllActorsOfClass(GetWorld(), ActorClass, FoundActors);

    TArray<ACharacter*> OutCharacters;
    for (AActor* index : FoundActors)
    {
        //If AActor is ACharacter, Add to OutCharacters;
    }

    return OutCharacters;
}


If someone could point me in the right direction or tell me how to go about this, I’d appreciate it. I’ve been stuck on this for a couple days now.

Maybe this is better:



...
TArray<ACharacter*> OutCharacters;
GetAllCharactersInWorld(OutCharacters);
...

void UServerCharacterRegistry::GetAllCharactersInWorld(TArray<ACharacter*>& OutValues)
{
    TArray<AActor*> FoundActors;
    UGameplayStatics::GetAllActorsOfClass(this, ACharacter::StaticClass(), FoundActors);

    for (AActor* index : FoundActors)
    {
        OutValues.Add(Cast<ACharacter>(index));
    }
}


That seems to have worked brilliantly!

I’ve never used “Cast<class>” before, but it certainly seems handy so I’ll be looking that up. Thank you very much Helghast, I appreciate it! (And thanks for showing how I could reduce the line count too :slight_smile: )

Since GetAllActorsOfClass is rather expensive to call you could take advantage of the existing Pawn iterator and filter out the Characters in that. Here I used the Blueprint Function Library class to make it easy to get from anywhere.

MyBlueprintFunctionLibrary.h


    UFUNCTION(BlueprintPure, meta = (WorldContext = "WorldContextObject"))
    static const TArray<class ACharacter*> GetCharacters(UObject* WorldContextObject);

MyBlueprintFunctionLibrary.cpp


const TArray<ACharacter*> UMyBlueprintFunctionLibrary::GetCharacters(UObject* WorldContextObject)
{
    TArray<ACharacter*> Characters;
    for (FConstPawnIterator Iterator = WorldContextObject->GetWorld()->GetPawnIterator() ; Iterator; ++Iterator)
    {
        auto Character = Cast<ACharacter>(Iterator->Get());
        if (Character)
        {
            Characters.Add(Character);
        }
    }
    return Characters;
}

Why not something nicer?


const TArray<ACharacter*> USomeClass::GetCharacters()
{
           TArray<ACharacter*> OutChars;
            for (ACharacter* Char : TActorRange<ACharacter>(GetWorld())
            {
                  OutChars.Add(Char);
            }
      return OutChars;
}



TActorRange loops through every Actor in the game doesn’t it? FConstPawnIterator only loops through the managed Pawn Array.

Yes but i was referring to the second post, not your one. Sorry for confusion. It’s just i dislike the use of GetAllActorsOfClass in C++.