Stutter when destroying a local part

Hi, I’m making a game but I have a stutter problem, when i kill a mob it drops some yen, then if the player is in drop’s range it will move to the player and when touched it will be destroyed. The problem is, every time i destroy it my game stutters and that’s really annoying. I even tried to change drops position to -450 and see if the game destroys it because of the height but nothing happens. Also if i let the debris destroy it, it also stutters the game. Also tried to not create the align position to see if it was the problem but still nothing, i have no idea on how to fix that. Would appreciate some help or tips.

This is a local script

local players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")

local plr = players.LocalPlayer

local mobsTable = require(rs.Modules.Mobs)
local remoteEvents = rs:WaitForChild("RemoteEvents")
local dropYenEvent = remoteEvents:WaitForChild("DropYen")
local dropTouchEvent = remoteEvents:WaitForChild("DropTouch")

local function dropYen(mob, plrDmg)
	if mob ~= nil then
		if ((100/plrDmg.Value) * mobsTable[mob.Name].MaxHP) >= 10  then
			local char = plr.Character or plr.CharacterAdded:Wait()

			local drops = nil
			if mob.Stats.EnemyType.Value == "Normal" then
				drops = math.random(5,10)
			elseif mob.Stats.EnemyType.Value == "Boss" then
				drops = math.random(1,5)
			end

			for i=1, drops, 1 do
				local moveDropCoroutine = nil
				local touchDropCoroutine = nil
				local drop = rs.YenDrop:Clone()
				drop.Position = mob.HumanoidRootPart.Position
				drop.Parent = workspace.PlayerDrops
				Debris:AddItem(drop,180)

				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(10,30), randomZ[math.random(1,2)])

				drop.AssemblyLinearVelocity = velocity

				local attachment = Instance.new("Attachment")
				attachment.Parent = drop

				local attachDrop = char.HumanoidRootPart:FindFirstChild("AttachDrop")

				if not attachDrop then
					attachDrop = Instance.new("Attachment")
					attachDrop.Name = "AttachDrop"
					attachDrop.Parent = char.HumanoidRootPart
				end

				local alignPosition = Instance.new("AlignPosition")
				alignPosition.Attachment0 = attachment
				alignPosition.Attachment1 = attachDrop
				alignPosition.MaxForce = 0
				alignPosition.Responsiveness = 50
				alignPosition.Parent = drop

				local function moveDrop()
					task.wait(1)
					while true do
						local target = char.HumanoidRootPart.Position
						local distance = (target - drop.Position).Magnitude
						if distance <= 8 then
							alignPosition.MaxForce = 500
							drop.CanCollide = false
							break
						end
						task.wait(0.05)
					end
				end

				local function touchDrop()
					task.wait(1)
					drop.Touched:Connect(function(touch)
						local plr = players:FindFirstChild(touch.Parent.Name)
						if plr then
							dropTouchEvent:FireServer(plrDmg.Value, mob)
							coroutine.close(moveDropCoroutine)
--							drop.Position = Vector3.new(char.HumanoidRootPart.Position.X, -450,char.HumanoidRootPart.Position.Z)
							drop:Destroy()
						end
					end)
				end

				moveDropCoroutine = coroutine.create(moveDrop)
				touchDropCoroutine = coroutine.create(touchDrop)

				coroutine.resume(moveDropCoroutine)
				coroutine.resume(touchDropCoroutine)
			end
		end
	end
end


dropYenEvent.OnClientEvent:Connect(dropYen)

I think its because the touched event in each yen, when a Character made of many parts fires it, the touched event fires multiple times per yen, you could only check if the touch part is equal to a HumanoidRootPart or use a debounce if the Player was found from the first part touched (example an arm,foot, etc) in order to not repeat the touched function again if the player was already found:

Debounce

local debounce = true
drop.Touched:Connect(function(touch)
	if debounce then
		local plr = game.Players:GetPlayerFromCharacter(touch.Parent)
		if plr then
			debounce = false
			dropTouchEvent:FireServer(plrDmg.Value, mob)
			coroutine.close(moveDropCoroutine)
			drop:Destroy()
		end
	end
end)

HRP check

drop.Touched:Connect(function(touch)
	if touch.Name == "HumanoidRootPart" then
		local plr = game.Players:GetPlayerFromCharacter(touch.Parent)
		if plr then
			dropTouchEvent:FireServer(plrDmg.Value, mob)
			coroutine.close(moveDropCoroutine)
			drop:Destroy()
		end
	end
end)

Unfortunately, it also doesn’t work, but it’s not a big deal. I’ll rework the drop system. Thx for your help

1 Like