How can I optimise many actors in world?

I’ve been working on an unreal project for a few years now.
It features thousands of fish skeletal meshes that roam around throughout it, and I was wondering if I could get help with optimization, as I’ve been struggling with framerate for some time.

My current solution (which helps but isn’t ideal):
Separate the open world into many separate levels in a grid and load when near.
This helps but causes a freeze every time the player crosses a boundary

The only problem for optimization is my animal blueprints, they work by moving forward and changing direction a small increment every tick. This isn’t too taxing for 1 blueprint, but x50 at a time and I start to get slowdown.
I’ve tried using simple culling of the blueprint when at a certain distance, but the blueprint still seems to keep holding down frames.

(What the actors look like in-game)

I’ve been stuck on this for some time now, I can’t figure out a way of stopping the blueprint actors from slowing down frames without having to completely unload them from the game.

Any help would be appreciated

many thanks

What about configuring the BPs ( fish ) so they don’t even draw themselves until they’re near the player?

It’s a trival vector calculation for a fish to find out if it’s near the player. Each fish can work it out for itself.

Hi, some things you could try:

(1) for small fishes you could try using particle systems instead of actors, so each fish would be a particle and you place some of those particle systems around, then use a vector field to move the particles (fishes).

(2) Implement some spawn/despawn system. So either destroy and spawn the actors based on distance to the player, but since each spawn/destroy will cost you some time it might be better to only inactivate/reactivate them (disable tick, disable visibility, pause all timers you have running, … so disable anything that uses performance).

Both times you would need some system that checks the distance to the player. Since you seem to have quite many fishes, I would create a new actor “Actor A” that holds an array of fish actor references / spawn info and first check the distance of this “Actor A” to the player and only then of the references / spawn info it holds to save performance. You might even wanna create another actor “Actor B” that holds a array of references of "Actor A"s and then first check the distance of this “Actor B” to the player, so build a hierarchical system.

(3) Rewrite the logic you execute on tick in C++ (so (3) is more like an and instead of an or, so this would save you performance anyway)

Thanks for the response

But yikes, I have no idea how to implement an actor that holds an array of references like that (and I have no knowledge of c++) although I’ve been working on the project for 2+ years I’m much more suited to the art assets and level design side of things.
Where would I look to even start working on such an implementation?

Thanks so much for the help still

Cogg, you don’t need arrays of actors, you just need to code the fish not to draw their mesh until they are in range of the player.

If you’re interested, come back, and I’ll help you…

Yes Clockwork I’m definitely interested in anything that will help,

How would you go about this?

On a very basic level, it would be something like:

inside each fish.

Probably a good idea to set the frequency of the tick event down to about .5 seconds ( in details ).

Also, I’m not sure if the animation will have a hit when the fish is not visible. If that’s the case, it would need to stop along with that.

The main idea is, when the fish is not seen, it should use almost no resources.

I’ve got 1024 ‘tile shaped fish’ here with no hit whatsoever:


Thanks for that answer
It seems like this is the most helpful script to have
It’ll take me a few days to implement it to all of the different actors, so I’ll get to work and see If it helps me out overall

Before you have to change everything, we can easily ‘prototype’ the whole thing and find out what makes the biggest difference.

All you need is a basic level and one kind of fish. I will post a BP to place a lot of fish randomly and you can check it out.

Gimme a little while…

Had the same issue in one underwater project :slight_smile:
Ended up with representing a school of fish as one animated actor.

And, of course, get rid of tick e.t.c in each actor.

Also, check the flyweight pattern: Flyweight

Here you go, put this in a BP actor:

Just put it in the level, make it the right size, and change the loop amount to change the amount of fish.

That way you can try it out with one fish BP.

I’ve already thought of a way to avoid looking for the player on tick in the fish using dispatchers, but give this a go first see where you get to :slight_smile:

So, I modified it a bit, and wrote a ‘basic spherical fish AI’. This is the default player level with 500 fish in the playing area ( I used fog for the sea ):


I’m getting around 70-80 fps, ok… not great.

A lot really depends on your level, how dense you want the fish, etc.

I can defintely make if faster, and make a version that runs in unlimited space.

But tell me how you do first…

EDIT: 100 fps with another slight tweak…

Not OP, just wanted to tell you how cool that is. Nice stuff! :slight_smile:

(I have also added a cull distance for each skeletal mesh for each fish model I’m using)

Oh wow nice this is helpful
Ok i’ve done a little experimenting and it seems that disabling the tick at a distance does slightly help performance (Jumped from 14 to 17fps) -Which is a lot better than nothing

I’m still going to keep experimenting around but in the meantime, are there any useful commands ingame console I can use to debug (such as realtime wireframe or seeing what is taking up most performance etc)
Thanks for the help

Also, Unfortunately the self-filling spawn volume won’t work for me personally as I have handpicked spots I have been placing my fish in specifically

Ok cool. Mind you, 17fps is still low.

As far as debug goes, there isn’t really console stuff to find out which fish is using all your resources. What I recommend is controlled experiments. Put 50 of one kind in, then try 50 of another kind etc. You’ll be able to find out if one if killing it more, then start looking at it’s animation etc.

Come back if you do want the fill volume. Even if you are handpicking, you can configure it to spawn with a specific profile ( not yet, but easily changable ).

Also, it depends on how large your hand picked areas are, it might still be useful to have a volume follow the player in those areas ( I don’t know your setup ).

Ok. Totally different method. You can have unlimited space, you don’t have to bother with fish visibility. Runs at high speed:


Bascially a self filling spawn volume that follows the player.

Tell me when and if you want to know about it, I don’t want to snow you under with info…

Could you show an image of the following console commands: stat unit, stat game, stat gpu. That would be for us to better see where you’re performance bottleneck is.

But since your frame rate went up when disabling tick (runs on CPU) that would mean you’re CPU bound not GPU bound. So especially the stat game would be useful to see here.

Ok nice some info then


I’m pretty lost when it comes to the technical side of things so I’ll have to look up what I need

Also, the skeletal mesh fish actors I’m using don’t have bones but are instead animated a bit cheaper with a few different morph targets that are powered by timelines