Projectile Lag with Ranged Tools [SOLVED]

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

fixed, was unrelated to the code above

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.