Remove players hats excluding hair

So say I want to remove accessories. I would simply do

local humanoid = character:WaitForChild("Humanoid")
humanoid:RemoveAccessories()

The problem is, this would remove EVERYTHING. What if I just wanted to remove hats, not hair? How would I do this? I would like the players to keep their hair, but not the hats.

If anyone could help me do this, that would be great. I really don’t know why I am having trouble.

.
Thanks for helping!
Alex :slightly_smiling_face:

10 Likes

This is fairly difficult to do, since there’s no way to determine the difference between one hat or another other than names. The only way I can think of would be to build a hair library and scan it when a player joins and whitelist the contents.

You could POSSIBLY use string.find() to scan Accessory names for “hair”, but this almost certainly won’t cover all of the hair accessories.

6 Likes

You could take the hair move it to replicatedstorage and then move it back

1 Like

But how would I move the hair if there is no way to specify it?

3 Likes

I really do think this is impossible, there is no way to distinguish between hats and hair.

1 Like

You can check if the name of the accessory contains the word "hair,’ but not all hair accessories are guaranteed to contain the word hair, or a name at all, for that matter.

hair accessories have an attachment that signifies them as being hair. just loop over the children of character, and if it’s an accessory that doesnt contain this attachment, destroy it.

edit: specifically, the “HairAttachment” located under the accessory’s handle

5 Likes

Actually, now I think about it, presuming you allow players to use their Roblox avatar in-game, you haven’t yet modified their appearance, and you’re doing it from a server script, you can load the HumanoidDescription of the player using Humanoid:GetAppliedDescription(), parse the HairAccessory property (using string.split), loop through each asset and load it via the InsertService, and compare names of the currently worn accessories by the character with the name of the inserted asset.

Quick, horribly made, script demonstrating what I mean:
local function removehair(player)
	local char = player.Character
	local desc = char.Humanoid:GetAppliedDescription()
	
	for _, hair in next, string.split(desc.HairAccessory, ",") do
		local asset = game.InsertService:LoadAsset(hair)
		
		if (char:FindFirstChild(asset:GetChildren()[1].Name)) then
			char[asset:GetChildren()[1].Name]:Destroy()
		end

		asset:Destroy()
	end
end

removehair(game.Players.ClockworkSquirrel)

image

Obviously, there’s still a chance that two accessories might have the same name, but you can compare further properties of the accessory to check they’re the same (such as the MeshId, part size, etc.).

Edit: @Camper0008 is right, however, there is a specific HairAttachment which you can look for in each accessory.

image

It really depends on how accurate you want to be with it.

9 Likes

this will only not remove items that have the word “hair” somewhere in them. (It wont remove it if the hair is named “Ravenhaired Charmer” for example.

for _, v in pairs(character:GetChildren()) do
if v:IsA("Accessory") and not string.match(v.Name:lower(), "hair") then
v:Destroy()
end
end
1 Like

Using this approach, ideally you’d use the Humanoid:GetAccessories() method, so that you’re only affecting accessories parented to the character and nothing else. And string.match should match “Ravenhaired Charmer” regardless, as it still contains the word “hair.”

image

I’d really recommend using the other method I posted, or Camper’s solution, however.

oh oops didnt notice that lol. Yeah a better example would be “Blue Swoosh” or something like that

1 Like

That’s very true, and it’s all dependant on how precise @OP wants to be with their removal. However, assets’ Accoutrements aren’t necessarily named the same as what’s displayed in the catalogue. Blue Swoosh, for example, is actually named “SpikeySwooshHair.”

Although, to prove your point, Beeism’s “Baseball Cap Cutie” is classed as a hair accessory, yet has the name “BaseballCapCutieAccessory.”

exactly, there is no really good way to do it other than making a list of hair accessories that he wants to be classified as one. A possible way to do it is to go on the roblox catalog and go to hair accessories, then put every hair accessory without the name “hair” in the list.
Then, use this code

local hairAccessoriesWithoutHairInName = {
['Baseball cap cutie'] = true;
['RandomAccessoryNameHere1'] = true;
['RandomAccessoryNameHere2'] = true;
['RandomAccessoryNameHere3'] = true;
}

for _, v in pairs(character:FindFirstChildOfClass("Humanoid"):GetAccessories()) do
if not string.match(v.Name:lower(), "hair") and not hairAccessoriesWithoutHairInName[v.Name] then
v:Destroy()
end
end
1 Like

You should be using string.find(), as it will find the word hair anywhere in the hat name, but this method isn’t good. As @Camper0008 has pointed out there is an Attachment called HairAttachment, so simply looking for that will be a solution.

local children = character:GetChildren()
for i=1, #children do
     local instance = children[i]
     if (instance.ClassName == "Accessory") then
          if (not instance.Handle:FindFirstChild("HairAttachment")) then --it's not hair!
               instance:Destroy()
          end
     end
end
4 Likes

What if you grabbed the item IDs of the player’s accessories, and call the :GetProductInfo() method of MarketplaceService with each ID, then see if the AssetTypeId equals 41 (which is HairAccessory)

I just tested this idea, and it worked like a charm.

8 Likes

yes, string.match does find it anywhere in the name

“character” has an error. (30 charsss)

1 Like

sorry if i’m being late but every type of accessory has it’s own “unique” position (try math.floor to determine more less where it is) on character for humanoidrootpart and we can very fastly determine what type of accessory it is. It might be inaccurate sometimes but it’s very fast.

1 Like

Thank you, that’s an awesome idea! Do you happen to know what is the ID for Face Accessories?

You could call the :GetAppliedDescription() method on the character’s humanoid to grab a HumanoidDescription object, which has properties such as the IDs of all FaceAccessories that they’re wearing:

https://developer.roblox.com/en-us/api-reference/class/HumanoidDescription

1 Like