Sprinting and walking animation based on player speed?

The script should: Change the players animation based on his walkspeed, below 20 is the walk animation (when walking) and above 20 is running animation

the script does: only has walking animation, when i change my character speed to 50 it suddenly does play the running animation but does NOT turn back to walk when i go slower.

game.Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        local humanoid = character:WaitForChild("Humanoid")
        local walkAnim = player.Character.Animate.walk.WalkAnim

        humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
            if humanoid.WalkSpeed > 20 then
                walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493330373" -- Animation ID for faster movement
            else
                walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493310971" -- Default animation ID
            end
        end)

        -- Set initial animation based on starting speed
        if humanoid.WalkSpeed > 20 then
            walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493330373"
        else
            walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493310971"
        end
    end)
end)

5 Likes

Hello! What type of script is running this (server script, client script)?

1 Like

The script is located inside a server side script in workspace

Also to add to this, how are you changing the walk speed? Is this done on the server or client?

If you are unsure, then I think a better question I should ask is where you are changing the walk speed from, such as the explorer or via admin commands.

1 Like

clientsided in a localscript located in StarterGui (connected to a stamina bar ui)
the walkspeed changing to 50 is done with kohls admin via ingame

I’m not entirely sure what is exactly is going wrong here yet, but I guess we could start by moving this server script into StarterCharacterScripts(I think that’s the name at least, don’t have studio open currently. this should be located: Game > StarterPlayer > StarterCharacterScripts):

local character = script.Parent 
local humanoid = character:WaitForChild("Humanoid")
local walkAnim = character:WaitForChild("Animate"):WaitForChild("walk"):WaitForChild("WalkAnim")

        humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
            if humanoid.WalkSpeed > 20 then
                print("Changed to run")
walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493330373" -- Animation ID for faster movement
            else
                print("Changed to walk")
walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493310971" -- Default animation ID
            end
        end)

        -- Set initial animation based on starting speed
        if humanoid.WalkSpeed > 20 then
              print("Started with run")
            walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493330373"
        else
            print("Started with walk")
            walkAnim.AnimationId = "http://www.roblox.com/asset/?id=16493310971"
        end

ALSO IMPORTANT TO CHANGE IT TO A LOCAL SCRIPT (forgot to mention this)

After you add this, test it out and please provide the output located in the console.

p.s. Do not mind the terrible code formatting the site is giving me difficulty as of right now.

1 Like

Hey, ive tested it out in a localscript, now the animation doesnt change instantly when reaching the speed BUT whenever i jump it goes to the run animation as wished, when i stop going fast it keeps playing the run animation until i again go idle or jump, probably because by jumping and going idle i refresh animation i presume?

I am fairly sure this is the case.

1 Like

is there any way to refresh animation as soon as it changes to run/walk animation?

Yes there is, one moment let me create a script.

1 Like

I would recommend using the Player’s HumanoidRootPart as to get the amount of speed the player is accelerating at.

  local maxSpeed = MAX_WALK_SPEED; -- Maximum speed value for full animation speed
  local currentSpeed = <HumanoidRootPart>.AssemblyLinearVelocity.Magnitude;
  local normalizedSpeed = math.min(currentSpeed / maxSpeed, 1);

  -- If you want to apply a simple smoothing (ease out quad) as an example
  local smoothedSpeed = normalizedSpeed * normalizedSpeed;

  print(smoothedSpeed)

2 Likes

Ok, I believe I did it. Tell me if there are any errors on your end and then I can correct them. Same thing as before use this as a local script under StarterCharacterScripts:

local RunService = game:GetService("RunService")

local character = script.Parent 
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

local MAX_WALK_SPEED = humanoid.WalkSpeed -- or any value of your choosing

local DEFAULT_RUNNING_ANIMATION = 16493330373
local DEFAULT_WALKING_ANIMATION = 16493310971

local runAnimation = Instance.new("Animation")
runAnimation.AnimationId = "rbxassetid://" .. DEFAULT_RUNNING_ANIMATION
runAnimation = animator:LoadAnimation(runAnimation)
runAnimation.Priority = Enum.AnimationPriority.Idle

local renderConnection 

local isRunning = false

local function startRun()
	if isRunning == true then
		return
	end
	
	isRunning = true
	
	runAnimation:Play()
end

local function stopRun()
	if isRunning == false then
		return
	end

	isRunning = false
	
	runAnimation:Stop()
end

local function determine(deltaTime)
	if humanoidRootPart.AssemblyLinearVelocity.Magnitude > 20 then
		startRun()
		
		local maxSpeed = MAX_WALK_SPEED -- Maximum speed value for full animation speed
		local currentSpeed = humanoidRootPart.AssemblyLinearVelocity.Magnitude
		local normalizedSpeed = math.min(currentSpeed / maxSpeed, 1)

		-- If you want to apply a simple smoothing (ease out quad) as an example
		local smoothedSpeed = normalizedSpeed * normalizedSpeed
		
		runAnimation:AdjustSpeed(smoothedSpeed)
	else
		stopRun()
	end
end

humanoid.StateChanged:Connect(function(previous, current)
	if previous == Enum.HumanoidStateType.Running then
		if renderConnection ~= nil then

			renderConnection:Disconnect()
			renderConnection = nil

			stopRun()
		end
	elseif current == Enum.HumanoidStateType.Running then
		if renderConnection == nil then
			renderConnection = RunService.RenderStepped:Connect(determine)
		end
	end
end)

character:WaitForChild("Animate"):WaitForChild("walk"):WaitForChild("WalkAnim").AnimationId = "rbxassetid://" .. DEFAULT_WALKING_ANIMATION
2 Likes

Going off of what Ace said, I think it would be very useful to add a change in animation speed as well.

1 Like

What went wrong: no walking animation anymore, When running the running animation plays but frozen in one keyframe

Heres the console although nothing came in it whenever i started/stopped running:

also yes, i think that making the run animation faster would be even better

Ah, I see the problem, one moment.

1 Like

I have just edited the script above to fix the problem and apply Ace’s contributions to the animation speed.

Let me know if there are any errors from the script, or if it does not function as intended.

1 Like

it seems the animation refresh works great, though the walking animation is now the default roblox and the running animation is the custom running animation

1 Like

My apologies, let me add a place where you can edit the custom walking animation.

1 Like

Just edited it to allow you to change the default walking animation ID. Hopefully nothing errors, if it does let me know.

1 Like

You are a legend, thank you so much my dude.

1 Like