Most efficient way to add status effects?

I have a small handful of status effects that I need to apply to enemies in my game and I’m curious what would be the be way to do so performance wise.

Should I make a pool of objects that attach to the target when they get that effect that makes the particles and does the damage?

Or since I have such a limited number of status effects would it make more sense to just have every enemy have them preloaded?

Consequently the status effects I’m doing are burning, poison, bleeding, and an energy charge that makes the enemy explode when it is greater than their current life.

You could have a Pooling System accepting on every Request (Position, Effect).

That way you could reuse them every time.
Depending on how many units you have, i would use a Pooling System,

imagine having 100 units carrying 4 effects ea. (for now, who knows if you add more), then you got 100 + 400 Objects which the Engine need to check/carry for which is alot

1 Like

The goal is to have thousands of enemies on screen.

So I’m really trying to squeeze every bit of efficiency out that I can.

Sounds like pooling is the correct option.

But why wouldn’t I just parent the effects to the enemy and send it back to the pool when it’s done? Wouldn’t that be easier?

First just get it working. Don’t imagine yourself into problems that might not even exist, then go and wreck your codebase trying to optimize something that doesn’t need it. Unity is a BEAST of an engine and on modern hardware, you can do a LOT.

Besides, you might put it all together and have a DIFFERENT performance issue, one that your pooling code exacerbates. Write it first!

Standard blurb:

DO NOT OPTIMIZE “JUST BECAUSE…” If you don’t have a problem, DO NOT OPTIMIZE!

If you DO have a problem, there is only ONE way to find out. Always start by using the profiler:

Window → Analysis → Profiler

Failure to use the profiler first means you’re just guessing, making a mess of your code for no good reason.

Not only that but performance on platform A will likely be completely different than platform B. Test on the platform(s) that you care about, and test to the extent that it is worth your effort, and no more.

https://discussions.unity.com/t/841163/2

Remember that optimized code is ALWAYS harder to work with and more brittle, making subsequent feature development difficult or impossible, or incurring massive technical debt on future development.

Notes on optimizing UnityEngine.UI setups:

https://discussions.unity.com/t/846847/2

At a minimum you want to clearly understand what performance issues you are having:

  • running too slowly?
  • loading too slowly?
  • using too much runtime memory?
  • final bundle too large?
  • too much network traffic?
  • something else?

If you are unable to engage the profiler, then your next solution is gross guessing changes, such as “reimport all textures as 32x32 tiny textures” or “replace some complex 3D objects with cubes/capsules” to try and figure out what is bogging you down.

Each experiment you do may give you intel about what is causing the performance issue that you identified. More importantly let you eliminate candidates for optimization. For instance if you swap out your biggest textures with 32x32 stamps and you STILL have a problem, you may be able to eliminate textures as an issue and move onto something else.

This sort of speculative optimization assumes you’re properly using source control so it takes one click to revert to the way your project was before if there is no improvement, while carefully making notes about what you have tried and more importantly what results it has had.

1 Like

Well, thousands of enemies is a hard task.

I would say, stick to the answer from Kurt, optimize when you need it.

Anyways, i would go for the Pooling System and send a Effect when its needed.
You can put the effects as a child when its needed but that wont change the position of the effect, in that case you just send it to a certain destination when you needed and thats it.

Dont add too much “in that case” unnecessary complexity.

Simple:
1 - Pool Handler
2 - Ask Pool for Effect → RaiseRequest(Effect effect, Vector3 position);
3 - When its done → RaiseFinishEvent

and thats it :slight_smile:

2 Likes

I would like to add that you need to specify what is your goal. If you had 4 status effects and you are 100% sure there not gonna be more than like 5-10, then it’s not like it’s bad idea to implement them into every unit, however it depends on what is status effect. Most of the time you want some particles, sound or at least icon, so adding this to each unit sounds like waste of resources. However if your effect is just icon or something you can spawn with some “outer”/global manager then you can just attach simple scriptable objects or even something simpler like enum flags.

All 4 status effects will have visuals.

It seems to me that I could have already made the pool in the time we’ve talked about it so there’s my answer.

Also, I totally get the make it first then optimize it approach and know that a lot of new devs get caught in scope creep, so I do appreciate that advice.

But that said, I actually do have a lot done. I just know exactly what I’m making, I know that it’s never been done before, and I know that it is going to drop jaws when I finally show it.

And when it’s time I want to show a good trailer, but then show it. Show a thousand enemies on screen at once and having it playable. I want to make something that journalist HAVE to talk about. I want a trailer that will be on the front page of IGN.

And anyone hearing me say that is correct to be skeptical, but believe me when I say that this is going to be a game changer.

Devs will be copying my design for decades and I have something that, for a lack of better words, is nothing short of magic.

Keep in mind that you know me, and you know that I’m a very modest person and far from a braggart, so I am being completely sincere when I say that I’ve got something huge.

I just really need to wait for the right time to show it because I work slow.

Thanks everyone.