Grenade clips through wall

I need to fix this annoying clipping bug with a grenade I am working on. The grenade seems to clip through walls when thrown at the lower wall. I made it so the grenade changes the color of the parts hit. The grenade tool creates a “tracer” that reflects off of surfaces until its final hit. On its final hit the tracer is deleted and replaced with a physical model of the grenade that explodes. This “tracer” system uses the FastCast module.

12:37:27.766  BottomLining  -  Client - LocalReplicationScript:1328
12:37:27.768  lowwall  -  Client - LocalReplicationScript:1328
12:37:27.769  floor  -  Client - LocalReplicationScript:1328
12:37:27.783  lowwall  -  Client - LocalReplicationScript:1328

is what was printed when throwing the grenade

local PersonalCaster = FastCast.new()
local PersonalraycastParams = RaycastParams.new()
PersonalraycastParams.FilterType = Enum.RaycastFilterType.Exclude
PersonalCasterBehavior = FastCast:newBehavior()
PersonalCasterBehavior.RaycastParams = PersonalraycastParams
PersonalCasterBehavior.CosmeticBulletContainer = TracerParent

local PersonalTracerEvente = PersonalTracerEvent.Event:Connect(function(Origin,Direction,TravelSpeed,TracerObject,BulletDrop,MaxDistance,t,aoi)
	PersonalraycastParams.FilterDescendantsInstances = {CollectionService:GetTagged("Ignore"),Character}
	PersonalCasterBehavior.CanPierceFunction = CanRayPierce
	PersonalCasterBehavior.MaxDistance = MaxDistance
	PersonalCasterBehavior.Acceleration = BulletDrop
	PersonalCasterBehavior.CosmeticBulletTemplate = TracerObject
	local cast = PersonalCaster:Fire(Origin, Direction, TravelSpeed, PersonalCasterBehavior)
	cast.MockGrenade = false
	if aoi then
		cast.ActiveOnImpact = true
	end
	Tool = t
	shareOrigin = Origin
end)


local PersonalRayHitFunction = PersonalCaster.RayHit:Connect(function(ActiveCast, raycastResult,_,cosmeticBulletObject)
	if ActiveCast.MockGrenade == false then
		local passableCFrame = cosmeticBulletObject.Hitbox.CFrame or nil
		ThrowEvent:FireServer(Tool,raycastResult.Position,shareOrigin,Character,raycastResult.Normal,passableCFrame,nil)
	end
end)

PersonalCaster.RayPierced:Connect(function(cast, raycastResult, segmentVelocity, cosmeticBulletObject)
	local position = raycastResult.Position
	local normal = raycastResult.Normal
	local raycastInstance = raycastResult.Instance	

	if not raycastInstance:HasTag("Ignore") and not raycastInstance:HasTag("GrenadeIgnore") and not raycastInstance:GetAttribute("Shatter") then
		local redH, redS, redV = raycastInstance.Color:ToHSV()
		raycastInstance.Color = Color3.fromHSV(redH,redS,redV+5)
		local newNormal = Reflect(normal, segmentVelocity.Unit)
		cast:SetPosition(position)
		if not cast.ActiveOnImpact then cast:SetVelocity(newNormal * (segmentVelocity.Magnitude/2)) end
	elseif raycastInstance:GetAttribute("Shatter") then
		BulletEvent:FireServer(Objects:WaitForChild("BulletHoles"):WaitForChild("GlassHit"),position,normal,raycastInstance)
	end
end)
	
local PersonalLengthChangedFunction = PersonalCaster.LengthChanged:Connect(function(_, lastPoint, rayDir, displacement, _, cosmeticBulletObject)
	local lengthObject = cosmeticBulletObject
	if cosmeticBulletObject:FindFirstChild("Hitbox") then
		lengthObject = cosmeticBulletObject.Hitbox
		local bulLength = cosmeticBulletObject.Hitbox.Size.Z/2
		local offset = CFrame.new(0,0,-(displacement - bulLength))
		if cosmeticBulletObject:GetAttribute("timeModification") then 
			local timeTook = displacement/180
			Debris:AddItem(cosmeticBulletObject,timeTook)
			TweenService:Create(cosmeticBulletObject.Hitbox, TweenInfo.new(timeTook, Enum.EasingStyle.Linear), {CFrame = CFrame.lookAt(lastPoint, lastPoint + rayDir):ToWorldSpace(offset)}):Play()
		else
			TweenService:Create(cosmeticBulletObject.Hitbox, TweenInfo.new(0.06, Enum.EasingStyle.Linear), {CFrame = CFrame.lookAt(lastPoint, lastPoint + rayDir):ToWorldSpace(offset)}):Play()
		end
	elseif cosmeticBulletObject:IsA("BasePart") then
		local bulLength = cosmeticBulletObject.Size.Z/2
		local offset = CFrame.new(0,0,-(displacement - bulLength))
		if cosmeticBulletObject:GetAttribute("timeModification") then 
			local timeTook = displacement/180
			Debris:AddItem(cosmeticBulletObject,timeTook)
			TweenService:Create(cosmeticBulletObject, TweenInfo.new(timeTook, Enum.EasingStyle.Linear), {CFrame = CFrame.lookAt(lastPoint, lastPoint + rayDir):ToWorldSpace(offset)}):Play()
		else
			TweenService:Create(cosmeticBulletObject, TweenInfo.new(0.06, Enum.EasingStyle.Linear), {CFrame = CFrame.lookAt(lastPoint, lastPoint + rayDir):ToWorldSpace(offset)}):Play()
		end
	end
end)
local PersonalCastTerminatingFunction = PersonalCaster.CastTerminating:Connect(function(cast)
	local cosmeticBulletToDestroy = cast.RayInfo.CosmeticBulletObject
	if not cosmeticBulletToDestroy:GetAttribute("timeModification") then cosmeticBulletToDestroy:Destroy() end
end)

is my code for this.

Sometimes it works like this instance

I’ve asked some of my development team on if they could figure it out and we haven’t figured out a solution for this. Any help would be very appreciated

3 Likes

have you tried to add a collision block on the grenade?

2 Likes

yes, I made the Hitbox of the grenade tracer CanCollide true and it still has the problem of clipping through the wall

2 Likes

I cpuldnt really read and understand your code, becuase im too lazy, but make sure that you have collisions on the wall and grenade. It might just be roblox’s poor physics system.

2 Likes

both the collision on the wall and grenade are active. When it does work the fast cast module reflects the grenade off surfaces when RayPierced

3 Likes


reflecting does work most of the time, just not all of the time. Specifically when aiming at the lower part of the wall

1 Like

Are you using a script to make the bounce physics or actual roblox physics. If you arent
using roblox physics, it might be unreliable. Try to test it out with a thicker wall.

1 Like