Most performant way to determine if a player is within bounds of a room?

So the map we have, it’s very large. Lots of classrooms. I figured I could use the new querying APIs to determine if the player is within one of these rooms, specifying a white list to just a single part.

That made no difference performance wise. I only tried this with 7 zones, and I got around 16% activity. I tried both APIs, thinking :GetPartInBounds() (or whatever that one’s called) would work better, but the same results occurred.

I even tried lowering the update rate at which the collision tests were executed, and that still brought it around 2-3% with only 7 zones. There will be a lot more.

I’m a little confused as to what I can really do here. Raycasting certainly won’t work, as if a player is inside of a zone, the ray will never hit the part.

Only other thing I can think of is reduce the update rate even more (< 10 times per second, what I’m using now) and to reduce the volume of the parts I’m using to test for collisions.

Still though, what else can I do?


1 Like

Alright sorry, I just realized I could make flat parts cover the area of each room, and then use raycasting with a whitelist set to those parts.

bruh moment

1 Like

Hmm, the new query methods should be perfect for this.

This example has “script activity” around 0.1% for me with 180 parts, going up to ~0.4% sometimes. Obviously it’s completely unnecessary to check every heartbeat for most purposes. Not sure what activity means exactly, but certainly doesn’t seem like it’s going to be a performance issue.

local TagS = game:GetService("CollectionService")

local getZonesOverlapParams =
getZonesOverlapParams.FilterType = Enum.RaycastFilterType.Whitelist
--Keep track of zone parts instead of re-generating the list using GetTagged every time
getZonesOverlapParams.FilterDescendantsInstances = TagS:GetTagged("ZoneBoundsPart")
	table.insert(getZonesOverlapParams.FilterDescendantsInstances, part)

function getPartZones(part: PVInstance): { Part }
	return game.Workspace:GetPartsInPart(part, getZonesOverlapParams)

local prevOverlapping = {}
while task.wait() do
	local overlapping = getPartZones(game.Workspace.ZoneDetector)
	-- Seems if overlapping isn't "used" for something, activity just stays at 0%???
	table.move(overlapping, 1, #overlapping, 0, prevOverlapping)

That’s really weird.

I even capped the update rate of mine (which should be dead similar to what you wrote) to 10 times per second, which should be more than what task.wait yields for.

What size is the zone that you made? I’m wondering if it was too small, the ones I initially made had quite a big volume.

1 Like

Like 20x20x20 I’d guess chars chars

1 Like