How to detect when all accessories are loaded onto a character?

Hello!

I have a duel system, players step on pads, where LoadCharacter() and :MoveTo() is applied to them.

I’m trying to create a custom forcefield, where the player’s body parts are highlighted and accessories and face are set to not visible. The code should run fine, however it seems it runs before accessories are loaded onto a character. I’ve tried using Player:HasAppearanceLoaded() and a small wait(0.1) but neither has worked, ideally the effect applies as soon as possible to make it look clean.

Miight suggest not using LoadCharacter(), but this is the most optimal way of ensuring a player’s backpack is clear and their health is full.

Here’s what I’m using:

local function beginDuel()
	local forcefieldDuration = 5 --math.random(2,4)
	print("Forcefield will last ".. forcefieldDuration .. " seconds.")
	for player = 1, #universePlayers do
		local playerCharacter = workspace:FindFirstChild(universePlayers[player].Name)
		local forcefield = Instance.new("ForceField")
		forcefield.Parent = playerCharacter
		forcefield.Visible = false
		for i,v in pairs(playerCharacter:GetChildren()) do -- CUSTOM FORCEFIELD ADDITION
			if v:IsA("BasePart") and v.Name ~= "HumanoidRootPart" then
				local highlight = workspace.BodypartsTest.Highlight:Clone()
				highlight.Parent = v
			elseif v:IsA("Accessory") then
				local handle = v:FindFirstChildWhichIsA("BasePart")
				handle.Transparency = 1
			end
			if v.Name == "Head" then
				v.face.Transparency = 1
			end
		end

	end
-- function continues
end

This is what happens:

This is what I want to happen:

I’m not sure if highlight is a good way to simulate a cool effect for a forcefield, so as a side-topic any suggestions for that are appreciated.
Novice scripter, so ways of optimization are always welcome too :slightly_smiling_face:

edit: uploaded images instead of imgur link

You can do something like this to ensure you get the accessories, but I’m curious to know if there’s a better way

local sp = script.Parent

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAppearanceLoaded:Connect(function(c)
		if not plr:GetAttribute('FF') then return end
		plr:SetAttribute('FF',nil)
		for i,v in pairs(c:GetChildren()) do
			print(v)
			if v:FindFirstChildWhichIsA('BasePart') then
				print'Handle found'
			end
		end
	end)
end)


sp.Touched:Connect(function(touch)
	if touch.Parent:FindFirstChild('Humanoid') then
		local plr = game.Players:GetPlayerFromCharacter(touch.Parent)
		plr:SetAttribute('FF',true)
		plr:LoadCharacter()
		
	end
end)

Edit: If hiding the accessories is all you wanted to do, you could also use Humanoid:RemoveAccessories(), Humanoid:ApplyDescription(), or Humanoid:ApplyDescriptionReset() after CharacterAppearanceLoaded

Have you tried listening for CharacterAppearanceLoaded?

I’m not sure what to make of the above code, there’s a lot of confusing things with attributes, which I’m not sure how they correlate to accessories under the Players service.

I may give RemoveAccessories() + ApplyDescription() a go.

edit: Have now given the above a go. ApplyDescription() has a delay which ends up circling back round to the problem. There’s no way of detecting how long this delay is.

I’ve tried the property version of that event, HasAppearanceLoaded, to no success unfortunately.

Have you tried doing something like this?

if not player:HasAppearanceLoaded() then
	player.CharacterAppearanceLoaded:Wait()
end

-- Rest of code goes here

I attempted something similar.

while not player.CharacterAppearanceLoaded do
   wait()
end

I just attempted your version, also to no success.
Quite funny, just did a print check, yup it outputs “true”, even though it’s not. It’s as if appearanceloaded is correlated to the character baseparts being loaded, not the accessories.

1 Like