(Fastcast) Issues with Ricocheting Bullets

Hello Again!, I’m Trying to add a Mechanic in which the bullet would Ricochet off of a certain angle in a part, But it would Often go through The part and go through the Parts that was behind it.

Here’s it in Action
https://streamable.com/0sbzs1

Here’s What i mean.

i have tried by offsetting the Position a little bit
cast:SetPosition(Position + NewNormal * 0.01)

but the issue still remains

local function Reflect(surfaceNormal, bulletNormal)
	return bulletNormal - (2 * bulletNormal:Dot(surfaceNormal) * surfaceNormal)
end

local function canraypierce(cast, raycastResult: RaycastResult, segmentVelocity, bullet)
	local Angle = math.deg(math.acos(segmentVelocity.Unit:Dot(raycastResult.Normal)))

	if cast.UserData.Bounces > 1 then
		return false
	end
	
	local Mat = nil
	
	if AnglesMT[raycastResult.Material.Name] then
		Mat = AnglesMT[raycastResult.Material.Name]
	else
		Mat = AnglesMT.Default
	end
	
	if Mat then
		if Angle <= Mat.AngleToRicho then

			cast.UserData["Bounces"] += 1

			local Position = raycastResult.Position
			local NewNormal = Reflect(raycastResult.Normal, segmentVelocity.Unit)
            --From the thread i found
			cast:SetVelocity(NewNormal * segmentVelocity.Magnitude * Mat.BulletSpeed)
			cast:SetPosition(Position + NewNormal * 0.01)

			return true
		else
			return false
		end
	end
	
	return false
end

Thanks in Advance.

1 Like

Your code handling the setting of velocity and position should be on the OnRayPierced function. The canpierce function’s job is simply to tell fastcast whether to fire OnRayHit or OnRayPierced on a ray collision (through returning true or false).

1 Like

Hey!, i tried doing what you said by placing the code that changes the velocity and position in the OnRayPierced but its still the same. i tried changing the bullet’s velocity and it sort of worked and it doesn’t go through the parts that often.

1 Like

You might just be having the bullets move too quickly.

Alternatively, make the CanPierceFunction just always return true and see if reflections are still inconsistent then.

2 Likes

Hey, It seems that the reflections are still inconsistent, i tried just by changing the weapon velocity to the point where it could barley be noticed but the bullet would be very slow and unrealistic and i’ve run out of solutions i could think, so all i did was just fire another caster from the NewNormal


local function Reflect(surfaceNormal, bulletNormal)
	return bulletNormal - (2 * bulletNormal:Dot(surfaceNormal) * surfaceNormal)
end


caster.RayHit:Connect(function(cast, raycastResult, segmentVelocity, cosmeticBulletObject)
		
		local Angle = math.deg(math.acos(segmentVelocity.Unit:Dot(raycastResult.Normal)))
		local Mat = nil

		if AnglesMT[raycastResult.Material.Name] then
			Mat = AnglesMT[raycastResult.Material.Name]
		else
			Mat = AnglesMT.Default
		end

		if cast.UserData["Bounced"] then
			print("bullet bounced before")
		else
			if Mat then
				if Angle <= Mat.AngleToRicho then
					local Position = raycastResult.Position
					local NewNormal = Reflect(raycastResult.Normal, segmentVelocity.Unit)
					local Direction = NewNormal
					

					local NewCast= caster:Fire(Position + Direction * 0.01, Direction, 600, behaviour)
					NewCast.UserData["Bounced"] = true
					NewCast:SetVelocity(NewNormal * segmentVelocity.Magnitude * Mat.BulletSpeed)
					NewCast:AddAcceleration(Vector3.new(-100,-400,0))
					NewCast:SetPosition(Position + NewNormal * 0.01)
				end
			end
		end
		
	end)
	

i know there could be a way better solution than this. but this is all i could think of as i’m bad at math

2 Likes

Have you tried seeing if it’s still inconsistent with thicker walls? If so, you’re just making the bullets wayy too fast