CharacterAppearanceLoaded fires before R15 body re-built

An R15 character spawns and loads in its clothing/accessories.CharacterAppearanceLoaded fires at this point. After this, the body is rebuilt, for whatever reason (probably rebuilding to adjust scale and/or load packages), and references to the rebuilt body parts are not longer valid. The easiest way to reproduce this is by inserting the following code into ServerScriptService:

game.Players.PlayerAdded:connect(function(player)
	player.CharacterAppearanceLoaded:connect(function(character)
		local upperTorso = character:FindFirstChild("UpperTorso")
		print(upperTorso.Parent)
		wait(1)
		print(upperTorso.Parent)
	end)
end)

Which prints out:

Player1
nil

CharacterAppearanceLoaded should only fire after the character has been rebuilt and all references to body parts are permanent.

2 Likes

I’m also having an issue with CharacterAppeaanceLoaded using R15.

Gif

The player should respawn and always have the caveman clothing on.
Imgur: The magic of the Internet

Code:

Player.CharacterAppearanceLoaded:connect(function(Character)
		print(Character.Name.." - Appearance Loaded")
		
		local Pants = Character:FindFirstChild("Pants")
		local Shirt = Character:FindFirstChild("Shirt")
		
		
		if not Pants then
			Pants = Instance.new("Pants")
			Pants.Name = "Pants"
			Pants.Parent = Character
		end
		
		Pants.PantsTemplate = "rbxassetid://446432753"
		
		if Shirt then
			Shirt:Destroy()
		end
		
	end)

This definitely needs to be fixed, I can repro the problem easily so I will add a task to fix it.

There are few weird things here that should be fixed.

You are wearing avatar animations, right? There is an issue with how the CharacterAppearanceLoaded signal fires for Avatar animations currently (I only discovered this from running the repro code @EchoReaper provided). It causes the signal to not fire when all the character assets are loaded. I’ll prioritize getting this problem fixed ASAP. Does your code work without any avatar animations equipped?

Why is the clothing added to the dead character? This isn’t done somewhere in your code, right? Sometimes after your character dies you can see it flicker grey for a second, it looks like there is a problem in the character loading code that’s causing this. I’ll also look into that issue.

3 Likes

Same thing happens with default animations.

This is the only code in the game that changes the players clothes.

I released the fix for CharacterAppearanceLoaded with avatar animations and this code now works for me. No update on the overall bug yet but I should get to it next week.

2 Likes

It looks like there is still avatar reloading going on after CharacterAppearanceLoaded. Using the following repro code, we can see that while the UpperTorso is not replaced after CharacterAppearanceLoaded fires, it is re-parented:

game.Players.PlayerAdded:connect(function(player)
	player.CharacterAppearanceLoaded:connect(function(character)
		local upperTorso = character:FindFirstChild("UpperTorso")
		local oldParent = upperTorso.Parent
		
		upperTorso.AncestryChanged:connect(function()
			print("UpperTorso moved from", oldParent:GetFullName(), "to", upperTorso.Parent:GetFullName())
			oldParent = upperTorso.Parent
		end)
	end)
end)

Output: UpperTorso moved from Workspace.EchoReaper to Workspace.EchoReaper


It’s being re-parented to the same parent, and this is breaking all joints attached. This happens for all body parts as far as I can tell.

I don’t think the UpperTorso is being re-parented, the ancestry is being changed but this is because the character model is being parented to Workspace.

I think this code shows what is going on better:

game.Players.PlayerAdded:connect(function(player)
	player.CharacterAppearanceLoaded:connect(function(character)
		local upperTorso = character:FindFirstChild("UpperTorso")
		local oldParent = upperTorso.Parent and upperTorso.Parent:GetFullName() or "nil"
		
		upperTorso.AncestryChanged:connect(function()
			local newParent = upperTorso.Parent and upperTorso.Parent:GetFullName() or "nil"
			print("UpperTorso moved from", oldParent, "to", newParent)
			oldParent = newParent
		end)
	end)
end)

Output: UpperTorso moved from TheGamer101 to Workspace.TheGamer101

You’re right – that’s what it was. My bad. Updated repro:

Repro Code:

game.Players.PlayerAdded:connect(function(player)
	local character = player.CharacterAppearanceLoaded:wait()
	character.AncestryChanged:wait()--Wait to be parented to Workspace
	print("Loaded")
	
	local hand = character.RightHand
	local part = Instance.new("Part", workspace)
	local weld = Instance.new("Weld", hand)
	weld.Part0 = hand
	weld.Part1 = part
	
	weld.AncestryChanged:wait()
	print("Weld destroyed")
end)

Output:

Loaded
Weld destroyed


I assume it's some internal mechanism that is running after CharacterAppearanceLoaded fires that clears out the joints.

I can reproduce this, I’ll file a bug and fix it as soon as possible.

2 Likes