Now that we have the objects exported and referenced in our scriptable object we can go ahead and build our characters.
For this, we first need a way to generically combine skinned meshes so we declare a function that will do just that. An important thing to note here is that this will only work if all the skinned meshes use the same texture but since all our character parts went through the atlasing part, this will not be an issue.
Unity has an API that will take care of most of the mesh merging but it does not work well when it comes to bone deformations. First, we allocate the mesh that will hold the result and a list of CombineInstance structs (Unity API). Note that this list is allocated inside the function here because it's easier to understand but like with any allocation that can be reused it should make use of a cache system.
Next thing we need to do is get the count of how many bones our meshes are bound to. Vertices are deformed by a maximum of 4 bones but the bone indices need to be common across our input meshes so we also make sure this is the case:
After this we run the regular Unity function to combine the meshes together:
The problem with CombineMeshes is that it acts as if every mesh will use completely different bones so the resulting geometry will use a number of bone indices for the weights that is equal to the number of bones times the number of meshes combined. In order to get around this, we go through the bone weights and fix the indices:
Because of the way Unity handles bones in skinned meshes, the resulting bind poses are also incorrect. Bind poses are transformation matrices for each bone which are used to define the exact transformation each bone is in when in the rest pose. This is the same as the bone transformations at the time of vertex weight painting in Blender. Fortunately this is really easy to fix. We just take the bind poses of one of the input prefabs and use that since the bones are all shared:
Finally, we need to create the final object. For this we again instantiate one of the prefabs and then edit it to use the correct mesh. We do not create an object from scratch because we also need to have all the bone objects created.
With this function out of the way, we can go ahead and build our animated character. First we take a structure that specifies which of the parts to use and a parent that will contain the final object:
Next, we assemble a list of the objects that we need to use. Again, 'objects' should be cached but is presented here like this to be easier to understand.
Next create our final object, and add the animator component to the first child of the root. This is because that object is the Blender armature so all animations are relative to it.
This is it. Our meshes are combined into a single one with all the bone deformations still working as intended. This way we only have one skinning computation to do and only one draw call to dispatch to the renderer for each character.