Bullet Wallbanging is not functioning properly


I’m trying to create bullet penetration in a project of mine.
Part of the calculation requires first finding a normalized size:

local NormalizedSize = RaycastResult and (RaycastResult.Instance.Size * RaycastResult.Normal)

And then seeing if that magnitude is less than or equal to the max penetration in studs:

elseif NumberPenetrations < self.MaxPenetrations and NormalizedSize.Magnitude <= self.Penetration then
			NumberPenetrations += 1
			Origin = RaycastResult.Position - RaycastResult.Normal * NormalizedSize.Magnitude * 0.999
			Direction -= Distance

Now the issue is that when parts are rotated, functionality is broken, as the size will be the same on a different world axis.

How do I fix the code bit to include functionality for rotated parts?


So why not just ray-casting again?
The same way it you did it, adding to ignore list the last hit

The issue is that the normalized size isn’t correctly calculated, due to it changing based on the part’s rotation.

Oh, you’re trying to get the normal cframe? like the ray end position? like bullet holes right?

Not exactly, I’m trying to get a normalized size for wallbanging.

I don’t get it, why do you need the size?

To see if the bullet can penetrate. Basically, if the normalized size’s magnitude is less than or equal to the max bullet penetration, allow the ray to continue.

This is how I solved this issue in my gun system:

I fire a ray from the player to get the initial hit position (p1). I step forward by a small number, and do another ray test (ray2). I take the hit position of ray2 (p2), and ray test backwards (ray3) to get (p3) in the diagram.

I take the distance between P3 and P1, and run some logic to check if it’s possible to wallbang that far, and if it is, then I will repeat all the above logic, but starting at P3, instead of the player. I keep repeating until the bullet has either traveled too far or wallbanged through too many surfaces.

You can see the effects of it here: [NPC] Gun Testing - Roblox


Interesting way of doing it.
If I don’t find a way to use one ray with rotation calculations, I’ll be sure to approach that solution.

Size is in world space, and the normal won’t always be pointing in the exact opposite direction of your ray (it could be pointing up at an angle for example if your ray hits a wedge), so there’s your problem.

Instead, I suggest to keep raycasting through the wall, except backwards and in the direction of the hit, and keep going until you hit the surface of the wall on the other side (and the length of the ray is at most your weapon’s penetration depth). Origin is hit pos and direction is (hit pos - start pos).Unit * constant.

Some pseudocode:

local size = 1 
local increment = 1 -- how big your backwards ray will increase every iteration
local penetrationDepth = 5 --how far your ray is allowed to go through the wall

local origin = -- the origin of your original ray
local hitpos = --position where your original raycast hit the wall

local hit, pos 

while size < penetrationDepth do
    hit, pos = raycast(hitpos, (hitpos - origin).Unit * size) 

    if not hit then 
        size += increment 

    -- do your raycasting, if a hit is confirmed, or the size goes over the penetration depth, then this loop will break. Make sure to use deep casting (concatenating a bunch of small rays together and analyzing every hit) for the best accuracy

Then, pos would be the other side of the wall (if it makes it through. From there it’s up to you what you want to do with it, since you have the depth of the brick it went through - (pos - origPos).Magnitude, you can recalculate damage using the depth. You could even add some more detailed mechanics like changing the iteration size and speed based on the material of what it hit.

Sorry if this is formatted bad, I’m on mobile.

Edit: Yeah this is more or less the same thing @orange451 proposed. Great minds think alike