Realistic explosion damage

I am adding explosives to my FPS, I was able to find most of the code needed online with no issues and it was pretty straightforward, however I want my explosions to be more realistic.

My game has a lot of indoor parts and walls, so I don’t want the explosion to use overlap spheres because those affect all objects in range regardless how close and if there is anything between them. I want to use raycasts, if possible even RaycastAll, so that I can make the explosion affect objects based not only on distance but also reduce or avoid damage entirely if they are behind a wall.

That would require raycasts in all directions similar to shrapnel from a real life explosive, so:

  1. How do I make so I can loop through all raycasts in a single for?
  2. Is that going to be performance heavy?

Go ahead and use your OverlapSphere to find all objects nearby that would/should be affected by the explosion.

Take the results of the OverlapSphere and do a raycast from the point of the explosion to each object, with a layermask that would only hit obstacles that could block the explosion. If the raycast doesn’t hit anything, then your line of sight from the explosion to the object is clear, and you can apply the explosion force to the object. If your raycast hits something, the way is obstructed and the object is safe.

But what part of the object should I raycast to? The center? Then if the object is halfly protected, it won’t be hit at all or completely hit…

Also, I didn’t mean LITERALLY all directions, that is obviously impossible… I meant something like 1 raycast, then another one rotated 1 degree in one direction, then one more, like a clock in multiple directions… Maybe make it somewhat random too to make it even more dynamic. It would end up with raycasts going in completely separate directions.

What I want is multiple raycasts going in a sphere like manner from the center of the explosion, with some randomness into it but not 100% random (so there is no risk of every raycast going around the same area and having an area right next to the explosion completely unnaffected).

A good compromise might be (pseudocode):

for each hit object O:
  bool hitTheObject = false;
  for each point in O.collider.bounds.corners:
    point = O.collider.ClosestPoint(point);
    if not Raycast(explosioncenter, point):
      hitTheObject = true;

Then you’re doing 8 raycasts per object in range, instead of potentially hundreds of raycasts for every possible direction.

2 Likes

That still has the same issue, where the closest point of an object is always hit if it’s exposed, so if you have someone standing behind a wall and the tip of their foot is visible, it will be like they weren’t protected at all… And in the way you made it, it’s not like there won’t be a ridiculous amount of raycasts, if you have 15 objects close to the explosion that is 15 * 8 = 120 raycasts. Also, I wonder what would happen if the object close to it is a sphere or cylinder?

Is it a big deal to have too many raycasts going in many different directions at once?

You’re going to have to make a tradeoff at some point between 1 raycast and infinite raycasts. Where that tradeoff ends up is your choice.

If you do 8 raycasts and only one hits, maybe you do less pushing than you would if all 8 hit?

At what point does the game lags because of too many raycasts? Does it change whether it is normal Physics.Raycast or Physics.RaycastAll? Only with this kind of information can I choose the tradeoff.

I guess that could work

Only through testing and profiling can you figure this out.

If you want to delve into the job system, you can also use RaycastCommand to do lots of raycasts in parallel: https://docs.unity3d.com/ScriptReference/RaycastCommand.html