Changing Animation Issue

Hello! I am having some trouble changing animations for my character after setting values to it. Part of my script is from the Developer Hub:

local Players = game:GetService("Players")

local function onCharacterAdded(character)
	local humanoid = character:WaitForChild("Humanoid")
    
	for _, playingTracks in pairs(humanoid:GetPlayingAnimationTracks()) do
		playingTracks:Stop(0)
	end
 	
	local animateScript = character:WaitForChild("Animate")
	wait(1)
	animateScript.run.RunAnim.AnimationId = "rbxassetid://616010382"        -- Run
	animateScript.walk.RunAnim.AnimationId = "rbxassetid://616013216"      -- Walk
	animateScript.jump.JumpAnim.AnimationId = "rbxassetid://616008936"      -- Jump
	animateScript.idle.Animation1.AnimationId = "rbxassetid://616006778"    -- Idle (Variation 1)
	animateScript.idle.Animation2.AnimationId = "rbxassetid://616008087"    -- Idle (Variation 2)
	animateScript.fall.FallAnim.AnimationId = "rbxassetid://616005863"      -- Fall
	animateScript.swim.Swim.AnimationId = "rbxassetid://616011509"          -- Swim (Active)
	animateScript.swimidle.SwimIdle.AnimationId = "rbxassetid://616012453"  -- Swim (Idle)
	animateScript.climb.ClimbAnim.AnimationId = "rbxassetid://616003713"    -- Climb
end
 
local function onPlayerAdded(player)
	player.CharacterAppearanceLoaded:Connect(onCharacterAdded)
end
 
Players.PlayerAdded:Connect(onPlayerAdded)

What I want to have happen is to turn it into this…

local Players = game:GetService("Players")

local function onCharacterAdded(character)
	local humanoid = character:WaitForChild("Humanoid")
    local player = game.Players:GetPlayerFromCharacter(character)
    local anim = player.PlayerAnim.Value
	for _, playingTracks in pairs(humanoid:GetPlayingAnimationTracks()) do
		playingTracks:Stop(0)
	end
 if anim == "DefaultAnim" then	
	local animateScript = character:WaitForChild("Animate")
	wait(1)
	animateScript.run.RunAnim.AnimationId = "rbxassetid://616010382"        -- Run
	animateScript.walk.RunAnim.AnimationId = "rbxassetid://616013216"      -- Walk
	animateScript.jump.JumpAnim.AnimationId = "rbxassetid://616008936"      -- Jump
	animateScript.idle.Animation1.AnimationId = "rbxassetid://616006778"    -- Idle (Variation 1)
	animateScript.idle.Animation2.AnimationId = "rbxassetid://616008087"    -- Idle (Variation 2)
	animateScript.fall.FallAnim.AnimationId = "rbxassetid://616005863"      -- Fall
	animateScript.swim.Swim.AnimationId = "rbxassetid://616011509"          -- Swim (Active)
	animateScript.swimidle.SwimIdle.AnimationId = "rbxassetid://616012453"  -- Swim (Idle)
	animateScript.climb.ClimbAnim.AnimationId = "rbxassetid://616003713"    -- Climb
end
end
 
local function onPlayerAdded(player)
	player.CharacterAppearanceLoaded:Connect(onCharacterAdded)
end
 
Players.PlayerAdded:Connect(onPlayerAdded)

The problem is, by the time I assign the PlayerAnim Value and all the other stuff to the player (in another part of the script), this line has already fired

player.CharacterAppearanceLoaded:Connect(onCharacterAdded)

I thought of putting in LoadCharacterAppearance() but it says it is depreciated, and I am getting errors.
Any thoughts?

Note: this is a repost of my other one

I did not get answers, but it was Sunday, so I guess that is what you expect.

2 Likes

This wont stop the animations.
PlayingTracks is an array so you will want to stop each animation.

playingTracks[Index]:Stop()

This is how you would stop each one.

Loading appearance isn’t really a good idea as there is an interval between char added and appearance loaded when first spawning. It would do about the same thing so it wouldn’t really be worth changing it to load appearance.

Personally I would stick with your first script but you would want to modify it by changing the animation ID before stopping it so that once the animation restarts it will play the correct animation. The only reason for this is if they are using the animations they spawned with so you can get a smoother transition.

2 Likes

I agree with you, I would want to stick to the first script, because that works, the problem is that I want to have multiple animations,

But if the first script works doesn’t that mean that it does?
You probably know a lot more about this than me but I am just thinking.

so you are saying that I should put

for _, playingTracks in pairs(humanoid:GetPlayingAnimationTracks()) do
	playingTracks[animateScript.run.RunAnim.AnimationId]:Stop(0)
end

for each one?

Not quite, Heres a edited version so you can see

The only issue with your one was that it would only stop the run animation constantly

1 Like

Ahhhhhhhhhhhhh, I see, I think. Thanks, I will see if it works!

On a side note when using for loops its key to remember the two elements

– Commonly used method
for Index , Table in pairs do

end

— My prefered method
for Index = 1, #Table

end

1 Like

Oh wait, do you literally write Index or do you replace both “Index” with something else? Sorry, I am not the best at scripting

Okay so Index is like a variable that only exists in the loop
For each object in an array it will run, all index does is tell you which number object

for example

Table = {"A","B","C"}
for i = 1,#Table do
    print(i)
    print(Table[i])
end

would result in
1 - A
2 - B
3 - C

However when you set it to only

it would do the same thing despite having different values in an array.

Oh ok I get it. Thanks! I definitely need to use that.

The name of the variable is misleading. The code will stop each animation track.
Maybe if I wrote it like this,

playingTracks = humanoid:GetPlayingAnimationTracks()
for _, playingTrack in pairs(playingTracks) do
    playingTrack:Stop(0)
end

it would be more obvious.

Yeah I am still stuck, the CharacterAppearance loads before I can set the values, or when I have it wait till afterwards it just does nothing…

I tried that as well, the whole thing still did not work

When changing the animations, the animate script only updates the existing animations once a child/descendant has been modified or added. Changing the animation IDs for each animation won’t trigger this, so it won’t reload the animations that you select.

Just clone the existing animation objects, delete the old ones, and change the IDs like you have done already and it should work properly. The loop has nothing to do with it - all it does is tell you which tracks are playing. You don’t even need to stop those tracks, you can forego the loop entirely, since the animate script will reload all your animations for you.

Ok yes but the function only runs when it is connected by CharacterAppearanceLoaded, which runs only once at the start of the game, before it has time to set the values. And I need some line of code to run that again like LoadCharacterApearance(), but it is depreciated.

You can set it at any time in the game using the method I mentioned. You don’t need to rely on character loading or otherwise; that said, you need to make sure the animate script and all the descendants are loaded in. You can throw in a few WaitForChild’s to do that.

So I did what you said using this method?

    local firstanimation = animateScript.run.RunAnim.AnimationId
	local firstanimationClone = firstanimation:Clone()
	animateScript.run.RunAnim.AnimationId:Destory()
	firstanimationClone = "rbxassetid://616163682" 

And I am getting

ServerScriptService.ChangeAnimationScript:34: attempt to call a nil value 

Is this a typo in the code sample or is this a typo in your code that is giving you the error? (it would be helpful to provide line numbers or indicate which line is the one you are getting the error for)

Sorry, yes typo, I fixed it and it still didn’t work.

13    local firstanimation = animateScript.run.RunAnim
14	local firstanimationClone = firstanimation:Clone()
15	animateScript.run.RunAnim:Destroy()
16	firstanimationClone.AnimationId = "rbxassetid://616010382"        -- Run
17	local secondanimation = animateScript.walk.RunAnim
18	local secondanimationClone = secondanimation:Clone()
19	animateScript.walk.RunAnim:Destroy()
20    secondanimationClone.AnimationId = "rbxassetid://616013216" 

And right now I am getting

  15:37:41.266  RunAnim is not a valid member of StringValue "Workspace.MRKYLO20.Animate.run"  -  Server  -  ChangeAnimationScript:13
  15:37:41.267  Stack Begin  -  Studio
  15:37:41.267  Script 'ServerScriptService.ChangeAnimationScript', Line 13 - function onCharacterAdded  -  Studio  -  ChangeAnimationScript:13
  15:37:41.267  Stack End

My apologies by the way, I am not the best at scripting and I am trying to learn this… So thanks for spending the time to help me.

1 Like

That issue looks like when the character is added, not all of the descendants of the script have loaded yet. Instead of this,

13    local firstanimation = animateScript.run.RunAnim

You may have to call WaitForChild("run"):WaitForChild("RunAnim") instead. This will wait until everything is loaded in the character. You would need to do this for all the animations - secondanimation, thirdanimation, etc. that you want to change.

13    local firstanimation = animateScript.run:WaitForChild("RunAnim")

or 

13    local firstanimation = animateScript:WaitForChild("run"):WaitForChild("RunAnim")

You could optionally put a wait(2) if you want a quick fix, but it doesn’t guarantee that everything has loaded. It just gives extra time to wait, hoping that everything in the character has loaded 2 seconds later.

13    wait(2)
14    local firstanimation = animateScript.run.RunAnim