How to apply animations to players?

Hello!
I need my help with running and walking animations.
In my game, character has 2 phases: running and walking.
I have a custom animation for each but I’m unable to apply it to player.

This is the script I used:

local function onRun()
	for _, playingTrack in animator:GetPlayingAnimationTracks() do
		playingTrack:Stop(0)
	end
	animateScript.run.RunAnim.AnimationId = "rbxassetid://ID"
	animateScript.walk.WalkAnim.AnimationId = "rbxassetid://ID"
end

local function onWalk()
	for _, playingTrack in animator:GetPlayingAnimationTracks() do
		playingTrack:Stop(0)
	end
	animateScript.run.RunAnim.AnimationId = "rbxassetid://ID"
	animateScript.walk.WalkAnim.AnimationId = "rbxassetid://ID"
end

The player just ends up having no animation at all, and return to default animation shortly after.
Could you help me figure out what’s going on?

Thanks in advance!

Sincerely,
GalaxySMediaXz

I recommend handling custom animations using your own script, rather than forking the default script

You can use animation track priorities to prevent the core animations messing up your custom ones

Doing something like this should work:

-- Needs to be a LocalScript inside of StarterCharacterScripts!
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")

local FADE_TIME = 0.1 -- The fade time between animations playing and stopping. In seconds
local WALK_SPEED = 8 -- The player is considered to be walking if their walk-speed is less-than or equal to this value. In studs per second

local character = script.Parent
local rootPart = character.PrimaryPart or character:WaitForChild("HumanoidRootPart"):: BasePart

local humanoid = character:WaitForChild("Humanoid"):: Humanoid
local animator = humanoid:WaitForChild("Animator"):: Animator

local runAnim = Instance.new("Animation")
runAnim.AnimationId = "rbxassetid://ID"

local walkAnim = Instance.new("Animation")
walkAnim.AnimationId = "rbxassetid://ID"

local run = animator:LoadAnimation(runAnim)
run.Priority = Enum.AnimationPriority.Movement -- The default animations use the core priority, which is the lowest

local walk = animator:LoadAnimation(walkAnim)
walk.Priority = Enum.AnimationPriority.Movement


local currentAnimation = walk -- This is done to avoid a situation where currentAnimation is nil
local isRunning = false


local function play(track: AnimationTrack)
	if track.IsPlaying then return end -- The track is already playing, no need to play it again
	currentAnimation:Stop(FADE_TIME)
	currentAnimation = track
	currentAnimation:Play(FADE_TIME)
end

local function onRunAction(_, userInputState: Enum.UserInputState)
	if userInputState == Enum.UserInputState.Begin then
		isRunning = true
	elseif userInputState == Enum.UserInputState.End then
		isRunning = false
	end
end

local function onPostSimulation()
	local speed = math.round(rootPart.AssemblyLinearVelocity.Magnitude)

	if speed > 0 then
		play(if isRunning then run else walk)
	else
		if currentAnimation.IsPlaying then currentAnimation:Stop(FADE_TIME) end
	end
end

ContextActionService:BindAction("Run", onRunAction, false, Enum.KeyCode.LeftShift, Enum.KeyCode.RightShift)

RunService.PostSimulation:Connect(onPostSimulation)

@GalaxySMediaXz I updated the script to reflect the new information you’ve provided :slight_smile::+1:

Script before the edit
-- Needs to be a LocalScript inside of StarterCharacterScripts!
local FADE_TIME = 0.1 -- The fade time between animations playing and stopping. In seconds
local WALK_SPEED = 8 -- The player is considered to be walking if their walk-speed is less-than or equal to this value. In studs per second

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

local runAnim = Instance.new("Animation")
runAnim.AnimationId = "rbxassetid://ID"

local walkAnim = Instance.new("Animation")
walkAnim.AnimationId = "rbxassetid://ID"

local run = animator:LoadAnimation(runAnim)
run.Priority = Enum.AnimationPriority.Movement -- The default animations use the core priority, which is the lowest

local walk = animator:LoadAnimation(walkAnim)
walk.Priority = Enum.AnimationPriority.Movement


local currentAnimation = walk -- This is done to avoid a situation where currentAnimation is nil


local function play(track: AnimationTrack)
	if track.IsPlaying then return end -- The track is already playing, no need to play it again
	currentAnimation:Stop(FADE_TIME)
	currentAnimation = track
	currentAnimation:Play(FADE_TIME)
end

local function onRunning(speed: number)
	local speed = math.round(speed)

	if speed > WALK_SPEED then -- Player is running
		play(run)
	elseif speed <= WALK_SPEED and speed > 0 then -- Player is walking
		play(walk)
	else -- Player is idle
		currentAnimation:Stop(FADE_TIME)
	end
end

humanoid.Running:Connect(onRunning)

@GalaxySMediaXz Fixed an issue with the new script, it should work correctly now

2 Likes

Thank you for your response! I appreciate your help.
However, I am here to clarify something you might have misunderstood.

By ‘two phases,’ I meant that if a player holds ‘Shift,’ they’ll be ‘running,’ but if they don’t, they’ll be ‘walking.’

Your answer is very close to what I need. Thanks again!

Thank you for you help!
The new custom animation works just as expected.
But the default animation is interfering with the custom animation, making them look weird.

I’m trying to disable default animation right now, thanks again!

Using the most recent script I provided, you could try changing the AnimationPriority so that it’s higher than Movement, such as: Action, Action2, Action3, Action4

I ended up removing the “Animate” script.
Thank you very much for your help!

1 Like

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