First off, I don’t know if this will work in every situation. In my case, I changed the source fbx humanoid rig a bit for creating animations off of mixamo and ended up with great animations but also with the following problem. I was always able to fix it that way when the animation was from mixamo. Might work somewhere else as well:
Assume ending up having an animation where all keyframes which are supposed to be set for the root bone of an avatar are instead set to the root transform, and as a consequence of this, the character will always be fixed to a world position while in the animation.
Here is what I do in order to fix the files.
-
Make a backup of the animation.
-
If there are keyframes for the root bone already, which only have a keyframe with Vector3.zero for position and Quaternion.identity for rotation. Delete all these entries entirely.
-
Save the animation and do File → Save Project.
-
Copy the animation somewhere outside the unity project and only edit it from here on out in the copy outside of the project! (Unity could mess up the file in the whole editing process by reimporting).
-
Open up the animation file in a text editor with a find and replace option (Visual Studio works fine).
-
Search this term :“path: \n” and replace it by “path: root\n”. The whitespace in the search strings are important!
→ The “root” refers to your root bone in the replacement. If your root bone transform is named any other way, you have to use that name instead there. -
At the bottom of the file there is an option “m_HasGenericRootTransform: 1”. Change it to “m_HasGenericRootTransform: 0”
-
Save the animation.
We ain’t done yet!
The next thing is where the magic comes in because the animation does not yet bind the keyframes to the correct transform. You have to find the reference id for your root bone and replace it at the correct position.
Do the following:
- Create a new animation for your character that only moves and rotates your root bone by any amount. For convenience, it should only be one keyframe!
- Save the animation and do File → Save Project.
- Open up the new animation and search for the string “m_ClipBindingConstant:”. You will see something looking like this:
...
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 385153371
attribute: 1
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
- serializedVersion: 2
path: 385153371
attribute: 4
script: {fileID: 0}
typeID: 4
customType: 4
isPPtrCurve: 0
...
The entry with “path: ” is your root bone reference id. Copy this number.
- Go back into your target animation and search again for “m_ClipBindingConstant:”. You will find something similar to this:
...
m_ClipBindingConstant:
genericBindings:
- serializedVersion: 2
path: 0
attribute: 1
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
- serializedVersion: 2
path: 0
attribute: 2
script: {fileID: 0}
typeID: 4
customType: 0
isPPtrCurve: 0
...
The entries with the string “path: 0” are referencing the root transform at the moment. Replace the 0 by the number you have saved in the last step.
- Save the file and let unity import the file by putting the file somewhere into the asset folder.
Everything should be replaced now.
By the way, all this is just stuff that I found by comparing data. The term “reference id” that I used is probably nothing any unity dev would understand, or probably isn’t even what it is. These are all just assumptions based on the data that I analyzed and based on that it worked for me in the end.