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
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.
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.
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
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