- Home /
How to alter the mesh of an animated prefab without breaking prefab or losing animations?
Hi guys,
I'm a new Unity user so it's possible this is a simple, stupid problem I'm having. I feel like I have tried everything... Here's the situation:
I have an animated .FBX from the Asset Store, and I've made some minor changes to the mesh in Blender. I've saved this again as an .FBX and imported it to Unity. The mesh changes are minor and wouldn't break any animations, it all plays back perfectly in Blender.
Now, this Asset from the Store ALSO came with a demo Prefab which is all set up with a script and animations. So, I can either just simply switch out the mesh into this prefab (seems like the simplistic option), OR I can go about re-building a new prefab with this new mesh and setting up the dozens of animations and a few scripts which came with it.
So, going with the first option, how do I switch this new mesh into the prefab I have which is already set up with animations? If necessary I can provide screenshots to help explain...
Thanks for reading.
Answer by meat5000 · Oct 02, 2015 at 08:07 AM
As far as I am aware, this will not work. Animation data requires vertex information, vertex number and position etc. If this information has changed (and hence is no longer valid) the animation will break.
The easiest way to achieve this (as far as I am aware) is to use the Animation Retargetting feature of Unity which requires sharing an Avatar or an Animation Controller between two separate models.
Only Humanoid is officially supported but I have had success in Generic using certain methods with compatible rigs.
Hi meat, Thanks for your reply!
I will definitely try this Animation Retargeting. I previously watched some videos where this was done on humanoids and it looked very easy, hope it holds up as well with 'Generic' avatars. $$anonymous$$y two rigs are almost certainly compatible-- my mesh changes are super $$anonymous$$or and would not effect any armatures to my knowledge.
I realized that I may be fra$$anonymous$$g my problem incorrectly. Like I said before, my altered model exports from Blender fine with all the animations intact. So rather than just replacing the mesh in the prefab, I could replace the entire .FBX which would import animations as well. Does this change anything about your answer?
I'm a little baffled--How do game studios deal with this problem if they have a game build but want to make a change to a character model? It seems an obvious workflow thing that Unity should offer. I suppose Avatars may be the answer.
There are certain things to consider.
With retargetting it is important that bone structure matches. This should no be a problem in your case. You should also make sure that the new mesh has the exact same number of vertices. The real trouble with Vertex information with regard to animation is with the Weight information ( how much the vertex is influenced by the bone ).
If you plan to continually add models the scenario is tricky but if you have a predefined amount of meshes you want to control with a rig you could consider adding and animating ALL meshes on separate layers in blender and simply enabling/disabling the one you want. i.e export all meshes together parented to the same rig in the same FBX.
Otherwise retargetting should work. One method (I dont remember which) causes strange scaling errors if the model is larger or smaller than the previous one whos avatar it uses. You will see this in the form of a stretched out character or a crushed one.
So the first way is to use the avatar of another model. The second way is to Use the Animation Controller for a model (as far as I can remember).
Remember that if you make such changes to a model at runtime you should use the animator Rebind function.
Hope I actually addressed your query here :/
I don't see a reason why switching out the mesh on the Skinned$$anonymous$$eshRenderer shouldn't work as long as the bone structure stays the same. The skinning information (by which bones a vertex is affected) belongs to the mesh class itself (See boneWeights). The actual bone array is stored internally in the Skinned$$anonymous$$eshRenderer (See bones).
When i said the bone structure stays the same i mean exactly the same. No additional bones and no removing or rena$$anonymous$$g. It's also recommended to not change the bone positions / rotations. Animations work by applying absolute values to the bone rotations (and some times positions as well).
As long as the bone order in the array stays the same you should be able to just replace the mesh in the Skinned$$anonymous$$eshRenderer
And Rebind ;)
You are able to swap out a mesh if everything matches. However, unless your weighs are mostly 1 or 0, odd things will happen to some of the geometry based on the weight data. In most cases this may not be relevant but if your guy's elbow spikes start bending funny (for example), you know why :P
Retargetting is definitely preferred. You are able to play with scale in one of the methods without spurious effects.
OP: Play with S$$anonymous$$R, retargetting->Avatars, retargetting->AnimController and see which works best in your case.
Think of a system like $$anonymous$$ixamo, where they use 1 generic rig for ALL their models and hence they can sell individual animation that will work on all models. This works as everything is made to 1 standard.
Uhm rebind? Do you mean the bindposes? Those also belong to the mesh and just create the link between the base pose and the bones. Again, as long as the bones stay the same you can replace the whole mesh with different vertices bound to different bones and it should still just work out of the box.
There is a chance that when you import two different models which have the same bone structure that the bone order does't match. As far as i know there's no common rule in which Unity lays out the bones in the bones array. If the order has changed you either have to fix the order in the bones array of the Skinned$$anonymous$$eshRenderer, fix the order in the boneWeights array of the $$anonymous$$esh (by changing the bone indices) or simply use the Skinned$$anonymous$$eshRenderer that got imported with the new $$anonymous$$esh.
I don't think the relatively new copy&paste component function in Unity work here. It's possible to copy the Skinned$$anonymous$$eshRenderer component over, however the bones array won't reference the correct bones anyways. So the a common way is to simply copy the whole GameObject including the bone structure. That's why it's usually a good idea to put the actual model (with Skinned$$anonymous$$eshRenderer) as child of your actual player object. It simplifies the exchanging of the whole model.
I haven't used imported animations recently. When i worked with animations there wasn't support for "root motion" (which let an animation actually move the player). However i think(guess) that's what the "root bone" variable is good for. I would need to do some test on my own, but i don't have an animated model at hand and don't really have time for that ^^.