How efficient would using Region3s for custom-explosions be / help with raycasted explosions?


Hello, everyone!

I’ve ran into a massive performance problem in Redshift Arena, my arena FPS that has been featured twice so far. Currently, for Custom-Explosion logic, I’m using GetDescendants on the workspace, which is actually not working out too well on the more detailed maps in my game. I’m wondering if using Region3 would be much better for something like this, or if there’s a better way to handle explosions. I was considering using Raycast, however, I’m not sure how to do a RayCast in a ball shape, so Region3 is my next best bet.

However, if someone can point me in the direction of using raycast for this instead, please let me know! Thanks! :slight_smile:


Region3 definitely sounds better than looping through all of workspace. Best bet though is to try it and see what works better!


I’d recommend looping through all characters caught within a (larger) Region3 and raycasting towards them only a certain distance. If the raycast hits them, then deal damage or kill them.

Good idea using a Region3 because looping through the workspace is VERY expensive if you have a lot of parts. Region3s break it up into chunks and check those, with which you can then just loop through to see what should actually hit.


How would the raycasts not hit the players if a wall or something similar is blocking the explosion? I like your idea of using Raycast, instead of doing a 360-degree ball.


That’s the nature of raycasts - they detect if something is in the way of the ray.
If you have the list of parts which are in the region, you can loop through them and see if they get hit by rays from the centre of the explosion.


You can use workspace:FindPartOnRayWithWhitelist to whitelist players.

On topic of whitelisting. Why not tag all players using collectionservice and then when an explosion accrues, get all tagged players and use rays rotated to the humanoidrootpart of the character and set a ray size (the explosion radius) so not everyone gets hit. Then just use workspace:FindPartOnRayWithWhitelist to check if the ray hit the player or not.


Why not both? With this module, you can create a spherical Region3.


If all you’re trying to achieve with the custom explosions is damaging players, this is a good way to go about it:

  • For loop through all the players in the game, get the position of their character’s HumanoidRootPart

  • Compare the distance between your explosion’s center and their HumanoidRootPart’s position

  • Check if the distance is within the ‘radius’ of the explosion, proceed only if this is true

  • Cast a ray from the explosion center to the character’s position, if this ray collides with a part inside the Character, we deal damage

I personally implement this method for explosions in all my games and have not had any performance issues with it, and I believe it’s far less expensive compared to using a Region3.


So if I have a ray going from the explosion to the player’s HumanoidRootPart, and there’s a wall in front of it, it won’t hit the player?


I’m pretty sure you can simply just create an explosion normally, but just set the Visible property to false. Then, you can use the .Hit event to detect any hit parts within the explosion radius. To make the explosion completely harmless and not push parts, set the .BlastPressure to 0 and .DestroyJointRadiusPercent to 0.


How long ago was this property added to Explosions?

That’s pretty much the only reason I switched over to using a custom explosion system - was to have my own visual look to them.


I don’t know exactly when it was added but it surely was at one point.


Raycasts are better than region3 because what happens if the explosion happens behind a wall? The player dies anyways? Unless you want the wall to be destructible you would want to use raycast (plus raycast is pretty easy to implement for destructible walls).

Region3 makes a rectangle from two points
Raycast simply sends a ray in a direction (then stops at “magnitude” distances)

So raycast is closer to the ball you want.


Region3 is only being used for (as the name states) regions. The Region3 determines the radius around the explosion and any parts within that Region are fetched. The raycasts are then sent out to parts within that region to take effect.

If you only use raycasts, then you’re going to end up iterating over an entire table of things regardless of their positioning. Region3 helps to minimise those results only to parts that are within the area.


That makes it much more efficient, but I thought Region3 was only a rectangle scan. You need two points, so unless I have it wrong I think it only makes a rectangle. Is there a function that makes a sphere scan?


Think of the WorkSpace:FindPartsInRegion3() call as a first pass at getting all the parts intersecting a sphere of diameter D centered at Vector3 P. First we create a cubic region centered at P with sides of length D, then we fire a ray from P to each part found within the region to determine: a) if the ray actually intersects the part we’re testing, and b) if the ray’s length is less than or equal to D/2. If the answer to both of these is yes, then the part is within the sphere of radius D/2 centered at P.


But that still implies that Region3 is only a rectangle (like parts intersecting that rectangle) scan. Can Region3 do sphere scans as well?


No. What I described is a way to use both FindPartsInRegion3() and FindPartOnRay() to find parts that lie within a sphere. The Region3 is in fact a cube, we’re just using it to reduce the amount of computation


That would make sense, but wouldn’t it be simpler to just make a white list of all the parts that are “explodable” and then check if they are within a set amount of studs, then do the magic with raycasting? It would basically amount to the same amount of computation and would work maybe better than Region3, but that’s just me thinking out loud at this point…


That will work fine as long as the size of the whitelist is kept small, but as more and more parts are added most of our time is going to be spent doing magnitude calculations on parts that aren’t even close to being within our desired radius.

@AllYourBlox made a post a few months ago which has some more details on the trade-offs involved when using FindPartsInRegion3()