Walk speed ramp up

I want to make a sort of system where when you start walking you start off slow, and then your walk speed gets higher the more you walk until it reaches a number like 16 where it stops ramping it up. I know you can use Humanoid.Running to detect if they’re walking, but how would I make it ramp up your walk speed the more you walk? Can someone give me an example?

7 Likes

Sure, luckily the hard work was done by @ThanksRoBama in smoother characters.

This method uses Humanoid:Move() and lerping the direction vector from magnitude 0 to 1 where 0 is no speed and 1 is the humanoid WalkSpeed.

Keep in mind this is just one method and ofc not the best method. What matters is the method of using Humanoid:Move() to maintain the default humanoid movement system and such.

--Localscript in starter player scripts
local RunS = game:GetService("RunService")
local InputS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local character = player.Character or player.CharacterAdded:Wait()

player.CharacterAdded:Connect(function(_character)
	character = _character
end)

local walkKeyBinds = {
	Forward = { Key = Enum.KeyCode.W, Direction = Enum.NormalId.Front },
	Backward = { Key = Enum.KeyCode.S, Direction = Enum.NormalId.Back },
	Left = { Key = Enum.KeyCode.A, Direction = Enum.NormalId.Left },
	Right = { Key = Enum.KeyCode.D, Direction = Enum.NormalId.Right }
}

local function getWalkDirectionCameraSpace()
	local walkDir = Vector3.new()

	for keyBindName, keyBind in pairs(walkKeyBinds) do
		if InputS:IsKeyDown(keyBind.Key) then
			walkDir += Vector3.FromNormalId( keyBind.Direction )
		end
	end

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end

	return walkDir
end

local function getWalkDirectionWorldSpace()
	local walkDir = camera.CFrame:VectorToWorldSpace( getWalkDirectionCameraSpace() )
	walkDir *= Vector3.new(1, 0, 1) --Set Y axis to 0

	if walkDir.Magnitude > 0 then --(0, 0, 0).Unit = NaN, do not want
		walkDir = walkDir.Unit --Normalize, because we (probably) changed an Axis so it's no longer a unit vector
	end

	return walkDir
end

local function lerp(a, b, c)
	return a + ((b - a) * c)
end

local targetMoveVelocity = Vector3.new()
local moveVelocity = Vector3.new()
local moveAcceleration = 1

local function updateMovement( dt )
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.WalkSpeed = 50

		local moveDir = getWalkDirectionWorldSpace()
		targetMoveVelocity = moveDir
		moveVelocity = lerp( moveVelocity, targetMoveVelocity, math.clamp(dt * moveAcceleration, 0, 1) )
		humanoid:Move( moveVelocity )
	end
end	

RunS.RenderStepped:Connect(updateMovement)
3 Likes

You can make a part where certain areas you can lose and get speed

-- Set a variable for boosted speed power
local SPEEED_POWER = 200
local function speed(otherPart)
    local partParent = otherPart.Parent
    local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
        local currentSpeed = humanoid.WalkSpeed
        if currentSpeed < SPEEED_POWER then
            humanoid.WalkSpeed = SPEEED_POWER
            wait(10)
            humanoid.WalkSpeed = currentSpeed
         end
    end
speedPart.Touched:Connect(speed)
1 Like

No, I want it so that the more you walk the faster you go, not by touching something you get faster, by walking it’ll slowly ramp up your walk speed until it reaches a certain value.

1 Like

I’d collect the stats somewhere, like a leaderboard. Start it off at the walkspeed you want (16 speed). Then for each step you give leaderboard + 1 and a script where your walkspeed is = to the leaderstats.

1 Like

How do I detect each step? All I know is that the Humanoid.Running function runs every time the player moves or stops.

1 Like

To detect each step, I suggest taking a look at this topic:

From there you can just set the humanoid walkspeed += 1

Also, if you want it to reset when the player stops, just use this snippet of code:

Humanoid:GetPropertyChangedSignal(“MoveDirection”):Connect(function()
    if Humanoid.MoveDirection.Magnitude <= 0 then
        Humanoid.WalkSpeed = 16
    end
end)

Hope you find this useful :slight_smile:

I tested this and it worked:

local players = game:GetService("Players")
local initialSpeed = 0.2 -- How fast should the player go when he joins
local maxSpeed = 16 -- What should the maximum speed be
local increment = 1 -- How much should get added to the speed every x seconds
local speedDelay = 5 -- How fast does the speed get added to the player's speed

players.PlayerAdded:Connect(function(playerInstance)
	playerInstance.CharacterAdded:Connect(function(playerCharacter)
		local humanoid = playerCharacter:FindFirstChild("Humanoid")
		humanoid.WalkSpeed = initialSpeed
		while humanoid and humanoid.WalkSpeed ~= maxSpeed do
			if humanoid.MoveDirection.X > 0 or humanoid.MoveDirection.Y > 0 or humanoid.MoveDirection.Z > 0 or humanoid.MoveDirection.X < 0 or humanoid.MoveDirection.Y < 0 or humanoid.MoveDirection.Z < 0 then
				if humanoid.WalkSpeed < maxSpeed then
					humanoid.WalkSpeed = humanoid.WalkSpeed + increment
				end
			end
			task.wait(speedDelay)
		end
	end)
end)

Make sure to put it inside a Script in ServerScriptService.

Mark this as the solution if it helped with your issue!

6 Likes

Terribly sorry, I forgot about this post I made LOL, thanks for your help it helped me after changing a bit of stuff so I could tween it instead.

1 Like