Checking player movement causing massive frame drops

Hello. I am brand new to scripting in the past month and I am having troubles with a crouching animation script.

I have already created a function that will check if a player is moving, but it seems to build up lag over time. I want to figure out a way to eliminate the frame drops. I haven’t seen this anywhere else on the forum so I must be missing something silly.

I’ve tried using a coroutine and then yielding when uncrouching, but that didn’t work. I’ve also tried using RunService.Heartbeat/RenderStepped, but that made the problem worse.

Part of script that causes lag:

				spawn(function()

					while crouching == true do
						wait()
						print("Checking player movespeed")

						humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()

							if humanoid.MoveDirection.Magnitude > 0 then

								track:AdjustSpeed(0.65)

							else

								track:AdjustSpeed(0)

							end
						end)
					end
				end)

Full script:

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

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local sprintScript = character:WaitForChild("Sprint")

local crouchAnim = script.Crouch
local track = humanoid:LoadAnimation(crouchAnim)

track.Looped = true
track.Priority = Enum.AnimationPriority.Action

local crouching = false

local function checkKeyDown(input, gameProcessed)
	
	if not gameProcessed then
		
		if input.KeyCode == Enum.KeyCode.C then
			
			if not crouching then
				crouching = true
				
				sprintScript.Enabled = false
				
				if humanoid.MoveDirection.Magnitude > 0 then
					
					track:Play()
					track:AdjustSpeed(0.65)

				else
					
					track:Play()
					track:AdjustSpeed(0)

				end
				
				humanoid.WalkSpeed = 8
				
				spawn(function()

					while crouching == true do
						wait()
						print("Checking player movespeed")

						humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()

							if humanoid.MoveDirection.Magnitude > 0 then

								track:AdjustSpeed(0.65)

							else

								track:AdjustSpeed(0)

							end
						end)
					end
				end)

			elseif crouching then
				crouching = false
				sprintScript.Enabled = true

				track:Stop()
				humanoid.WalkSpeed = 16
				
			end
		end
	end
end

UserInputService.InputBegan:Connect(checkKeyDown)
1 Like

Whenever you crouch, you spawn a thread which repeatedly creates GetPropertyChangedSignal connections inside of a loop, which causes lag when there are many of them. Here is a script which solves this problem by only creating the connection once:

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

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local sprintScript = character:WaitForChild("Sprint")

local crouchAnim = script.Crouch
local track = humanoid:LoadAnimation(crouchAnim)

track.Looped = true
track.Priority = Enum.AnimationPriority.Action

local crouching = false

local function checkKeyDown(input, gameProcessed)
	
	if not gameProcessed then
		
		if input.KeyCode == Enum.KeyCode.C then
			
			if not crouching then
				crouching = true
				
				sprintScript.Enabled = false
				
				if humanoid.MoveDirection.Magnitude > 0 then
					
					track:Play()
					track:AdjustSpeed(0.65)

				else
					
					track:Play()
					track:AdjustSpeed(0)

				end
				
				humanoid.WalkSpeed = 8

			elseif crouching then
				crouching = false
				sprintScript.Enabled = true

				track:Stop()
				humanoid.WalkSpeed = 16
				
			end
		end
	end
end

humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if not crouching then return end -- ignore this signal if crouching is false
	if humanoid.MoveDirection.Magnitude > 0 then

		track:AdjustSpeed(0.65)

	else

		track:AdjustSpeed(0)

	end
end)

UserInputService.InputBegan:Connect(checkKeyDown)
1 Like

Whoops, that makes sense. No clue why I thought it had to be part of a loop. This works perfectly. Thank you!

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