Game experiencing lag spikes overtime whenever the player jumps

this is a private game that uses skinned meshes and a custom animate script for its animations, i dont know if the way i set it up is bad but i also dont know whats causing the lag spikes

local lp = game:GetService("Players").LocalPlayer
local function setup()
	local hum = lc:WaitForChild("Humanoid")
	local anm8r = hum:WaitForChild("Animator")
	local jumpanim = script:WaitForChild('Jump')
	local fallanim = script:WaitForChild('Fall')
	local jumptrack = anm8r:LoadAnimation(jumpanim)
	local falltrack = anm8r:LoadAnimation(fallanim)
	local canmove = true

	while true do
		task.wait()
		local jumping = hum:GetState() == Enum.HumanoidStateType.Jumping
		local falling = hum:GetState() == Enum.HumanoidStateType.Freefall
		local grounded = hum:GetState() == Enum.HumanoidStateType.Landed
        local jumped = false


		if canmove then 

			hum.Jumping:Connect(function(IsJumping)
				if IsJumping then
					for _, v in pairs(hum:GetPlayingAnimationTracks()) do
						v:Stop()
					end
					jumptrack:Play()
				else
				end
			end)

			if falling then
				if not jumptrack.IsPlaying then
					jumptrack:Stop()
					falltrack:Play()
				end
			end

			if grounded then
				if falltrack.IsPlaying then
					falltrack:Stop()
				end
			end
end

lp.CharacterAdded:Connect(function(character)
	lc = character
	setup()
end)


not sure if its noticeable in the video but this is happening

There are a couple of issues with your code that could be causing lag spikes (I didn’t see them in the video).

  1. your script affects the character, but it isn’t in startercharacterscripts, which causes it to have to connect a useless connection to CharacterAdded.

  2. You are connecting a .Jumping event handler in the while loop, every heartbeat without cleaning up the old one, this is a huge memory leak. Those old handlers are still in memory and will eventually take up all of the space allocated for your game.

  3. You are using a while loop, generally you want to avoid infinite while loops, if you really need them, use RunService.Heartbeat instead. But this can theoretically be done without while loops, using Humanoid.StateChanged

Combining these, I have made this script you can use:

--Changes:
--[[
  * Moved script location to StarterCharacterScripts, this way, we can access the character using script.Parent, and 
  we do not need to add a useless connection.
  
  * fixed weird cryptic names, don't do that, you'll regret it later.
  * removed loop and replaced it with state checking
]]
local players = game:GetService "Players"
local player = players.LocalPlayer

local character = script.Parent
local humanoid = character:FindFirstChildOfClass "Humanoid"
local animator = humanoid:FindFirstChildOfClass "Animator" or Instance.new("Animator", humanoid)

local fall_track = animator:LoadAnimation(nil) --add your track
local jump_track = animator:LoadAnimation(nil) --add your track

humanoid.StateChanged:Connect(function(old: Enum.HumanoidStateType, new: Enum.HumanoidStateType)
	if new == Enum.HumanoidStateType.Jumping then
		jump_track:Play()
	elseif new == Enum.HumanoidStateType.Freefall then
--freefall is after jumping, so we can assume jumptrack is still playing
		jump_track:Stop()
		fall_track:Play()
	elseif new == Enum.HumanoidStateType.Landed then
		fall_track:Stop()
	end
end)

Hope this helps.

1 Like

The issue with this code is that you’re continuously connecting the Jump event inside a while true do loop, which can cause performance problems. Since the loop will always run, it keeps adding new connections each time, leading to memory leaks. Instead, you should connect the Jump event once and handle state changes more efficiently.

1 Like

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