Currently facing an issue with my projectile and ranged tools system.
Problem: FPS drops significantly as I start to move and fire projectiles into the air, mainly at high distances (1 projectile per 2 second)
Is there any apparent issues in my code that could contribute to this? All my other tools that are connected to the same RE don’t reproduce this issue at all. I’ve tried to use the Microprofiler, but no luck.
Client Module Func
visualizeProjectile = function(positions)
debug.profilebegin("ClientVisualizeProjectile")
if not positions or #positions == 0 then return end
local projectile = Rep.Projectiles.Arrow:Clone()
projectile.CFrame = CFrame.lookAt(positions[1], positions[2] or positions[1] + Vector3.new(0, 0, -1))
projectile.Parent = workspace
coroutine.wrap(function()
for i = 2, #positions do
local startPos = positions[i - 1]
local endPos = positions[i]
local segmentLength = (endPos - startPos).Magnitude
local segmentTime = segmentLength / 100
local elapsed = 0
while elapsed < segmentTime do
local alpha = elapsed / segmentTime
local pos = startPos:Lerp(endPos, alpha)
projectile.CFrame = CFrame.lookAt(pos, endPos)
elapsed += task.wait()
end
projectile.CFrame = CFrame.lookAt(endPos, endPos + (endPos - startPos).Unit)
end
local pos = positions[#positions]
local lastSegment = positions[#positions] - positions[#positions - 1]
local velocity = lastSegment.Unit * 100
local gravity = workspace.Gravity
while true do
local dt = task.wait()
velocity += Vector3.new(0, -gravity * dt, 0)
local nextPos = pos + velocity * dt
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {projectile}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local rayResult = workspace:Raycast(pos, (nextPos - pos), raycastParams)
if rayResult then
print("hit")
projectile.CFrame = CFrame.lookAt(rayResult.Position, rayResult.Position + rayResult.Normal)
break
end
pos = nextPos
projectile.CFrame = CFrame.lookAt(pos, pos + velocity.Unit)
end
if projectile then
projectile:Destroy()
end
end)()
debug.profileend()
end
Rep.Events.VisualizeProjectile.OnClientEvent:Connect(function(pos)
print("sent projectile", tick())
CFB.visualizeProjectile(pos)
end)
Server Module
GU.FireProjectile = function(player)
local playerGui = player.PlayerGui:WaitForChild("Main")
local targetSlider = playerGui:WaitForChild("TargetBar")
warn("FIRING ARROW LOLZ")
local positions = Rep.Events.SendCurrentArc:InvokeClient(player)
if not positions or #positions == 0 then
warn("no arc pos 😂😂😂")
return
end
Rep.Events.VisualizeProjectile:FireAllClients(positions)
coroutine.wrap(function()
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {player.Character}
rayParams.IgnoreWater = true
local lastVelocity = Vector3.new()
for i = 2, #positions do
local startPos = positions[i - 1]
local endPos = positions[i]
local direction = (endPos - startPos).Unit
local distance = (endPos - startPos).Magnitude
lastVelocity = direction * 100 -- arc velocity
local result = workspace:Raycast(startPos, direction * distance, rayParams)
if result then
local hitModel = result.Instance:FindFirstAncestorOfClass("Model")
if hitModel and hitModel:FindFirstChild("Health") then
warn("Arrow hit", hitModel.Name)
GU.damageObject(hitModel, 5)
Rep.Events.UpdateClient:FireClient(player, "drawTargetSlider", {hitModel})
else
targetSlider.Visible = true
targetSlider.Visible = false
end
return
end
task.wait()
end
warn("freefall projectile")
local gravity = workspace.Gravity
local pos = positions[#positions]
local velocity = lastVelocity
local dt
while true do
dt = task.wait()
velocity += Vector3.new(0, -gravity * dt, 0)
local nextPos = pos + velocity * dt
local result = workspace:Raycast(pos, nextPos - pos, rayParams)
if result then
local hitModel = result.Instance:FindFirstAncestorOfClass("Model")
if hitModel and hitModel:FindFirstChild("Health") then
warn("hit", hitModel.Name)
GU.damageObject(hitModel, 5)
if hitModel:FindFirstChild("Health") and hitModel:FindFirstChild("Health").Value then
Rep.Events.UpdateClient:FireClient(player, "drawTargetSlider", {hitModel})
end
else
targetSlider.Visible = true
targetSlider.Visible = false
end
return
end
pos = nextPos
end
end)()
end