Gem collection system makes game very laggy

  1. What do you want to achieve? Keep it simple and clear!
    I currently have a system where a bunch of parts with BillboardGuis on them spawn in every few seconds. (Temporary system, in the final game this will happen when you break ores.)
    They have a big invisble sphere welded to them, and a springcontraint that gets attached to the player when you touch the sphere. I think the problem stems from the .Touched events that are used for every part, because before implementing the system it wasn’t laggy at all.

I’m not sure how i could make this laggy, or if running .Touched events through the players character would make it lag less. I would appreciate some pointers in how to fix the lag. Maybe checking the distance from the player through .Magnitude would make it better? Or maybe i should ditch the whole springcontraint system and just try lerping instead? I’m new to developing so i’m not sure what would work best here.

My scripts:

Spawner Localscript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DropGem = require(ReplicatedStorage:WaitForChild("DropCurrency"))

while true do
	for i=1, 50 do
		DropGem.DropCurrency(workspace.Location.CFrame, ReplicatedStorage.GemDrop, 1)
		task.wait(0.05)
	end
	
	task.wait(4)
end

“DropCurrency” ModuleScript

local Drop = {}

local function setThing (clonedObject)
	task.wait(2)
	clonedObject.SpringConstraint.Attachment1 = workspace.Tester.TestAttach
	clonedObject:Destroy()
end

function Drop.DropCurrency(originCFrame, object, amount)
	for i=0, amount do
		local clonedObject = object:Clone()
		clonedObject.Name = "Drop" .. i
		clonedObject.CFrame = originCFrame
		clonedObject.Parent = workspace
		
		local randomX = {math.random(-10, 5), math.random(5, 10)}
		local randomZ = {math.random(-10, 5), math.random(5, 10)}
		
		local velocity = Vector3.new(randomX[math.random(1,2)], math.random(60,80), randomZ[math.random(1,2)])
		
		clonedObject.AssemblyLinearVelocity = velocity
		
		local thing = coroutine.create(function()
			
			local touchedByPlayer = false

			clonedObject.Hitbox.Touched:Connect(function(hit)
				if hit.Parent then
					if hit.Parent:FindFirstChild("Humanoid") then
						clonedObject.SpringConstraint.Attachment1 = hit.Parent.HumanoidRootPart.PlayerAttachment
						touchedByPlayer = true
						return
					end
				end
			end)

			clonedObject.Touched:Connect(function(hit)
				if touchedByPlayer then
					if hit.Parent then
						if hit.Parent:FindFirstChild("Humanoid") then
							print("Collected gem!")
							clonedObject:Destroy()
							return
						end
					end
				end
			end)
		end)
		
		coroutine.resume(thing)
			
	end
end

return Drop

ServerScript for fixing CollisionGroups and inserting the attachment into the player (kinda irrelevant):

local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")

PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:CollisionGroupSetCollidable("Characters", "Characters", false)

local function onDescendantAdded(descendant)
	-- Set collision group for any part descendant
	if descendant:IsA("BasePart") then
		descendant.CollisionGroup = "Players"
	end
end

local function onCharacterAdded(character)
	-- Process existing and new descendants for physics setup
	local playerAttachment = Instance.new("Attachment", character.HumanoidRootPart)
	playerAttachment.Name = "PlayerAttachment"

	for _, descendant in pairs(character:GetDescendants()) do
		onDescendantAdded(descendant)
	end
	character.DescendantAdded:Connect(onDescendantAdded)
end

Players.PlayerAdded:Connect(function(player)
	-- Detect when the player's character is added
	player.CharacterAdded:Connect(onCharacterAdded)
end)

Like i said, any small help from experienced devs would help, thanks.

Maybe for the sphere event use:

if hit.Parent and not touchedByPlayer then

Or use :once() instead of :connect()

I like the approach with the spring.

I don’t think you need a coroutine to connect events.

aight nvm i just used .Magnitude and :Lerp in a different script which checks the distance of all the drops. its much more preformant now

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