Sprint System Help

  1. What do you want to achieve? Keep it simple and clear!
    I’m trying to achieve a sprint system, similar to other games found on roblox, like Track & Field Infinite, Prilda’s track and field, etc. The system is simple, pressing Q or E increases your speed, pressing them fast almost simultaneously increases your speed.

  2. What is the issue? Include screenshots / videos if possible!
    Whenever I click fast, my speed always gets stuck in the 69-71 speed range, which is confusing. I know there are people who are faster than me at clicking Q and E, so if anyone better than me wants to try sprint, they’ll be stuck on the same speed as each other. It’s also not great knowing there’s a cap to the speed you want to go at. (the green text is my speed.)

https://medal.tv/games/roblox-studio/clips/msh4kLwP4AbVc_nbq?invite=cr-MSxLeHgsNDE2MzM4Njk4&v=8

  1. What solutions have you tried so far? Did you look for solutions on the Creator Hub?
    I’ve tried using a macro to emulate clicking very fast, but i still get stuck at 69-71.
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")

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.Q and not gameProcessed then
		humanoid.WalkSpeed = humanoid.WalkSpeed + 5
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.Q and not gameProcessed then
		humanoid.WalkSpeed = humanoid.WalkSpeed - 2.35
		task.wait(1.14)
		humanoid.WalkSpeed = humanoid.WalkSpeed - 2.65
	end
end)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.E and not gameProcessed then
		humanoid.WalkSpeed = humanoid.WalkSpeed + 5
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.E and not gameProcessed then
		humanoid.WalkSpeed = humanoid.WalkSpeed - 2.35
		task.wait(1.14)
		humanoid.WalkSpeed = humanoid.WalkSpeed - 2.65
	end
end)
1 Like

Your deceleration is stacking up and fighting against you. Every time you release Q or E it fires two separate speed reductions, and since task.wait is async they all pile up in the background. When you’re clicking fast you’ve got like 10 pending -2.65 deductions queued that all land at roughly the same time and tank your speed back down, which is why you’re hitting that 69-71 wall no matter how fast you click.

The cleaner approach is to not touch speed on key release at all, just let a single loop handle the decay based on how recently a key was pressed:

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

local Humanoid = Players.LocalPlayer.Character:WaitForChild("Humanoid")

local LastPress = 0
local BaseSpeed = 16
local MaxSpeed = 150
local DecayRate = 5

UserInputService.InputBegan:Connect(function(Input, Processed)
	if Processed then return end
	if Input.KeyCode ~= Enum.KeyCode.Q and Input.KeyCode ~= Enum.KeyCode.E then return end

	LastPress = tick()
	Humanoid.WalkSpeed = math.min(Humanoid.WalkSpeed + 5, MaxSpeed)
end)

task.spawn(function()
	while true do
		task.wait(0.1)
		if tick() - LastPress > 0.3 then
			Humanoid.WalkSpeed = math.max(Humanoid.WalkSpeed - DecayRate, BaseSpeed)
		end
	end
end)

Now speed only decays when you stop pressing, and there’s nothing stacking in the background. You can tune DecayRate and the 0.3 idle threshold to feel however you want. The MaxSpeed cap is there too so you can actually control the ceiling instead of it being some weird emergent number like 71.

2 Likes

the task.wait(1.14) function piles up the humanoid walkspeed deduction lines and task.wait() function cannot be changed dynamically because each time an event fires it creates a new thread running asynchronously and the task function is in there so it does not care