My script runs too early, what solutions are there?

Just because the character is created doesn’t mean it has been parented to the Workspace. You could use character.AncestryChanged:Wait() at the top of your CharacterAppearanceLoaded event (it passes the character as an argument, use it) or you can use a while loop with a wait:

while character.Parent ~= workspace do
    RunService.Heartbeat:Wait();  --Assuming you already defined RunService
end
1 Like

I’ve actually already tried that. The problem is not that the humanoid doesn’t exist, it does. It’s just not a descendant of the game object. Thanks anyways!

That’s what “not a descendant of the game” means. You tried to access it, but it did not exist in the game space yet.

Have you tried yielding with characteradded?

local character = player.Character or player.CharacterAdded:Wait()

That’s exactly what “not a descendant of the game” means. The OP already holds a reference to the Humanoid, but it hasn’t been parented to the game yet. Read the error carefully or you may end up giving the wrong solution again.

The character already exists (it’s passed through CharacterAppearanceLoaded), but it hasn’t been parented to the game yet. OP needs to yield using AncestryChanged or a while loop to check the character’s parent.

I see. Well its a bit unorthodox, but like your script, I usually just yield until the child im waiting for loads.

repeat wait() until character.Humanoid -- Or the child waiting for
local Plr = game:GetService("Players").LocalPlayer;
local Char = Plr.Character or Plr.CharacterAdded:Wait();
local Human = Char:WaitForChild("Humanoid");

--<Your Code


Plr.CharacterAdded:Connect(function(Character)
    Char = Character; Human = Character:WaitForChild("Humanoid");
--[[
Update the old "Char" variable, since it technically doesn't exist since a
new character is created whenever you respawn
]]
end);

The thing is the child already exists (OP also has reference to the Humanoid object), but calling :LoadAnimation requires the Humanoid to be a descendant of the game. In this case, the character has not been parented to the game yet.

Then couldnt you just yield until child.Parent == workspace. OP, have you tried any of wow’s code?

character:WaitForChild(“Humanoid”) would not help in this case because it would still return the Humanoid since it already exists.
Let me repeat: OP. Already. Has. The. Humanoid.
The issue here is that the character is parented to nil.
Why, you ask?
Because Roblox’s character loading flow sucks. For some reason, all of the character-related events fire BEFORE the character is inserted into the workspace, but after all of the essential parts of the character are created.

1 Like

Ooh! Sorry I was not understanding. I have encountered this same problem before. The fix I have found is to put this code near the beginning of your script, which relies on AncestryChanged to tell when the character’s parent is no longer nil.

while character.Parent == nil do
	character.AncestryChanged:wait()
end

This should solve the problem.

1 Like

This would probably be better.

local rs = game:GetService(“RunService”)

repeat rs.Heartbeat:Wait() until character and character.Parent

If you’re just waiting for it to be in the workspace you could do until character.Parent == workspace

That would not be better. Your’s runs every frame, putting a significant strain on performance, whereas Excess’s only runs when the Parent changes.


In regards to OP, this is an unfortunate consequence of the current avatar loading event order. Currently, the only way to guarantee the character will be fully loaded by the time your script runs is by calling LoadCharacter and waiting for it to return. This should be fixed at some point, and is planned, but for some reason it’s been heavily delayed.

4 Likes

That technically uses up more resources though, since you are checking every Heartbeat, instead of waiting for the AncestryChanged event.

3 Likes

Oh right. Sorry lol I didn’t read it right

Just a heads up, the while loop isn’t needed since the character’s parent is currently nil. When the character is reparented, its new parent will never be nil.

1 Like

It is just a bit of coverage in case something goes haywire. This is generally true, but you never know what might happen.

No, I mean logically, something parented to nil cannot be parented to nil. There’s no reparenting.

1 Like

Very good point. However, I still feel safer using a loop, just in case the event somehow misfired. You are right that it is logicality not necessary though :+1:.