- Home /
How to have swappable Character Clothing - 3D Model & Meshes / Textures
I'm relatively new to Unity and learning an awful lot from everyone here and I am looking for a recommendation on the best way to add changeable clothing to a 3d desktop rpg game and have some concerns below. I am using Blender for modelling.
Due to clothing needing to extrude from the body I am going to need meshes for each piece of clothing. I would imagine I need to make these child objects of my base character mesh, animate and weight paint etc so they animate properly and hide these child objects. Concerns would be that my Character model would be huge with all the clothing if I add a lot of variations, and I can't find any tutorials on how I should be doing this. If my meshes are separate and loaded as new game objects, I am unsure how I attach these to the armature and maintain the vertex weightings for deforms so it still works in Unity. Can anyone give some guidance or point me to a tutorial or tutorial series?
For additional information, due to being an RPG I want to be able to script changing of clothing within my scene as a character equips items, and I thought of a list database of models with armature to attach to, mesh file location, and visible etc so I can toggle clothing on and off but unsure if this is achievable. The game would only have 1 character changing clothing.
Look forward to hearing your thoughts, as I want to learn how to achieve this rather than attack the asset store and buy something pre-done as this doesn't really help me develop my knowledge.
Answer by Cherno · Apr 24, 2015 at 05:14 PM
Here is the code for making an object with a SkinnedMeshRenderer component use another object's rig:
Shared skeleton and animation state
void Start () {
SkinnedMeshRenderer targetRenderer = m_attached.GetComponent<SkinnedMeshRenderer>();
Dictionary<string, Transform> boneMap = new Dictionary<string, Transform>();
foreach( Transform bone in targetRenderer.bones )
{
boneMap[bone.name] = bone;
}
SkinnedMeshRenderer thisRenderer = GetComponent<SkinnedMeshRenderer>();
Transform[] boneArray = thisRenderer.bones;
for(int idx = 0; idx < boneArray.Length; ++idx )
{
string boneName = boneArray[idx].name;
if( false == boneMap.TryGetValue(boneName, out boneArray[idx]) )
{
Debug.LogError("failed to get bone: " + boneName);
Debug.Break();
}
}
thisRenderer.bones = boneArray; //take effect
}
In your 3D modelling application, you create one rig and animate it as usual. However, not only the "naked" character model will be bound to this rig, but rather every piece of clothing (at least those that need to deform) will as well, and exported seperately.
In Unity, you then use the script to assign the rig of the naked character object to the clothing object. A database of clothing should be no problem. It can take the form of a Dictionary where string is the name of the item and ClothingItem is a custom class that holds the things you already mentioned, such as the prefab, offsets, etc.
Really helpful Cherno, Thanks for confir$$anonymous$$g my thoughts on how I can handle this and the script is exceptionally helpful. Thank you.
You're welcome. I think since finding this thread, I must have posted the link 25 times already :)
Important: Notice this possible caveat:
Weightless bones don't get added to Skinned$$anonymous$$eshRenderer bone array?!?
Can you explain how to get this working within Unity? I have a completely naked character rigged. He works in Unity. His rig (bone hierarchy) all show up fine within Unity too. Now I create a helmet for the character , I do the weighting inside 3DS max using the same rig. Then I export the helmet separately. Firstly - my FBX still for some reason contains the bone hierarchy. If i remove this in max , my helmet no longer becomes a Skinned$$anonymous$$esh. Secondly, after dragging the helmet into the scene on my character, it does automatically place the object in the correct place. But adding this script to my helmet has no effect. If i remove the bones inside the helmet hierarchy , the helmet itself just vanishes. What am I doing wrong here?!
Thanks
The clothing model needs to be imported as a Skinned $$anonymous$$eshRenderer as well, of course. Then, just have the two objects seperate in your scene (the rigged character and the rigged clothing item). Add the script to the clothing item, and assign the relevant variables (m_attached, in the case of the script above, referring to the character object). $$anonymous$$eep in $$anonymous$$d that bones with no vertex weights assigned to them can lead to problems, as detailed in the linked thread.
This is great! What would be the best way to make the new skinned mesh renderer independent so that I can delete the original.
When I do this with the existing code, the animation stops - I think because the new mesh is still using the bones list within the old mesh
No SR can be deleted.
You effectivels have two, which both use the same bones. that means that only the bones of the ones that are no longer needed (those from the clothing model or whatever) can be deleted.