Best way to Handle Area of Effect?

I’ve been working on a game and I have a problem where I have multiple instances that need to be checked in an area when I use a tool, and I’m not entirely sure what the best way is to handle it. The area itself should be able to change in size (not in realtime, mostly as a product of upgrades) and follow/work in the area of the player.

I have a couple of possible solutions but I’m not 100% sure which one is the best - I could either:

  • Create a Region3/Part every time the tool is activated, and check, then destroy. This seems pretty resource intensive and unnecessary if other methods are possible.

  • Create a Region3/Part when the player spawns, and check. This seems ok, but I’m still trying to figure out the best way to move a Region3. There also seems to be an odd issue where parts will spawn before the player does, making the Region3 inaccurate.

The other question would also be in regards to Region3 vs. Touched in terms of which one I should use. Touched is much more straightforward, but I have little knowledge on which one is better performing. I’ve heard that Touched is less consistent but that isn’t too big of an issue for me.

Thanks for the help!


After doing some testing, I believe that the Region3 method is probably my best option. nicemike’s suggestion of using EgoMoose’s module was also really helpful as I no longer have to calculate my own boundaries.

Thanks everyone for the help!

I would try it first with a Region3 + a collision group and see if that fits your use case.

This module might also be useful to you.

If you start to notice performance issues, you can look into some custom solutions where you e.g. only check the center of parts or do a fast magnitude check or something — but I bet you can get something working with Region3 that won’t be a noticeable hit to performance if you’re doing it semi-rarely.

1 Like

Interesting…that module definitely makes life easier.

Also, I just found out that Region3s aren’t objects within the world…would Roblox garbage collect them after use in that case? That would solve quite a bit of my worries.

All objects are garbage collected after any references to them in your code are dropped.

1 Like

This could work for you; it allows you to check for all other parts that are touching a given part. And the reason I used this way of doing :GetTouchingParts() (in the custom GetTouchingParts function) is because regularly, :GetTouchingParts() only works for parts that have CanCollide enabled. However, if you’re trying to use it when CanCollide is set to false, you need to use that trick, which I found here.

You could make the part invisible with transparency, and then set CanCollide to false, then just move and scale the part as you want. When you want to check for all the parts touching the main part, you just run the custom GetTouchingParts() function and loop through the table that is returned as shown in the below code.

part = script.Parent

local function GetTouchingParts(part)
	local connection = part.Touched:Connect(function() end)
	local results = part:GetTouchingParts()
	return results
local touching = GetTouchingParts(part) -- Call function

for i, v in pairs(touching) -- Loop through all parts touching your part
    -- v are the parts; do whatever you'd like

I hope this helps, and let me know if there’s any questions.

1 Like

Another possibility is to use Region3 to create a boundary box around the general area of the effect and then use magnitude to get a more accurate scope of which parts are in range.

The benefit is the Region3 doesn’t need to be 100% accurate and just allows for narrower table of Instances you would need to check their magnitudes on.

There is a lot of options, mostly dependent on your use cases. Things like CollectionService may benefit even more to filter down what you are looking for.

1 Like