Get All Actors of Class each frame - bad idea and slow performance, but how do I do it otherwise?


I have an arrow on my character pointing towards the closest objective and there are 20 objectives on the map. Since I am checking for the current distance with Event tick and I use Get All Actors to get my objective actors I get bad performance. How do I do this calculation any other way?

EDIT: Actually the loading time is the one affected, not the in game performance.

This should not affect performance, even if you’re casting here (there’s no need if you’re just getting the distance). If you want to avoid using Get All Actor of Class in Tick, do it only once at Begin Play, add the resulting actors to an array and use that array instead. You can always *add *| *remove *objects from that array dynamically during gameplay.

Make it reverse, and not every frame.

I was making some asteroid belt started with your approach. First asteroids do not move fast enough to require update each frame, so i made my own slower version of event tick, i called it pulse and fired every 0.2 seconds (after some experimenting it worked fast enough). So there is first optimization.

Second was to move all that tick (pulse code) to asteroid actor. Each one was running its own pulse code, first was very fast check of how far actor is from player. You also can use this (somehow) just find farthest distance from any actor that is possible, and if actor is further, just skip rest of checking.

And last optimization, that kind of gives sense to previous ones. Do not run all of them on same tick each tick, do it in batches, like only 10 each tick. Each actor when created got its own incremental integer ID, ie. incrementing number. And for eg. when i ran pulse every 20th frame, then only actors with multiply of 20 were triggered, next frame every actor for 20+1 etc. that was calculated with modulo function.

More in detail info of how i done it:

  • created event dispatcher, best in game mode or some other global and persisting blueprint
  • that dispatcher is called every frame, and has one value exposed, that is integer number which represents frame, for eg if you want to trigger actor every second you count it from 0 to 49. Two times per second 0…25 etc.
  • every actor on construction event (or begin play) should automatically ask game mode what is highest int number and increase it by 1, highest number is stored in actor as his ID
  • now you fire that dispatcher every tick (or slower if you want, now you have one place to change its frequency)
  • each time you fire dispatcher you increase integer number you send out 0…50 or 0.25 for comparing to ID number in actors
  • when actor recives event from dispatcher it compares if its number modulo 50 (or 25) is equal to integer sent from dispatcher
  • and only then actor does its check for distance to player, and updates it if that is closest, with its own location.

I know its upside down and bit complicated, but that worked best for mobile game. This way i could go from 60 or so asteroids to over 200.

Above post is for moving objects, but if you have all of them static it is very simple:

  • create vector array in your player pawn
  • create event (in player pawn) that upon calling reads vector value and adds it to vector array
  • on begin play in each of actors, call that event to add actor own location

Now in player pawn you have list of locations for each actor. Check which one is closest and update navigation about 5 times a second.

For optimizing loading time you did not gave enough info, it can be complicated model, or material, or something elsewhere.