Help on shift-to-sprint script

My shift-to-sprint script works, but whenever I stop walking while holding shift, the run animation still plays. I will also make the script a remote event later but right now I’m just trying to fix this. I also tried using humanoid:GetState() but that wasn’t as clean and the bug still occured. How should I fix this?

local uis = game:GetService("UserInputService")
local pls = game:GetService("Players")
local cas = game:GetService("ContextActionService")

local anim = script:WaitForChild("Run")
local play = pls.LocalPlayer.Character.Humanoid.Animator:LoadAnimation(anim)
play.Priority = Enum.AnimationPriority.Movement

local player = pls.LocalPlayer
local char = player.Character

local function beginSprint(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 24
		play:Play()
	end
end

local function endSprint(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 16
		play:Stop()
	end
end

local function beginSprintMOBILE(name, inputState)
	if inputState == Enum.UserInputState.Begin then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 24
		play:Play()
	elseif inputState == Enum.UserInputState.End then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 16
		play:Stop()
	end
end

uis.InputBegan:Connect(beginSprint)
uis.InputEnded:Connect(endSprint)

cas:BindAction("Run", beginSprintMOBILE, true)
cas:GetButton("Run")
cas:SetPosition("Run", UDim2.new(0, 0, -0.3, 0))
cas:SetTitle("Run", "Run")

Get the HumanoidRootPart’s velocity. If it’s lower than 1, it means the player isn’t moving so stop running. You can connect it to a RunService.RenderStepped event so it’s always checked.
(If you don’t know how to, it’s pls.LocalPlayer.Character.HumanoidRootPart.Velocity.Magnitude).

This will check whether you’ve stopped walking/moving at all or if you stopped clicking shift, if you’re still playing the animation after you stopped holding shift/stopped moving, the animation will stop playing.

local uis = game:GetService("UserInputService")
local pls = game:GetService("Players")
local cas = game:GetService("ContextActionService")

local anim = script:WaitForChild("Run")
local play = pls.LocalPlayer.Character.Humanoid.Animator:LoadAnimation(anim)
play.Priority = Enum.AnimationPriority.Movement

local player = pls.LocalPlayer
local char = player.Character

local isRunning = false

local function beginSprint(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		isRunning = true
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 24
		play:Play()
		coroutine.wrap(function()
			repeat wait() until not isRunning or player.Character.Humanoid.MoveDirection.Magnitude <= 0
			if play.IsPlaying then
				play:Stop()
			end
		end)()
	end
end

local function endSprint(input, isTyping)
	if isTyping then return end
	if input.KeyCode == Enum.KeyCode.LeftShift then
		isRunning = false
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 16
		play:Stop()
	end
end

local function beginSprintMOBILE(name, inputState)
	if inputState == Enum.UserInputState.Begin then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 24
		play:Play()
	elseif inputState == Enum.UserInputState.End then
		pls.LocalPlayer.Character.Humanoid.WalkSpeed = 16
		play:Stop()
	end
end

uis.InputBegan:Connect(beginSprint)
uis.InputEnded:Connect(endSprint)

cas:BindAction("Run", beginSprintMOBILE, true)
cas:GetButton("Run")
cas:SetPosition("Run", UDim2.new(0, 0, -0.3, 0))
cas:SetTitle("Run", "Run")```

If my solution worked, please mark it as your solution.
1 Like

Some problems I found with that script, when you press shift while standing still, it plays the animation a little bit, and when you hold shift while walking then stand still then walk again, the animation doesn’t play

How should I add that in, the functions wont keep being fired if the player is holding the button I don’t think.

Do something like this, in the character script:

local uis = game:GetService("UserInputService")

local sprintKey = Enum.KeyCode.LeftShift -- Set sprint key

local function sprinting()
	-- Do (sprinting) stuff
end

local function NOTsprinting()
	-- Do (NOT sprinting) stuff
end

-- Basic Shift-to-sprint function --
-- Edit this part if you have different ways of listening for sprint key input
uis.InputBegan:Connect(function(key, typing)
	if typing then return end

	if key.KeyCode == sprintKey then
		sprintKeyHeld()
	end
end)

uis.InputEnded:Connect(function(key, typing)
	if typing then return end -- [Optional] You can remove this since it may be annoying when sprinting wont stop if player is typing while sprint key is held 

	if key.KeyCode == sprintKey then
		sprintKeyReleased()
	end
end)
------------------------------------


local run = game:GetService("RunService")

local plr = game.Players.LocalPlayer
local char = plr.Character
local humanoid = char:WaitForChild("Humanoid")

local sprintButtonHeld = false
local alreadySprint = false
local dead = false
local alreadyDead = false

local function isMoving() return humanoid.MoveDirection.Magnitude > 0 end

function sprintKeyHeld() sprintButtonHeld = true end
function sprintKeyReleased() sprintButtonHeld = false end

humanoid.Died:Connect(function() dead = true end)

run.Stepped:Connect(function()
	if not dead then
		if sprintButtonHeld and isMoving() then
			if not alreadySprint then
				sprinting()
				alreadySprint = true
			end
		else
			if alreadySprint then
				NOTsprinting()
				alreadySprint = false
			end
		end
	else
		if not alreadyDead then
			NOTsprinting()
			alreadyDead = true
		end
	end
end)

The player will sprint if they are moving and holding the sprint button, and stop if either is false. This also only work if the player is alive.
Edit more about that one but that is just the basics of it

This one uses a loop so it could be a bit laggy or something.

1 Like