Cost of Get All Actors of Class

Calling this once per blueprint widget (UMG) tick to grab players and bots (ShooterCharacter). Bad idea? Is this a brute force search or is this query optimized in someway (spatial partition, actor pools)?

1 Like

Just a thought, but why not have players added to an array on join, and removed on disconnect. Then do the same for bots on spawn/destroyed. That way, you only have to interate through the list for whatever you are trying to do, not build the list and THEN do whatever you have to do. If you are really worried about missing something, set up a timer (like once a second) that polls the Get All Actors of Type and checks the arrays.

Yes, that would be great! So, how can you go about doing that? Are there join/spawn/exit events I can listen for in a blueprint? Not seeing anything obvious yet. Maybe something in code I can expose?

Hrmm, not sure on that one. I was going to say use the begin play event, but that might not work well with respawning.

GetAllActorsOfClass() is a brute-force search so it does not scale well and can be slow. Of course if you do not have a lot of actors spawned it might not be a problem.

I have not seen any profiling markers is that function so it is hard to check how much time is really spend getting all the actors.

Marc

There are Login and Logout functions in AGameMode which could be used in C++

But in BP, I don’t know :confused:

FYI - For future users, I thought it would be important to note that GetAllActorsOfClass DOES NOT iterate over all actors. It only iterates overe a hash of all actors of that class…

TActorIteratorBase is a templated class and queries a class-specific hash.

See http://www.casualdistractiongames.com/single-post/2016/09/15/Inside-UE-Source-FUObjectHashTables-the-magic-behind-GetAllActorsWith

2 Likes

So GetAllActorsOfClass is O(N) with N the number of Actors of the specified class in the current level?

The hash table used is likely similar to an unordered_map. So, it depends on the hash function used to distribute the elements into buckets, where best case would be O(1) and worst case (if all elements end up in the same bucket due to a bad hash function) would be O(N). The answer in this link explains it pretty well:

Assuming UE4 uses a well tested hash function for these per class Actor hash tables, I’d assume you’d normally have the best case of O(1).

What I’m pointing out is that it needs to copy the Actors references to a TArray anyway (from the map to return for the Blueprint system) so it should be O(N) always, with N being the Actors of the class selected