Struggling to boost the speed of the player with a running script

Okay so i wanna make my own speed boost system like the “octane” one, but im facing an issue. Firstly, theres a RemoteEvent in the tool linking the local script that plays the anim with the server script that should give the speed boost

I got a running script thats working well, when the player walks forward his walk speed will increase to a max speed of 50, and i have a tool that i supposed to give a +75% speed boost when used. On a test world with no runnin script its working pretty fine, but on the one with the script, it’s struggling since the effect only works with the speed the player had when using the tool, since the walkspeed wasnt meant to increase or dicrease, how can i adapt my code?

I thought about making a value inside of starter character to enable it when the RemoteEvent is fired but it didnt seem to work

Tool’s Serverscript:

local tool = script.Parent
local injectEvent = tool:WaitForChild("InjectEvent")
local POEvent = tool:WaitForChild("PullOutEvent")

local isBoosted = false

injectEvent.OnServerEvent:Connect(function(player)
	local character = player.Character
	if not character then return end

	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	local defaultSpeed = humanoid.WalkSpeed
	local boostedSpeed = defaultSpeed * 1.75
	
	if not isBoosted then
		humanoid.WalkSpeed = boostedSpeed
		isBoosted = true
	end
	

	local duration = 20
	local damagePerSecond = 10
	local timer = 0
	
	local runService = game:GetService("RunService")
	local connection
	
	connection = runService.Heartbeat:Connect(function(dt)
		timer += dt
		if timer >= 1 then
			timer = 0
			if humanoid.Health > damagePerSecond then
				humanoid:TakeDamage(damagePerSecond)
			else
				humanoid.Health = 0
				connection:Disconnect()
			end
			duration -= 1
			if duration <= 0 then
				connection:Disconnect()
				humanoid.WalkSpeed = defaultSpeed
				isBoosted = false
			end
		end
	end)
	
	POEvent.OnServerEvent:Connect(function(player)
		connection:Disconnect()
		humanoid.WalkSpeed = defaultSpeed
		isBoosted = false
	end)
end)

POEvent.OnServerEvent:Connect(function(player)
	local character = player.Character
	if not character then return end

	local humanoid = character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	humanoid.WalkSpeed = 16
end)

Now the running script :

local UIS = game:GetService('UserInputService')
local Player = game.Players.LocalPlayer
local Character = Player.Character

local maxSpeed = 50 -- The maximum speed you want to reach
local maxJump = 20 -- The maximum speed you want to reach
local acceleration = 0.08 -- The rate at which the speed increases

local currentSpeed = 13
local currentJump = 30
local currentAnimSpeed = 0.4
local isAccelerating = false
local isRunning = false

local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / maxSpeed -- Adjust playback speed initially

local function increaseSpeed()
	if currentSpeed < maxSpeed then
		currentSpeed = currentSpeed + acceleration
		currentAnimSpeed = currentAnimSpeed + (acceleration / maxSpeed)
	else
		currentSpeed = maxSpeed
		currentAnimSpeed = 1.1
		isAccelerating = false
	end

	Character.Humanoid.WalkSpeed = currentSpeed
	Character.Humanoid.JumpPower = currentSpeed * 1.18 -- Increase jump power with speed
	PlayAnim:AdjustSpeed(currentAnimSpeed)
	runSound.PlaybackSpeed = currentSpeed / maxSpeed -- Adjust playback speed based on current speed
end

local function increaseJump()
	if currentJump < maxJump then
		currentJump = currentJump + acceleration
	else
		currentJump = maxJump
		currentAnimSpeed = 1.1
		isAccelerating = false
	end

	Character.Humanoid.JumpPower = currentJump
end

function ToggleAnimationAndSound(shouldPlay)
	if shouldPlay then
		if not PlayAnim.IsPlaying then
			PlayAnim:Play()
		end
		if not runSound.IsPlaying then
			runSound:Play()
		end
	else
		PlayAnim:Stop()
		runSound:Stop()
	end
end

local leftControlDown = false

UIS.InputBegan:Connect(function(Key,IsTyping)
	if IsTyping then return end
	if Key.KeyCode == Enum.KeyCode.W then
		isRunning = true
		isAccelerating = true
		local Anim = script.SprintAnim
		PlayAnim = Character.Humanoid:LoadAnimation(Anim)
		ToggleAnimationAndSound(true)
		print('Running')
	elseif IsTyping.KeyCode == Enum.KeyCode.LeftControl then
		leftControlDown = true
	end
end)

UIS.InputEnded:Connect(function(Key,IsTyping)
	if IsTyping then return end
	if Key.KeyCode == Enum.KeyCode.W then
		Character.Humanoid.WalkSpeed = 13
		Character.Humanoid.JumpPower = 30
		ToggleAnimationAndSound(false)
		currentSpeed = 13
		currentAnimSpeed = 0.4
		isAccelerating = false
		isRunning = false
		print('Running stopped')
	elseif Key.KeyCode == Enum.KeyCode.LeftControl then
		leftControlDown = false
	end
end)

function ToggleRunningIfAirborne()
	if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
		ToggleAnimationAndSound(false)
	elseif isRunning then
		ToggleAnimationAndSound(true)
	end
end

game:GetService('RunService').Heartbeat:Connect(function()
	ToggleRunningIfAirborne()
	if isAccelerating then
		increaseSpeed()
	end
end)

please help ive struggled on this for too much time lol

1 Like

Hi there! I’ve been working on my very own AI model for a few months as a personal project and I’d like to test it out and see if it provides helpful coding solutions. The following text after this has been made by my AI model so any feedback on it would be helpful!

The issue occurs because your speed boost applies a one-time increase while the running script keeps modifying speed independently. Here’s the fixed version with both complete scripts.

Tool Script (Server-Side):

local tool = script.Parent
local injectEvent = tool:WaitForChild("InjectEvent")
local POEvent = tool:WaitForChild("PullOutEvent")

injectEvent.OnServerEvent:Connect(function(player)
    local character = player.Character
    if not character then return end

    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if not humanoid then return end
    
    local boostValue = character:FindFirstChild("IsSpeedBoosted")
    if not boostValue then
        boostValue = Instance.new("BoolValue")
        boostValue.Name = "IsSpeedBoosted"
        boostValue.Parent = character
    end
    
    if not boostValue.Value then
        boostValue.Value = true
        
        local duration = 20
        local damagePerSecond = 10
        local timer = 0
        
        local runService = game:GetService("RunService")
        local connection
        
        connection = runService.Heartbeat:Connect(function(dt)
            timer += dt
            if timer >= 1 then
                timer = 0
                if humanoid.Health > damagePerSecond then
                    humanoid:TakeDamage(damagePerSecond)
                else
                    humanoid.Health = 0
                    connection:Disconnect()
                    boostValue.Value = false
                end
                duration -= 1
                if duration <= 0 then
                    connection:Disconnect()
                    boostValue.Value = false
                end
            end
        end)
        
        POEvent.OnServerEvent:Connect(function(player)
            if connection then connection:Disconnect() end
            boostValue.Value = false
        end)
    end
end)

POEvent.OnServerEvent:Connect(function(player)
    local character = player.Character
    if not character then return end

    local boostValue = character:FindFirstChild("IsSpeedBoosted")
    if boostValue then
        boostValue.Value = false
    end
end)

Running Script (LocalScript):

local UIS = game:GetService('UserInputService')
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local maxSpeed = 50
local maxJump = 20 
local acceleration = 0.08

local currentSpeed = 13
local currentJump = 30
local currentAnimSpeed = 0.4
local isAccelerating = false
local isRunning = false

local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / maxSpeed

local function getFinalSpeed(baseSpeed)
    local boostValue = Character:FindFirstChild("IsSpeedBoosted")
    if boostValue and boostValue.Value then
        return baseSpeed * 1.75
    end
    return baseSpeed
end

local function increaseSpeed()
    if currentSpeed < maxSpeed then
        currentSpeed = currentSpeed + acceleration
        currentAnimSpeed = currentAnimSpeed + (acceleration / maxSpeed)
    else
        currentSpeed = maxSpeed
        currentAnimSpeed = 1.1
        isAccelerating = false
    end

    Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
    Character.Humanoid.JumpPower = getFinalSpeed(currentSpeed) * 1.18
    if PlayAnim then
        PlayAnim:AdjustSpeed(currentAnimSpeed)
    end
    runSound.PlaybackSpeed = currentSpeed / maxSpeed
end

local function increaseJump()
    if currentJump < maxJump then
        currentJump = currentJump + acceleration
    else
        currentJump = maxJump
        currentAnimSpeed = 1.1
        isAccelerating = false
    end

    Character.Humanoid.JumpPower = currentJump
end

function ToggleAnimationAndSound(shouldPlay)
    if shouldPlay then
        if not PlayAnim.IsPlaying then
            PlayAnim:Play()
        end
        if not runSound.IsPlaying then
            runSound:Play()
        end
    else
        PlayAnim:Stop()
        runSound:Stop()
    end
end

local leftControlDown = false

UIS.InputBegan:Connect(function(Key,IsTyping)
    if IsTyping then return end
    if Key.KeyCode == Enum.KeyCode.W then
        isRunning = true
        isAccelerating = true
        local Anim = script.SprintAnim
        PlayAnim = Character.Humanoid:LoadAnimation(Anim)
        ToggleAnimationAndSound(true)
        print('Running')
    elseif IsTyping.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = true
    end
end)

UIS.InputEnded:Connect(function(Key,IsTyping)
    if IsTyping then return end
    if Key.KeyCode == Enum.KeyCode.W then
        Character.Humanoid.WalkSpeed = 13
        Character.Humanoid.JumpPower = 30
        ToggleAnimationAndSound(false)
        currentSpeed = 13
        currentAnimSpeed = 0.4
        isAccelerating = false
        isRunning = false
        print('Running stopped')
    elseif Key.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = false
    end
end)

function ToggleRunningIfAirborne()
    if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
        ToggleAnimationAndSound(false)
    elseif isRunning then
        ToggleAnimationAndSound(true)
    end
end

game:GetService('RunService').Heartbeat:Connect(function()
    ToggleRunningIfAirborne()
    if isAccelerating then
        increaseSpeed()
    end
end)

The fix makes the boost work as a multiplier that applies to whatever speed you’re currently at. Let me know if you need any adjustments.

1 Like

tysm it works, ur a life saver man :smiley: ill just bother you with one last request, id like to make the boost go off when the effect is done, do u think that just divide the speed boost back would work?

2 Likes

oh and i got a small issue too, whenever the normal speed limit is reached (50 in my case) the effect doesnt work, its only working when the walk speed is increasing or dicreasing (it doenst work when walking backward too). Like you can reach the limit while boosted but cant use the effect if ur already running at full speed

1 Like

Alright, I’ve thought about ways to approach this problem and the following script is the best I could come up with. The Tool Script is unchanged since I think there isn’t anything wrong with it.

Running Script (Localscript)

local UIS = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local maxSpeed = 50
local maxJump = 20
local acceleration = 0.08
local deceleration = 0.15

local currentSpeed = 16
local currentJump = 30
local currentAnimSpeed = 0.4
local isAccelerating = false
local isRunning = false
local leftControlDown = false

local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / maxSpeed
local Anim = script:WaitForChild("SprintAnim")
local PlayAnim = Character.Humanoid:LoadAnimation(Anim)

local movementKeys = {
    [Enum.KeyCode.W] = true,
    [Enum.KeyCode.A] = true,
    [Enum.KeyCode.S] = true,
    [Enum.KeyCode.D] = true
}

local function getFinalSpeed(baseSpeed)
    local boostValue = Character:FindFirstChild("IsSpeedBoosted")
    return (boostValue and boostValue.Value) and (baseSpeed * 1.75) or baseSpeed
end

local function increaseSpeed()
    if currentSpeed < maxSpeed then
        currentSpeed = currentSpeed + acceleration
        currentAnimSpeed = currentAnimSpeed + (acceleration / maxSpeed)
    else
        currentSpeed = maxSpeed
        currentAnimSpeed = 1.1
    end
    Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
    runSound.PlaybackSpeed = currentSpeed / maxSpeed
end

local function increaseJump()
    if currentJump < maxJump then
        currentJump = currentJump + acceleration
    else
        currentJump = maxJump
    end
    Character.Humanoid.JumpPower = getFinalSpeed(currentJump) * 1.18
end

function ToggleAnimationAndSound(shouldPlay)
    if shouldPlay then
        if not PlayAnim.IsPlaying then PlayAnim:Play() end
        if not runSound.IsPlaying then runSound:Play() end
        PlayAnim:AdjustSpeed(currentAnimSpeed)
    else
        PlayAnim:Stop()
        runSound:Stop()
    end
end

function ToggleRunningIfAirborne()
    if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
        ToggleAnimationAndSound(false)
    elseif isRunning then
        ToggleAnimationAndSound(true)
    end
end

UIS.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        isRunning = true
        isAccelerating = true
        ToggleAnimationAndSound(true)
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = true
    elseif movementKeys[input.KeyCode] then
        isRunning = true
        isAccelerating = true
    end
end)

UIS.InputEnded:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        if not (UIS:IsKeyDown(Enum.KeyCode.A) or 
                UIS:IsKeyDown(Enum.KeyCode.S) or 
                UIS:IsKeyDown(Enum.KeyCode.D)) then
            isRunning = false
            isAccelerating = false
            currentSpeed = 16
            currentAnimSpeed = 0.4
            Character.Humanoid.WalkSpeed = 16
            ToggleAnimationAndSound(false)
        end
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = false
    elseif movementKeys[input.KeyCode] then
        local anyKeyPressed = false
        for key in pairs(movementKeys) do
            if UIS:IsKeyDown(key) then
                anyKeyPressed = true
                break
            end
        end
        if not anyKeyPressed then
            isRunning = false
            isAccelerating = false
        end
    end
end)

RunService.Heartbeat:Connect(function()
    ToggleRunningIfAirborne()
    
    if isAccelerating then
        increaseSpeed()
        increaseJump()
    else
        if currentSpeed > 16 then
            currentSpeed = math.max(currentSpeed - deceleration, 16)
            currentAnimSpeed = math.max(currentAnimSpeed - (deceleration/maxSpeed), 0.4)
            Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
            runSound.PlaybackSpeed = currentSpeed / maxSpeed
        end
    end
end)

Let me know how it goes, and if it does not work then I will find ways to re-modify the code!

1 Like

it works thanks a lot :slight_smile:

2 Likes

No problem! If there’s anything else you need, you may message me and I’ll see what I can do. Enjoy the rest of your day / night!

2 Likes

ahah never mind theres another problem, when i run using A S or D, the running anim still plays even if i stopped walking, maybe its because the base system only allowed you to run when using the W keybind and made you walk with the other movements key

1 Like

This following script aims to separately detect when the player is moving forward. The Tool Script remains unchanged, and it is just the Running Script that needs to be modified.

Running Script (Localscript)

local UIS = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local maxSpeed = 50
local maxJump = 20
local acceleration = 0.08
local deceleration = 0.15

local currentSpeed = 16
local currentJump = 30
local currentAnimSpeed = 0.4
local isMovingForward = false
local isMoving = false
local leftControlDown = false

local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / maxSpeed
local Anim = script:WaitForChild("SprintAnim")
local PlayAnim = Character.Humanoid:LoadAnimation(Anim)

local movementKeys = {
    [Enum.KeyCode.W] = true,
    [Enum.KeyCode.A] = true,
    [Enum.KeyCode.S] = true,
    [Enum.KeyCode.D] = true
}

local function getFinalSpeed(baseSpeed)
    local boostValue = Character:FindFirstChild("IsSpeedBoosted")
    return (boostValue and boostValue.Value) and (baseSpeed * 1.75) or baseSpeed
end

local function increaseSpeed()
    if currentSpeed < maxSpeed then
        currentSpeed = currentSpeed + acceleration
        currentAnimSpeed = currentAnimSpeed + (acceleration / maxSpeed)
    else
        currentSpeed = maxSpeed
        currentAnimSpeed = 1.1
    end
    Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
    runSound.PlaybackSpeed = currentSpeed / maxSpeed
end

local function increaseJump()
    if currentJump < maxJump then
        currentJump = currentJump + acceleration
    else
        currentJump = maxJump
    end
    Character.Humanoid.JumpPower = getFinalSpeed(currentJump) * 1.18
end

function ToggleAnimationAndSound(shouldPlay)
    if shouldPlay then
        if not PlayAnim.IsPlaying then
            PlayAnim:Play()
        end
        if not runSound.IsPlaying then
            runSound:Play()
        end
    else
        PlayAnim:Stop()
        runSound:Stop()
    end
end

function ToggleRunningIfAirborne()
    if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
        ToggleAnimationAndSound(false)
    elseif isMovingForward then
        ToggleAnimationAndSound(true)
    end
end

UIS.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if movementKeys[input.KeyCode] then
        isMoving = true
        if input.KeyCode == Enum.KeyCode.W then
            isMovingForward = true
            ToggleAnimationAndSound(true)
        end
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = true
    end
end)

UIS.InputEnded:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if movementKeys[input.KeyCode] then
        local anyKeyPressed = false
        for key in pairs(movementKeys) do
            if UIS:IsKeyDown(key) then
                anyKeyPressed = true
                break
            end
        end
        
        if not anyKeyPressed then
            isMoving = false
            isMovingForward = false
            ToggleAnimationAndSound(false)
        elseif input.KeyCode == Enum.KeyCode.W then
            isMovingForward = false
            ToggleAnimationAndSound(false)
        end
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = false
    end
end)

RunService.Heartbeat:Connect(function()
    ToggleRunningIfAirborne()
    
    if isMoving then
        increaseSpeed()
        increaseJump()
    else
        if currentSpeed > 16 then
            currentSpeed = math.max(currentSpeed - deceleration, 16)
            currentAnimSpeed = math.max(currentAnimSpeed - (deceleration/maxSpeed), 0.4)
            Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
            runSound.PlaybackSpeed = currentSpeed / maxSpeed
        end
    end
end)

If anything is wrong, let me know and I will try to fix the problems that may appear.

1 Like

the anims are now playing good but whenevr i walk backwards, the walking anim plays but the player can reach 50 of speed while he should just walk (16 speed), i only want the charcetr to be able to run and reach 50 of speed only when hes walking forward and so walking when pressing A S or D, would it be hard to make?

1 Like

I could definitely give it a try, if you want the speed to increase only when the user is pressing W and to keep the A S or D just for walking then this is the script I have tried to make for that

Running Script (Localscript):

local UIS = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

local walkSpeed = 16
local runSpeed = 50
local maxJump = 20
local acceleration = 0.08
local deceleration = 0.15

local currentSpeed = walkSpeed
local currentJump = 30
local currentAnimSpeed = 0.4
local isRunning = false
local isMoving = false
local leftControlDown = false

local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / runSpeed
local Anim = script:WaitForChild("SprintAnim")
local PlayAnim = Character.Humanoid:LoadAnimation(Anim)

local function getFinalSpeed(baseSpeed)
    local boostValue = Character:FindFirstChild("IsSpeedBoosted")
    return (boostValue and boostValue.Value) and (baseSpeed * 1.75) or baseSpeed
end

local function updateMovement()
    if isRunning then
        if currentSpeed < runSpeed then
            currentSpeed = currentSpeed + acceleration
            currentAnimSpeed = currentAnimSpeed + (acceleration / runSpeed)
        else
            currentSpeed = runSpeed
            currentAnimSpeed = 1.1
        end
    elseif isMoving then
        currentSpeed = walkSpeed
        currentAnimSpeed = 0.4
    else
        if currentSpeed > walkSpeed then
            currentSpeed = math.max(currentSpeed - deceleration, walkSpeed)
            currentAnimSpeed = math.max(currentAnimSpeed - (deceleration/runSpeed), 0.4)
        end
    end

    Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
    Character.Humanoid.JumpPower = getFinalSpeed(currentJump) * 1.18
    runSound.PlaybackSpeed = currentSpeed / runSpeed
    
    if PlayAnim then
        PlayAnim:AdjustSpeed(currentAnimSpeed)
        if isRunning and not PlayAnim.IsPlaying then
            PlayAnim:Play()
        elseif not isRunning and PlayAnim.IsPlaying then
            PlayAnim:Stop()
        end
    end
end

UIS.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        isRunning = true
        isMoving = true
    elseif input.KeyCode == Enum.KeyCode.A or 
           input.KeyCode == Enum.KeyCode.S or 
           input.KeyCode == Enum.KeyCode.D then
        isMoving = true
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = true
    end
end)

UIS.InputEnded:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        isRunning = false
        if not (UIS:IsKeyDown(Enum.KeyCode.A) or 
                UIS:IsKeyDown(Enum.KeyCode.S) or 
                UIS:IsKeyDown(Enum.KeyCode.D)) then
            isMoving = false
        end
    elseif input.KeyCode == Enum.KeyCode.A or 
           input.KeyCode == Enum.KeyCode.S or 
           input.KeyCode == Enum.KeyCode.D then
        if not (UIS:IsKeyDown(Enum.KeyCode.W) or 
                UIS:IsKeyDown(Enum.KeyCode.A) or 
                UIS:IsKeyDown(Enum.KeyCode.S) or 
                UIS:IsKeyDown(Enum.KeyCode.D)) then
            isMoving = false
        end
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = false
    end
end)

RunService.Heartbeat:Connect(function()
    if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
        if PlayAnim.IsPlaying then PlayAnim:Stop() end
        if runSound.IsPlaying then runSound:Stop() end
    else
        updateMovement()
    end
end)

Once again, if there are any problems feel free to let me know and I will try to solve them as much as I can!

1 Like

thank you for ur dedication, i think its almost done ! the only problem i have is that whenever i run, i stop and i run back, im keeping the run value i had before stopping. but i also noticed that this value seems to dicrease if i dont run, for i example i run and i reach 50 s/s, i stop for 1 sec, i run forward back and i still have 50 s/s instead of the walk speed resetting, on the other hand if i run until 50 studs per second and then i stop for 4 sec, the speed is back to normal, how to fix that to make it reset wheever the player stops moving (without getting rid of the boost ofc :sweat_smile:)

2 Likes

No worries! I’m happy to help :slight_smile:

The following script I have tried making aims to reset the speed when stopping and to increase the deceleration of the player. If there is anything else you need, let me know!

Running Script (Localscript)

local UIS = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

-- Movement Configuration
local walkSpeed = 16
local runSpeed = 50
local maxJump = 20
local acceleration = 0.08
local deceleration = 0.25  -- Increased deceleration for quicker stopping

local currentSpeed = walkSpeed
local currentJump = 30
local currentAnimSpeed = 0.4
local isRunning = false
local isMoving = false
local leftControlDown = false
local lastInputTime = 0
local speedDecayTimer = 0

-- Animation/Sound Setup
local runSound = game.SoundService.Running
runSound.PlaybackSpeed = currentSpeed / runSpeed
local Anim = script:WaitForChild("SprintAnim")
local PlayAnim = Character.Humanoid:LoadAnimation(Anim)

-- Boost System
local function getFinalSpeed(baseSpeed)
    local boostValue = Character:FindFirstChild("IsSpeedBoosted")
    return (boostValue and boostValue.Value) and (baseSpeed * 1.75) or baseSpeed
end

local function updateMovement(dt)
    -- Handle speed changes based on movement state
    if isRunning then
        if currentSpeed < runSpeed then
            currentSpeed = currentSpeed + acceleration
            currentAnimSpeed = currentAnimSpeed + (acceleration / runSpeed)
        else
            currentSpeed = runSpeed
            currentAnimSpeed = 1.1
        end
        speedDecayTimer = 0  -- Reset decay timer when running
    elseif isMoving then
        -- When moving with A/S/D, immediately drop to walk speed
        currentSpeed = walkSpeed
        currentAnimSpeed = 0.4
        speedDecayTimer = 0
    else
        -- When completely stopped, decay speed quickly
        speedDecayTimer = speedDecayTimer + dt
        if speedDecayTimer > 0.1 then  -- Small delay before decay starts
            currentSpeed = math.max(currentSpeed - deceleration * 2, walkSpeed)
            currentAnimSpeed = math.max(currentAnimSpeed - (deceleration * 2 / runSpeed), 0.4)
        end
    end

    -- Apply final speed with boost
    Character.Humanoid.WalkSpeed = getFinalSpeed(currentSpeed)
    Character.Humanoid.JumpPower = getFinalSpeed(currentJump) * 1.18
    runSound.PlaybackSpeed = currentSpeed / runSpeed
    
    -- Animation control
    if PlayAnim then
        PlayAnim:AdjustSpeed(currentAnimSpeed)
        if isRunning and not PlayAnim.IsPlaying then
            PlayAnim:Play()
        elseif not isRunning and PlayAnim.IsPlaying then
            PlayAnim:Stop()
        end
    end
end

-- Input Handling
UIS.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        isRunning = true
        isMoving = true
        lastInputTime = os.clock()
    elseif input.KeyCode == Enum.KeyCode.A or 
           input.KeyCode == Enum.KeyCode.S or 
           input.KeyCode == Enum.KeyCode.D then
        isMoving = true
        lastInputTime = os.clock()
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = true
    end
end)

UIS.InputEnded:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    
    if input.KeyCode == Enum.KeyCode.W then
        isRunning = false
        if not (UIS:IsKeyDown(Enum.KeyCode.A) or 
                UIS:IsKeyDown(Enum.KeyCode.S) or 
                UIS:IsKeyDown(Enum.KeyCode.D)) then
            isMoving = false
        end
    elseif input.KeyCode == Enum.KeyCode.A or 
           input.KeyCode == Enum.KeyCode.S or 
           input.KeyCode == Enum.KeyCode.D then
        if not (UIS:IsKeyDown(Enum.KeyCode.W) or 
                UIS:IsKeyDown(Enum.KeyCode.A) or 
                UIS:IsKeyDown(Enum.KeyCode.S) or 
                UIS:IsKeyDown(Enum.KeyCode.D)) then
            isMoving = false
        end
    elseif input.KeyCode == Enum.KeyCode.LeftControl then
        leftControlDown = false
    end
end)

-- Main Game Loop
RunService.Heartbeat:Connect(function(dt)
    if Character.Humanoid.FloorMaterial == Enum.Material.Air or leftControlDown then
        if PlayAnim.IsPlaying then PlayAnim:Stop() end
        if runSound.IsPlaying then runSound:Stop() end
    else
        updateMovement(dt)
    end
end)

If there is anything that emerges which causes errors or unsatisfactory results then feel free to tell me and I will continue to fix this!

1 Like

i see no issues, thanks for your help it really helped!!

2 Likes

Glad I could help! If there are any future requests you may have then feel free to DM me. I am also working on my own project at the moment and you may give me feedback on each dev log I make on it.

I hope you enjoy the rest of your day / night!

2 Likes