[SOLVED] 2D Game - Many AIs, performance issues with Character Movement Component.

Hi all,

I am making a 2D game (top-down) inspired by Vampire Survivers to practice my Blueprint skills.
I am solely working with Blueprints, not touching any C++ (I’m not a good programmer, and BP was the thing I wanted to learn more of).

I have run into an issue because of the number of enemies displayed and calculated on screen. My tracing/insight shows that the character movement component is the issue. There isn’t much I can do to optimize this more than I already have done after reading up a bunch on it (some examples, disabled tick for all components that do not need it, reduced tick speed, simplified collision calculations, etc.)

So I am left with two options. Either base the enemies on just a Pawn (the enemies I have use simple AI movement to find the player) or make my own kind of Pawn with elementary logic. All that these enemies are supposed to do in terms of movement is find the player, move to the player, move on a 2D plane, and do collisions.

I am not sure which one is the best, base it on the Pawn or do a custom solution. If anyone has any experience with this, all thoughts are much appreciated!

I am also using Unreal Engine 5.5.1.

TLDR;
2D game with many actors using Character Movement Component, bad fps.
Use Pawn as a base instead or make a custom one? And if custom one, what is the most efficient movement logic to find player?

1 Like

Hi, how many characters are you using (I think something like up to 100 could work, more likely not)? What you could try is:

  • Remove the physics assets of the character
  • In the character movement component use navmeshwalking (instead of walking) for the movement and disable “Sweep While Nav Walking”
  • Disable animation (to see how much that costs, if its heavy the optimize that → only tick pose when in view, enable update rate optimization, potentially use anim sharing, …)

Thanks for your reply.

I guess there is a maximum of around 200 on screen at the same time.

  • The physics asset is used for a simple collision check every 2 seconds between the enemies so they don’t overlap.
  • I tried using navmeshwalking, I’ll try out the Sweep thing.
  • There is no animation on these. They are only 2D sprites being moved around (which is why I am looking into other solutions than the character component).

Just did a quick test, 1000 characters containing only a single sphere mesh all randomly moving around cost me 31-32ms. Without collision its 16-17ms, without the sphere mesh its 14-15ms. Without collision but with RVO avoidance instead its 19ms. So 200 should work, but AFAIK they cost the same whether they are on screen or not.

With a pawn and FloatingPawnMovement (again 1000 of them), with collision enabled and a single sphere mesh it costs 18ms, without collision 11-12ms. And without collision and without the sphere its 9ms.

And my cpu is an AMD 3900X.

So a pawn seems quite a bit cheaper. If you use FloatingPawnMovement with a pawn, then you need to have a capsule component as root component to use the build in AI movement (MoveTo).

1 Like

I did some testing myself, it seems much lighter now with only using a Pawn instead of a CharacterComponent. But I’m not able to test it properly like the other version of my enemy because I am getting a lot of new issues since this is a completely different setup.

I will post the difference with statistics here when it works properly.

Right now I am getting issues with a CapsuleComponent being spawned as a root instead of my existing CapsuleComponent on spawn. I almost have the enemies working as before.

After reimplementing my enemy characters using Pawn instead of Character as a base, then rewriting everything to work with the Pawn instead of the Character and CharacterMovementComponent, I can’t get it under 60 fps in a shipping build, which I could easily do before.
Before, when using Character as a base, I managed to get the game to 11 fps when there were 500 enemies, now it stays at 60.

1 Like