How to universally detect if a part is fully inside a floor

Im wrking on a system that lets you pour gas on the floor and ignite it, id like to detect if the gas part is fully inside any parts, and not exposed to air. I want this to ignore the Y cordinate because it doesnt matter, not like you can put gas on the walls lol

This post is pretty close, but its not universal. I would have to supply a floor part and the gas part, but i need it to be standalone with the gas part. How would i check if the gas part is in the air?

I mean not sure if this is what the question is but, depending on the part’s size I would just raycast downwards OR if you want to account for slopes use the corresponding vector of the part’s cframe

Use method :GetTouchingParts or :CanCollideWith
Char limit

can you try raycasting into the part from a bunch of directions


Obviously there are several flaws with this system but you could get to a decent result in some way or the other.

An alternate way would be to have attachments setup at each corner of the part and check whether all of them are inside the wall:

local function checkPartInsideWall(part, wall)
    local attachmentsInside = 0
    for _, attachment in pairs(part:GetChildren()) do
        local op = OverlapParams.new()
        op.FilterDescendantsInstances = {part}
        op.FilterType = Enum.RaycastFilterType.Exclude
        local check = workspace:GetPartBoundsInRadius(attachment.WorldPosition, 0.01, op) -- might have to tweak size?
        if #check > 0 then attachmentsInside += 1 end
    end
    local final = attachmentsInside == #part:GetChildren()
    return final
end

This exact code is not guaranteed to work but something along similar lines could get you where you want to.

Ummm that called reinventing the wheel.
Physics related methods such as :GetTouchingParts() or workspace:GetPartsInPart() or even workspace:GetPartBoundsInBox() is the only way to go.
Raycasting also would be insanely unpredictable and would error to produce good result most of the time.

You clearly have no idea of what you’re talking about so take a moment before posting a comment about someone trying to help.

2 Likes

to be fair, :getpartsinpart returns parts touching/partially inside a part, i mean detecting if a parts geometry is fully inside another parts geometry

Im pretty sure workspace:GetPartsInPart() does exactly that

Since you don’t understand how the function works,

workspace:GetPartsInPart() would return true in both the images that I sent. However, we want a function which returns true in only the second condition.

it returns all parts touching/inside a part. I want to return all parts 100% inside a part

In that case your method would not work neither.
This has nothing to do with raycasting but instead bounding boxes

You still clearly don’t understand this discussion, please don’t reply.

2 Likes

Im not calculating volume ever with the raycast. My method was to raycast into each face and check if the raycast instersects with an other part (which means that some other part is covering that face of the gas part, meaning that face is submerged inside the part.) And then, you simply check if all faces are submerged in the part, if yes then that means the part is probably fully submerged inside.

The raycast’s are not going to be unpredictable, however they might be imprecise for some cases where the rotation of the gas part might result in one edge sticking out of the other part, but that would only happen if the same rotation also makes so that the center of the face is inside the part while an edge sticks out. This can happen for sure but it’s an extremely rare edge case and such a small loss of precision may/may not be acceptable depending on OP’s use cases.

My other method with attachments just checks if each corner is intersecting with some other part, representing each corner through an attachment.

Another baseless and fully wrong statement from you. Please contribute to the discussion.

like what has already been mentioned, raycast checks are probably the best way if youre dealing with geometry more complex than boxes and spheres and they are extremely cheap for performance so brute forcing accurate checks with a ton of rays should be ok, that being said the amount of rays can be probably be decreased if the geometry involved is very simple.

heres a screenshot of the parts and code and the roblox file for the place, press play and it will print the results in console.



detectIfPartFullyInsidePart.rbxl (56.2 KB)

Raycasting is NOT cheap unless done in parallel
Also calculating volume will be literally the best method

TL;DR someone has already made formula for that Help to check if a part is full inside another part - #4 by ThanksRoBama

bro just leave already. ive benchmarked raycasts and they are crazy cheap on performance and even better if they are setup optimally, running several thousands of rays in a single frame on a low end device wouldnt be a problem if I remember correctly.

using volume would be very limited.

parallel lua has overhead that is so bad that its a struggle to squeeze out any benefit, especially for such a low amount of rays that would be needed for decent accuracy in this instance

Then that would be so good to not gatekeep the code to prove legitimacy of your claims.

Trigger box should be OuterPart and Box that should be inside should be Inner
I did asked chat gpt for formula and i tested it so dw.

local EPSILON:number = 1e-6--Avoid false floating point calculations (hacky)
local function isPartFullyInside(inner: BasePart, outer: BasePart): boolean
	-- Step 1: Get transformation from inner to outer's local space
	local relativeCFrame:CFrame = outer.CFrame:ToObjectSpace(inner.CFrame)
	-- Step 2: Convert inner's size to outer's local space
	local rx, ry, rz = relativeCFrame.RightVector, relativeCFrame.UpVector, relativeCFrame.LookVector
	local ix, iy, iz = inner.Size.X *0.5, inner.Size.Y *0.5, inner.Size.Z *0.5

	-- Project inner's half-size into outer's local axes
	local offset:Vector3 = Vector3.new(
		math.abs(rx.X) * ix + math.abs(ry.X) * iy + math.abs(rz.X) * iz,
		math.abs(rx.Y) * ix + math.abs(ry.Y) * iy + math.abs(rz.Y) * iz,
		rx.Z * ix + ry.Z * iy + rz.Z * iz)

	-- Step 3: Compare projected center and extents
	local center:Vector3 = relativeCFrame.Position
	local outerHalf:Vector3 = outer.Size *0.5

	return math.abs(center.X) + offset.X <= outerHalf.X+EPSILON
		and math.abs(center.Y) + offset.Y <= outerHalf.Y+EPSILON
		and math.abs(center.Z) + offset.Z <= outerHalf.Z+EPSILON
end

Edit: i optimized function a little

benchmarked again and a raycast from an origin 10 studs above baseplate to the baseplate 10,000 times takes 8ms on my pc, 12ms on roblox servers and 26ms on an iphone 7 which could be considered low end device nowdays. the amount of parts a ray has to check and its distance it travels affect performance. I over exaggerated its performance earlier but its still pretty good and around 100 rays for my function should be ok for the OPs use case I think

Why would you use raycasting where it’s not needed?
I already provided a working formula that is robust, unlike your raycasting that would require creating parameters and is not the right way to implement something like that and is very unsafe for plot system for example.