If it’s just intended to be simple character customisation with catalog items you might be interested in using HumanoidDescription. This can work for both allowing users to enter in their own ids or you setting up a list of buttons for users to select. In the latter case you will need to keep ids and the accessory type handy so you can match the id to the appropriate property.
The xAccessory propertie are CSVs (comma-separated values), so whenever you want to add an accessory there you will want to concatenate a new string there containing the id. Just as a rough example, here’s how you’d add The Raven to a user’s shoulder accessories:
local description = humanoid:GetAppliedDescription()
description.ShouldersAccessory = description.ShouldersAccessory .. ",20945145"
In terms of case B, that one I find is pretty simple and I love to use it when I want to add extra items to players. I set up an accessory that follows Roblox convention (Accessory → Handle → Attachment, where Attachment has the same name of one in the character - for example, a hat will have HatAccessory or a hair will use HairAccessory) and then just call AddAccessory with it. This I find is the best for those click-to-wear-hat use cases.
Regarding inserting assets: when you call LoadAsset it returns a model but it doesn’t parent it anywhere meaning its a nil-parented asset, so you can’t find it because it doesn’t actually put itself anywhere. It loads in the asset and gives back a reference to the model that you can use later. For example, you can hold the reference in a variable so you can interact with it after loading it:
local hat = InsertService:LoadAsset(20945145)
hat.Parent = workspace -- NOW it exists in the Workspace
As far as you’re concerned with loading assets from the catalog, the assets you insert will always be wrapped in a model, so the hat is inside the model which is returned to the script after the LoadAsset call. In the case of the above example, suppose you want to directly add the hat:
local hat = InsertService:LoadAsset(20945145):GetChildren()
This chains a few evaluations and at the end of them all gives back the result of those evaluations. For the sake of simplicity I omitted good practice with using LoadAsset and made some assumptions like that the id is valid but be sure to read the article so you can get some information on how to use it well. In English, this is what the above code does:
- Call LoadAsset, I want to load in an asset with the id 20945145.
- Now that I have a model, get all the children of it and then select the first one in that list.
(LoadAsset on hats return a model with one child, so the first in the list is the accessory.)
- Give that first child back to me as the hat variable.
Your hat variable now holds a reference to the hat you loaded in, which you can do whatever you like with it like changing its parent.
In terms of your sources about InsertService, I do not believe this applies to the UGC hat catalog. There is a security and privacy restriction that only allows you to insert assets that you or Roblox own. That being said, UGC accessories still relatively new and previously only the Roblox account could upload hats to the site.
With the above in mind, it’s safe to say the security rule didn’t apply to certain asset types because it was always the assumption that only the Roblox account would upload those asset types and not users. I wouldn’t bank on this not being changed in the future but until then, InsertService is a great way to load and add accessories without knowing their type. HumanoidDescriptions on the other hand do require you to know the type.
Hope that’s a sufficient explanation.