Download

Best way to handle enemy potential target list?

I’ve got a game where I spawn projectiles that will home in on enemies. Right now I’m using an interface that is attached to enemy character BPs. When the projectile is spawned, it does a get all for that interface, then a ForEachLoop to determine the which actor is in the viewport and nearest the center of the screen. However when many of these particles are spawned, it creates performance issues. I notice a huge increase in MS, particularly from World Tick Time and Tick Time when monitoring Stat Game. (Nothing is being run through tick in these assets, and it’s been disabled which is also puzzling).

I’m thinking there has to be a better way to handle potential targets rather than doing a get all on each projectile spawn?

I spawn 18 enemies total, and when 1 dies another is spawned in their place until certain objectives are complete. I also have multiple enemy types, so I’d need a way to be able to reference multiple actor types rather than just 1.

How would I go about doing this in the most efficient way? I was thinking of doing some sort of functionality in the gamemode that added spawned actors to an array, then referencing the game mode and that array when spawning the projectiles. My only concern with that is how do I do that with multiple actor types if arrays can only be of a single object type?

Am I totally off, and there is some other way to handle this? Any help would be greatly appreciated!

Wouldn’t it be enough to just spawn the projectile and have it follow the current facing direction? Homing could still happen if these enemies move. This usually is done with a line trace for pawn, then on break Hit Actor you could save this actor to a variable, spawn the projectile blueprint, and reference the target actor.

Hi, your projectile movement and the checks for collision (the sphere collision component that generates overlap events) will also use up time. So you might wanna try spawning your projectiles without a projectile movement component and without any collision to make sure that your blueprint logic is using up the performance and not what is running under the hood.

Or you could use the profiler How to improve game thread CPU performance in Unreal Engine - Unreal Engine There you can see what is using up how much time. I would look at the tick time and how much time your projectile is using up there, how much goes into blueprint time there, how much goes into the projectile movement component, … (you can even see how much time each of your blueprint functions use up, so you might also wanna take a look at how much time the function that acquires the target uses up before you start using up time optimizing that). So unless you directly know where your performance problem is, using the profiler will go much faster than trial and error.

So I would first look for something like this:

Hmmm, might be that I missed something, but why not just make it of type Actor and retrieve any necessary information via an interface?

Hey unit23! With how the particles spawn I’m not sure how that would work. I delay enabling the homing functionality, so it moves outwards, then course corrects to the target in front of you/nearest the center of the screen. Am I calling the line trace from the player character I assume?

I tried looking this up through profiler - saved some gameplay and loaded it up but honestly I don’t really know what I’m looking at lol. When I’m just firing the projectile and no enemies are around I don’t notice any performance issues. It isn’t until it starts colliding with the enemies that the FPS starts to dip, and the Tick Time and World Tick Time start to spike.

If I were to send you the Stats file, do you think you may be able to make heads or tails of what the cause is by any chance?

Sure I can look through it. And it would be best if you would take the stats file while you have the performance problems, then what is causing them will be most visible inside the stats file.

Thanks, I recorded it during a play session where I had performance issues. I’ll PM you the link. =)

I looked through it, and one thing I found that is not consistent is the character movement time of your 18 bots. It goes from around 1.7ms when you have high frame rates to around 13.9ms when you have low frame rates.
And inside the character movement time what is especially not consistent there is the “Update Child Transforms” inside the “End Scoped Movement Update Time” and twice the “Component Post Update Nav Data” time. Once during “Char PhysWalking” and once during “MoveComponent(Primitive) Time”. And all the three times the time ends in self.

But I don’t know what this logic is doing and have no idea why it is changing that strongly in execution time.

Incidentally the character movement time of your player is consistent at around 0.7ms

So it seems to me that it is no code that you yourself wrote that is causing the performance problems directly, but rather something you’re doing that is then indirectly causing the build in character movement logic of your bots to increase in execution time.

So this is causing your frame time to increase. ““EDIT: But I have no idea what is causing those three times to vary that much (by around 12ms between high and low framerates).””

Do you destroy the projectile after collision or what happens when it collides with a bot? [HR][/HR]
By the way, did you get my reply on the PM? Never used this so I’m not entirely sure how it works =)

I’d just do a box trace from the center of the screen forward and grab the first npc it hits as the target. I use this for a lock on system and it’s pretty reliable. If you are spawning multiple projectiles at once, you might want to do your box trace once from the character BP and assign that to your projectiles with an exposed on spawn variable.

^^ This ^^…

Profiling / performance is so tricky / ambiguous sometimes.

Is there a tipping point elsewhere perhaps… For example, do you see the same consistent problem when you run the game in a vanilla or basic test level…??? I would try toggling collision on the enemies on / off too… (Maybe even toggle the level environment collision on / off as well)…:wink:

Lots of projectiles colliding can eat into FPS… If the projectiles are close to their target but not connecting with the detection code for some reason, you can do a distance check and teleport them to the target / destroy them / apply damage…

all your enemies do not inherit from base class?

I have this hierarchy and so I can always take a group of them

  • CharacterBase
    –PlayerBase
    —PlayerLocomotion
    ----PlayerShooter
    –NPC
    —NPC_Monster
    ----NPC_Monster_Migo
    ----NPC_Moster_XXX
    —NPC_Biped
    ----NPC_Locomotion
    -----NPC_Soldier
    -----NPC_Social

if you make an array of npc you can reach all types of enemies

Sorry for the late response,

Yes I did in fact get your PM! I thought I responded but I’ll have to double check. =)

To answer your question yes I do in fact destroy the projectiles once they collide with the enemies.

That’s what’s stumping me on this issue as well. I’ve double checked my BP code over and over again and I can’t find anything that would cause it to react like this.

I initially thought maybe it was the get all interface code I ran when the projectile spawned in order to find potential targets, but upon further testing that doesn’t seem to affect it at all. I ran tests where homing target/get all potential targets was disabled, just spawning the projectiles and letting them fire off in linear movement. Doing this on it’s own nothing happens. However doing it in a way where I angle my character so the projectiles will collide with the enemies causes the MS increase and subsequent FPS drop over time.

Even when I destroy characters that have been collided with the projectile, the MS will go down, but once I hit another enemy with it it will bounce back up to the last value it spiked at.

What sort of things do you think might indirectly affect this?

Appreciate you looking into this too btw, this is something I really would like to iron out. =)

Thanks, I’ll be looking into trying a trace method and seeing how it works. =)

The level I’m running in is very basic. Normally I maintain 120 fps on there, 8.33 ms tops throughout. There are about 4 or so projectiles that spawn through this attack, and they immediately destroy actor as soon as it overlaps with an enemy so I don’t think that’s the problem. It isn’t having an issue with connecting to the target and initiating the destruction sequence. It’s just seemingly causing an MS increase when it does so. =/

They inherit from the regular Character class. =)

The event begin play of the “Magic_MultiProjectiles” takes up an average time of 0.035ms of your average frame time of 11.390ms so nothing that could constantly drag down your frame rate, but it causes some spikes in your frame time (since it is adding around 6ms to the frame you’re executing it in), so you might wanna change this logic later on since this will/could cause you to drop from 60fps for the frame where you spawn it and therefore could lead to a short lag.


[HR][/HR]

So it’s the character movement of your bots that is causing you the low frame rates. And from what you say it seems to me that the reason why it sometimes takes up more time is somehow related to the projectiles of the player.

Further from looking at the frame times it seems to me that as you fire the “Magic_MultiProjectiles”, they get removed you fire them again and so on, your framerate starts to continuously go down and stays down even if there are no “Magic_MultiProjectiles” anymore. But the moment you destroy all the 18 bots the frame time goes up to normal again and stays high even when you spawn the 18 bots again. [HR][/HR]
Since I don’t know what causes this I would go with a trial and error approach to try narrow it down. Some things I would try (in different combinations and not necessary in this order)

(1) make sure it is not related to your level or to your specific project/project settings. So try it in a new level that contains only what is absolutely necessary. If this changes nothing try it in a blank project and there in a new level (so migrate the player, the bot, and the player projectile over to the new blank project).

Since it is apparently related to the character movement of your 18 bots and the “Magic_MutliProjectiles”

(2) Try making a new projectile where you only have what is absolutely necessary and use that instead of the “Magic_MultiProjectiles” and see if that still causes the problem, then continue adding logic there until you either experience the performance problem again, or have the same logic as in the old “Magic_MultiProjectiles”

(3) Try to use a different bot that inherits from character and start with as less as possible and continue testing and adding logic until you either experience the performance problem again, or have the same logic inside this new bot as you had in your old drone bot.

(4) Try changing the movement mode of your drone bots, so maybe try “flying” instead of the default “walking”.
[HR][/HR]
(5) I don’t know enough about navigation/movement/collision so I don’t know if this could change something, but you could try creating a new collision type for your “Magic_MultiProjectile” and then

(-) set both your capsule component and the mesh of your drone bot to ignore this collision type, so the “Magic_MultiProjectile” should just fly through your bot without any collision if that solves the performance problem, then
(-) set the mesh of the drone to block the collision type of your projectiles, so now the projectile should again collide with the drone bot, and see if the performance problem returns

Thanks for the detailed suggestions. I’ll give this a go and report back results. =)

Since the ms increase is related to your character movement, I would say this right here is probably where your issue lies. Whatever code you are using to angle/rotate your character may be fighting with some other code or perhaps some kind of infinite loop… or maybe unreal just really doesn’t like it.

When I spawn projectiles, I get the look at rotation for the target and plug that into the spawn rotation of the projectile.

You may already know to do that, and maybe I’m misunderstanding, but it just sounded from what you said that you might be rotating your whole character for each projectile spawned…

What I was referring to in the part you quoted was when I disabled homing target on the projectiles to see if that was the cause. After disabling it, I would let my character be surrounded by enemies while firing it so it will still hit them. Nothing code related to rotating my character or anything, just positioning in a way where the projectiles would still hit the enemies when homing was disabled. =)

In my experience infinite loops usually crash the game. I’ve got an attack rotation for the enemies that I go through where they check their distance to the player character, if within range they fire, if not they reset, delay, then try again. Do you think that may be a contributing factor? I’m not sure how else I would handle enemy attack rotations.

Triggers…

Any elaboration on the logic behind it?

Sorry you have 4308 messengers, I did not expect to have to explain things to you from unreal, hahaha.

Is it for your Simulacrum game?
Triggers are fine if the enemy is already spawned in an area of the map and you enter it.

But what I see is that you spawns a lot of enemies and you throw them against the player.

I have a similar enemy in my game.

The first thing is that my enemies do not move where the player is, but even a beacon that spawns it when it is created and it is unique for each of them.
The position of the beacon is not updated every frame, but every x time it watches if the player is far from the beacon.
Then depending on the distance I update the position of the beacon more times, until I put it where the player is.

In your case, if you do not want to complicate yourself, the enemy may carry a trigger so that when you are close to the player it is when you update your position more times.

And so the further they are from the player the less tick they consume.

I’m always learning. =P

And yes I’m still at work on Simulacrum. =)

I have two units, one which swarms the player, another which strafes around you once it reaches a certain distance threshold. The movement code is rather simple, I’m using base BT tasks within the engine for the most part. If I were to not update them in real time the enemies would not adapt to the environment as quickly as I’d need them to unfortunately. =/

When you mentioned triggers I thought you meant as a way to handle their attacks.

The problem is that something funny is going on with the character movement time of the 18 bots (that it increases gradually from around 1ms to 12ms while the player is firing projectiles on them and stays that high, but gets down at 1ms again as soon as the bots are destroyed and respawned), not the blueprint time or general game thread performance issues =)

Altering specific logic of your bots can only solve the issue if the bots are the problem. It may be that it is completely unrelated to them and that your player projectiles or something else entirely is causing the problem. Therefore it might be faster to just use a blank character as bot with some random movement logic and see if that solves the problem. If not, then you can rule out the bots as source of the problem.

Another thing would be to check if the player projectiles or any impact logic causes the problem. One way to check this would be to use the same setup you currently have but replace the player projectile with a new projectile that just flies straight and as soon as it hits a bot destroys itself. If this solves the problem, then you know the player projectile is causing the issue and can look deeper there. If not you have ruled out the player projectile as possible source of the problem.
[HR][/HR]
And also I would make sure that you do not attach anything to the bots when the player projectile impacts them (like particle systems, sounds, …) and see if that changes anything. Cause a great time of the character movement time of the bots goes into the “move component (primitive)”.