Running Animation Playing Over Idle Animation

I have a toggleable sprint script, however if you stop moving while it’s activated the running animation continues to play over the idle. I was wondering if anyone knows how to correct this bug? I just need somebody to make adjustments to the script so that it wont keep playing if the player is not moving. Thank you!

Script:

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

local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")

local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement

local running = false

local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 40
local WALK_SPEED = 16

local runBool = false

local function run() -- So we don't have to repeat the same commands
	if runBool then
		if hum.MoveDirection.Magnitude <= 0 then return end -- If not moving then stop function execution

		hum.WalkSpeed = RUN_SPEED
		track:Play()
	else
		hum.WalkSpeed = WALK_SPEED
		track:Stop()
	end
end

local function inputBegan(input, processed)
	if processed then return end

	if input.KeyCode == RUN_KEYCODE then
		if runBool then runBool = false
		else runBool = true end

		run()
	end
end

local function moveDirectionChanged()
	local magnitude = hum.MoveDirection.Magnitude
	if magnitude <= 0 then
		if running then
			run(false)
		end
	end
end

userInputService.InputBegan:Connect(inputBegan)

hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)


userInputService.InputBegan:connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		wait(.8)
		if char.Humanoid.WalkSpeed == 40 then
			track:Play()
		end
	end
end)
7 Likes

Hi, I think the issue is caused because the “running” variable isn’t used in the script at all except for an if statement that breaks the code:

local function moveDirectionChanged()
	local magnitude = hum.MoveDirection.Magnitude
	if magnitude <= 0 then
		if running then -- breaks code cuz it will never be true
			run()
		end
	end
end

Also this line:

if hum.MoveDirection.Magnitude <= 0 then return end -- If not moving then stop function execution

Causes it so that it wont stop running too.

I fixed up the script and added some comments aswell.

In the moveDirection function I set the running var to the runBool var so it actually has a job to do.

running = runBool

The job you’re wondering about is the one in the run function. I give it management to the first if statement to check if the player is running or not.

if runBool and running == false then

At the end I set both run variables and reset them to false.

Script (I’ve tested it, this works.):

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

local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")

local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://10921261968"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement

local running = false

local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 40
local WALK_SPEED = 16

local runBool = false

local function run() -- So we don't have to repeat the same commands
	if runBool and running == false then -- added the running if statement part to make sure the player is walking
		if hum.MoveDirection.Magnitude <= 0 then return end -- If not moving then stop function execution
		
		hum.WalkSpeed = RUN_SPEED
		track:Play()
	else
		hum.WalkSpeed = WALK_SPEED
		track:Stop()
		running = false -- does this to reset it
		runBool = false -- second time we set somethign to false
	end
end

local function inputBegan(input, processed)
	if processed then return end

	if input.KeyCode == RUN_KEYCODE then
		if runBool then runBool = false
		else runBool = true end
		run()
	end
end

local function moveDirectionChanged()
	local magnitude = hum.MoveDirection.Magnitude
	if magnitude <= 0 then
		running = runBool -- sets running var to the runBool
		run()
	end
end

userInputService.InputBegan:Connect(inputBegan)

hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)


userInputService.InputBegan:connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		wait(.8)
		if char.Humanoid.WalkSpeed == 40 then
			track:Play()
		end
	end
end)

Ask me anything!
Thanks,

  • MonsterTrident
4 Likes

Maybe try replacing;

userInputService.InputBegan:connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		wait(.8)
		if char.Humanoid.WalkSpeed == 40 then
			track:Play()
		end
	end
end)

With

hum.StateChanged:Connect(function(old, new)
  if new == Enum.HumanoidStateType.Running then
    track:Play()
  else
    track:Stop()
  end
end
3 Likes

Sorry to intrude, I know this is between the operator and the assistant. Respectfully, I don’t agree with changing it to your version due to many reasons:

  1. He has the Space keycode check in there to stop the running animation if the player has jumped and then waits 8th of a second.
    To add on:
    I won’t go into much detail but @MR_M3WTWO you can surely add the mechanic of when the humanoid is in the air (I think thats how it works, I don’t have all the knowledge in the world) they stop the run animation and then they aren’t (and with the necessary if statements) they run the animation.
    What I’m saying is you can replace the wait(.8) with a more efficient way and detect if the player is still in the air or not. This is totally up to you and doesn’t matter TOO much it just might improve the game if there are laggy players we won’t really want them to run in the air lol.

  2. The second if statement is good to check if the player is still running. But you can for sure change it so that if the runBool var is true(if not runBool then do the running var) THEN the track plays.

So overall @Mighty1964 I don’t see your message helping @MR_M3WTWO and rather causing him more issues. Not to cause any arguments, I’m just trying to help!

4 Likes

Oh alright then, sorry about that. It’s because what I thought would help would fix the problem that @MR_M3WTWO had.

3 Likes

This is certainly an improvement however there is an issue that may have resulted in miscommunication. Whenever I am running and I stop moving, it stops the sprint altogether. I want a scenario where you can be sprinting, stop sprinting, and continue sprinting again without having to toggle the script again. This can be an issue because you have to already be walking to start the script and it can also be annoying to have to start the running over and over again because you stopped moving for a couple of seconds.

If it helps, here is the id of my idle animation:
18543146961

2 Likes

All good, I see where you were coming from! Nobody is a perfect scripter and I totally understand that :+1:

4 Likes

I do rant a little and this may be confusing so just ask me if you need me to clarify something.

3 Likes

Yeah sorry I confused your message and wrote something you weren’t looking for. I’m a bit tired and if fixing this script will help then I’ll for sure do it!

Ah, I just realized a problem on my side too, when I was testing I accidentally forgot to change back the animation id back to yours.

Also I fixed the problem when if you stop running it stops the sprint altogether. Sorry if this took me a while I’m tired and it’s late lol.

I also switched some stuff to make it easier to read

One thing was that everything was working fine after I fixed some things but since the movedirection function kept firing I added a debounce. I’m pretty sure this isnt the BEST way to code but I’ll leave up the cleaning up and enhancement to you! Maybe someone else can come in here and enhance the code if dont feel like it or can’t. Anyways, I’m still learning how to enhance my code too so yeah nobody is perfect.

Final Script:

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

local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")

local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement

local running = false
local debounce = false -- so sorry I got super tired so I did it this way and added a debounce which helped reduce lag in the moverDirection function

local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 40
local WALK_SPEED = 16

local runBool = false

local function run(isIdle) -- So we don't have to repeat the same commands
	if hum.MoveDirection.Magnitude <= 0 and running == false then return end -- If not moving then stop function execution | added running var to this
	if runBool and not isIdle then 

		hum.WalkSpeed = RUN_SPEED
		track:Play()
	elseif runBool and isIdle then
		
		hum.WalkSpeed = WALK_SPEED
		track:Stop()
	end
end

local function inputBegan(input, processed)
	if processed then return end

	if input.KeyCode == RUN_KEYCODE then
		if runBool then runBool = false running = runBool
		else runBool = true running = runBool end
		run(false)
	end
end

local function moveDirectionChanged()
	local magnitude = hum.MoveDirection.Magnitude
	if magnitude <= 0 then
		running = runBool -- sets running var to the runBool
		run(true)
		debounce = false
	elseif magnitude > 0 and not debounce then -- debounce makes sure it doesnt run multiple times!
		debounce = true
		print(debounce)
		running = runBool -- sets running var to the runBool
		run(false)
	end
end

userInputService.InputBegan:Connect(inputBegan)

hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)


userInputService.InputBegan:connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		wait(.8)
		if char.Humanoid.WalkSpeed == 40 then
			track:Play()
		end
	end
end)

Ask me anything!
Thanks again,

  • MonsterTrident :crazy_face:

hold on I gotta fix something rq dont use this script yet

2 Likes

new script @MR_M3WTWO

Script:

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

local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")

local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement

local running = false
local debounce = false -- so sorry I got super tired so I did it this way and added a debounce which helped reduce lag in the moverDirection function

local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 40
local WALK_SPEED = 16

local runBool = false

local function run(isIdle) -- So we don't have to repeat the same commands
	if hum.MoveDirection.Magnitude <= 0 and running == false then return end -- If not moving then stop function execution | added running var to this
	if runBool and not isIdle then 

		hum.WalkSpeed = RUN_SPEED
		track:Play()
	elseif runBool and isIdle then

		hum.WalkSpeed = WALK_SPEED
		track:Stop()
	end
end

local function inputBegan(input, processed)
	if processed then return end

	if input.KeyCode == RUN_KEYCODE then
		if runBool then runBool = false running = runBool
			hum.WalkSpeed = WALK_SPEED
			track:Stop()
		else runBool = true running = runBool hum.WalkSpeed = RUN_SPEED
			track:Play() end
	end
end

local function moveDirectionChanged()
	local magnitude = hum.MoveDirection.Magnitude
	if magnitude <= 0 then
		running = runBool -- sets running var to the runBool
		run(true)
		debounce = false
	elseif magnitude > 0 and not debounce then -- debounce makes sure it doesnt run multiple times!
		debounce = true
		print(debounce)
		running = runBool -- sets running var to the runBool
		run(false)
	end
end

userInputService.InputBegan:Connect(inputBegan)

hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged)


userInputService.InputBegan:connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		wait(.8)
		if char.Humanoid.WalkSpeed == 40 then
			track:Play()
		end
	end
end)

I hope you like it!

4 Likes

I got off for the not because of a headache and when I finally got back on I tried this script.

Now it is definitely what I want however a found what I believe is the last bug that needs to be fixed.

If the script isn’t activated and you’re standing still, not moving, and then activate it, it plays the running animation. Everything else works fine, it you run, don’t move, and run, it works as planned however this is the last thing that needs to be corrected.

I redid a lot of the script since I felt like it was kinda messy and it was hard to get this task done but I did it! Here is your new script. I added comments so that you could understand what was happening.

Script:

-- Tried to make it clean and efficient, there are still things you can do to organize it more but thanks so much for having me :)
-- Helper: MonsterTrident

-- Services
local userInputService = game:GetService("UserInputService")
local players = game:GetService("Players")
-- Variables
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local animator = hum:WaitForChild("Animator")

local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://15720702879"
local track = animator:LoadAnimation(animation)
track.Priority = Enum.AnimationPriority.Movement

local RUN_KEYCODE = Enum.KeyCode.LeftShift
local RUN_SPEED = 40
local WALK_SPEED = 16
-- Togglables
local isSprinting = false -- if player has sprinting toggled
local isMoving = false -- if player is moving
local isInAir = false -- if player is in the air (because of jumping)

local function updateAnimation() -- Updates it based on if the player is moving or if they have sprinting on/off
	if isSprinting and isMoving then
		hum.WalkSpeed = RUN_SPEED
		if not track.IsPlaying then -- makes sure it isnt already playing
			track:Play()
		end
	else
		hum.WalkSpeed = WALK_SPEED
		track:Stop()
	end
end

local function inputBegan(input, processed)
	if processed then return end

	if input.KeyCode == RUN_KEYCODE then
		isSprinting = not isSprinting -- toggles on and off
		updateAnimation()
	end
end

local function moveDirectionChanged()
	isMoving = hum.MoveDirection.Magnitude > 0 -- sets var to true/false depending if they are moving or not
	if not isInAir then
		updateAnimation()
	end
end

userInputService.InputBegan:Connect(inputBegan) -- player presses key (we want them to press shift)

hum:GetPropertyChangedSignal("MoveDirection"):Connect(moveDirectionChanged) -- player moves

-- Additional: Stop sprinting if jumping | Redone
userInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		track:Stop()
		isInAir = true
		task.wait(.8)
		isInAir = false
	end
end)

Ask me anything!

2 Likes

No questions, this is perfect. Thank you so much for taking so much time to help me, it honestly works perfectly!

2 Likes

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