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