Skip to main content
Minor cleanup
Source Link
DMGregory
  • 140.8k
  • 23
  • 257
  • 401

Optimal way of dealing Dealing damage over multiple frames without damaging the same enemy twice in unity

I am using physics.overlapPhysics.Overlap to find which enemies are in my damage range. But dealing damage in only one frame is not what I want. Some attacks should be active for a longer time, to catch enemies who come into range part-way through the attack. 

But if I call the method again, I can get the same enemy multiple times. This means my damage will be higher if the framerate is higher. To avoid this I can:

  1. Put a timer on the enemy that prevents damage for some period of time after taking damage. This is the simplest approach but it's bad if you have high speed,multi hit multi-hit attacks that damages the enemy multiple times quickly.

  2. Keep track of damaged enemies with a list. As long as the hitbox is active, check every frame for enemies inside the hitbox. For each enemy found, check ifwhether it's already in the list, add it to the list and damage it if not.

  3. Same as #2 but use a dictionary/hashset.

Option #2 is my current approach. Hashsets are supposed to make dupe checks faster BUT I'm not sure how It does that. I use a listList<damageable> to track damaged enemies and damageableDamageable is an interface. 

How does a hashsetHashset<Damageable> differentiate between each entry if they are interfaces?

If I use dictionaries instead I'd need to generate different keys for each enemy. That's another problem unless game objects already have some sort of unique hash key. Even then, there's the possibility of ignoring a gameobject with multiple damageable components.

Then there's also the possibility that I'm getting nothing by doing this optimization. Most hitboxes will probably intersect with 3-5 enemies at most over it's lifetime. Would looping over a list be faster anyways?

Optimal way of dealing damage over multiple frames without damaging same enemy twice in unity

I am using physics.overlap to find which enemies are in my damage range. But dealing damage in only one frame is not what I want. Some attacks should be active for a longer time. But if I call the method again I can get the same enemy multiple times. This means my damage will be higher if framerate is higher. To avoid this I can:

  1. Put a timer on the enemy that prevents damage for some period of time after taking damage. This is the simplest approach but it's bad if you have high speed,multi hit attacks that damages enemy multiple times quickly.

  2. Keep track of damaged enemies with a list. As long as hitbox is active, check every frame for enemies inside hitbox, check if it's already in the list, add to list and damage if not.

  3. Same as #2 but use dictionary/hashset.

#2 is my current approach. Hashsets are supposed to make dupe checks faster BUT I'm not sure how It does that. I use a list to track damaged enemies and damageable is an interface. How does a hashset differentiate between each entry if they are interfaces?

If I use dictionaries instead I'd need to generate different keys for each enemy. That's another problem unless game objects already have some sort of unique hash key. Even then, there's the possibility of ignoring a gameobject with multiple damageable components.

Then there's also the possibility that I'm getting nothing by doing this optimization. Most hitboxes will probably intersect with 3-5 enemies at most over it's lifetime. Would looping over a list be faster anyways?

Dealing damage over multiple frames without damaging the same enemy twice

I am using Physics.Overlap to find which enemies are in my damage range. But dealing damage in only one frame is not what I want. Some attacks should be active for a longer time, to catch enemies who come into range part-way through the attack. 

But if I call the method again, I can get the same enemy multiple times. This means my damage will be higher if the framerate is higher. To avoid this I can:

  1. Put a timer on the enemy that prevents damage for some period of time after taking damage. This is the simplest approach but it's bad if you have high speed, multi-hit attacks that damages the enemy multiple times quickly.

  2. Keep track of damaged enemies with a list. As long as the hitbox is active, check every frame for enemies inside the hitbox. For each enemy found, check whether it's already in the list, add it to the list and damage it if not.

  3. Same as #2 but use a dictionary/hashset.

Option #2 is my current approach. Hashsets are supposed to make dupe checks faster BUT I'm not sure how It does that. I use a List<damageable> to track damaged enemies and Damageable is an interface. 

How does a Hashset<Damageable> differentiate between each entry if they are interfaces?

If I use dictionaries instead I'd need to generate different keys for each enemy. That's another problem unless game objects already have some sort of unique hash key. Even then, there's the possibility of ignoring a gameobject with multiple damageable components.

Then there's also the possibility that I'm getting nothing by doing this optimization. Most hitboxes will probably intersect with 3-5 enemies at most over it's lifetime. Would looping over a list be faster anyways?

Source Link

Optimal way of dealing damage over multiple frames without damaging same enemy twice in unity

I am using physics.overlap to find which enemies are in my damage range. But dealing damage in only one frame is not what I want. Some attacks should be active for a longer time. But if I call the method again I can get the same enemy multiple times. This means my damage will be higher if framerate is higher. To avoid this I can:

  1. Put a timer on the enemy that prevents damage for some period of time after taking damage. This is the simplest approach but it's bad if you have high speed,multi hit attacks that damages enemy multiple times quickly.

  2. Keep track of damaged enemies with a list. As long as hitbox is active, check every frame for enemies inside hitbox, check if it's already in the list, add to list and damage if not.

  3. Same as #2 but use dictionary/hashset.

#2 is my current approach. Hashsets are supposed to make dupe checks faster BUT I'm not sure how It does that. I use a list to track damaged enemies and damageable is an interface. How does a hashset differentiate between each entry if they are interfaces?

If I use dictionaries instead I'd need to generate different keys for each enemy. That's another problem unless game objects already have some sort of unique hash key. Even then, there's the possibility of ignoring a gameobject with multiple damageable components.

Then there's also the possibility that I'm getting nothing by doing this optimization. Most hitboxes will probably intersect with 3-5 enemies at most over it's lifetime. Would looping over a list be faster anyways?