How to penetrate through a part depending on thickness

Just wondering how you’d find part thickness from a raycast to determine if it’s thick enough to penetrate through or not.

My goal is to have a bullet projectile pierce if the part thickness is >= the weapons penetration depth.

I don’t know how to use “Normal” so I’m sorry if this doesn’t work

if result and result.Instance then
	local HitPart = result.Instance
    --save the size of each axis
    local SizeX = HitPart.Size.X
    local SizeY = HitPart.Size.Y
    local SizeZ = HitPart.Size.Z

	local WorldNormal = result.Normal
	
	-- Turn WorldNormal into "LocalNormal"
	local LocalNormal = HitPart.CFrame:VectorToObjectSpace(WorldNormal)
	
	local X = math.abs(LocalNormal.X)
	local Y = math.abs(LocalNormal.Y)
	local Z = math.abs(LocalNormal.Z)
	
	if X > Y and X > Z then
		--Hit the X axis
        if BulletPiercing > SizeX then
        --your code
        end
	elseif Y > X and Y > Z then
		--Hit the Y axis
        if BulletPiercing > SizeY then
        --your code
        end
	else
		--Hit the Z axis
        if BulletPiercing > SizeZ then
        --your code
        end
	end
end
2 Likes

this is probably not the most efficient way but u can probably do:

1 way: raycast to a direction, when u hit a part, based on that direction, get the corresponding axis (x, y, z) face it hit, and check parts size on that axis. like (if part.Size.X >= depth), issue with this is that it wont work with two walls, the second solution might be better

2 way: raycast to a direction, when u hit a part, have a variable (thickness), then raycast until it leaves the part, raycast distance will be the thickness

1 Like

If the parts being penetrated are simple objects, such as the Part types (cuboid, sphere, wedge etc), then there is definitely a geometric way to find the exit point of a ray entering the object at some point, which should be rather easy to find by googling, or even just by AI if you can’t find something on google.

If the parts are more complex, such as MeshParts, then the only way I know of is to clone the hit object into a secondary WorldModel (or use RaycastParameters which only include the hit object) and then cast a ray backwards from a point further along the ray to hit the back side of the hit object, then the distance between the back point and initial hit point is the penetration distance.
Something like this should work:

local backDistance = 50 -- Whatever the maximum thickness of what you want to allow is
local maxDistance = 200

...

local result = workspace:Raycast(origin, direction * maxDistance, params)
if result then
    local hitPos = result.Position
    local backPos = hitPos + direction * backDistance

    local backResult
    if option1 then
        local part = result.Instance:Clone()
        part.Parent = worldModel
        backResult = worldModel:Raycast(backPos, -direction * backDistance)
    else
        local params = RaycastParams.new()
        params.FilterType = Enum.RaycastFilterType.Include
        params:AddToFilter(result.Instance)
        backResult = workspace:Raycast(backPos, -direction * backDistance, params)
    end

    if not backResult then
        -- Part is too thick
    else
        local thickness = (backResult.Position - hitPos).Magnitude
    end
end

Note that this’ll only get the thickness of the part that was hit, and if you plan on continuing the raycast from the penetrated point, then other objects that were overlapping with the hit part may get ignored depending on how you do it.

1 Like

Raycast to get your hit wall, the normal way, then do a second raycast towards that hit point in the opposite direction as the first raycast. The second raycast should have the hit Instance as the only thing in the raycastparams include list, so you’re only raycasting against that part. The raycast length can be your max penetration distance for the projectile. If you get a hit result from the second raycast, ( hit1.Position - hit2.Position ).Magnitude, the distance between the hit parts is how much of your penetration was used up passing through that part. If you get no result, the second raycast started inside the part, so that part stopped the bullet.

You can also make the second raycast longer, if you’d prefer to always get a measurement of the part thickness, and compare it to your max pen distance. Either way is fine.

Note that this assumes the part is convex and solid. If you have something like a hollow culvert pipe (mesh part or union), and you only want to make sure you get the wall thickness, you have to get a bit more clever. The backwards raycast technique still works, but you will need to either add meta data to the part to give yourself some hints about wall thickness, or you might have to do a binary search where you keep halving the second raycast length and trying again, to make sure you get just the wall thickness, not the thickness across the whole part. Of course, this is probably only an issue if you have weapons that penetrate farther than the overall size of the parts.

Generally, you repeat this process, doing raycasts in the direction fired, until the penetration amount gets used up by the parts that get hit, or the bullet reaches a target character.

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.