Add root motion to root bone from pelvis bone animation (for Mixamo/marketplace animations)
This will only work with animations that are not in-place animations and you’ve actually got root motion like movement on the pelvis bone. It also assumes a UE4tools rig, maybe it works with others but I haven’t tested it with anything else. Also note that this will only work if you’re removing the extra root bone in your rig, either by renaming the Blender rig to “armature” or using the old FBX exporter hack.
- Retarget a Mixamo animation to your UE4tools rig (use the method in the post above).
- Open the newly retargeted animation and do Create Asset - Create Animation - Current Animation - Preview Mesh.
- Export the animation that was created to an .fbx by right clicking it and selecting Asset Actions - Export.
- Create a new .blend file and either append your rig or create a new UE4tools rig if you’re using the default setup anyway.
- Select the rig and run the following script. You paste it in a text editor and press Run Script. Note that the script assumes the rig imported from the .fbx name had the name “root” (because that’s the default name if your top bone name is “root”), otherwise you’ll have to manually edit that in the script.
import bpy
rig = bpy.context.selected_objects[0]
target_rig = bpy.data.objects'root'] #your target rig should have the name root if exported from UE4 preview exort (retargeted export)
bpy.ops.object.mode_set(mode='POSE', toggle=False)
i = 0
for layer in rig.data.layers:
#set all armature layers to be visible
rig.data.layers* = True
i+=1
bpy.ops.pose.select_all(action="SELECT") #select all pose bones
pose_bones = bpy.context.selected_pose_bones
for bone in pose_bones:
for constraint in bone.constraints:
constraint.influence = 0 #temporarily disable all constraints
ignored_bones = ("CS", "IK","ik") #ignore ik/control bones
for bone in pose_bones:
if bone.name.startswith(ignored_bones) == False: #not ignored bones - continue
if bone.name.startswith("root"):
bone.constraints.new(type="CHILD_OF") #add a special constraint to the root bone
bone.constraints"Child Of"].target = target_rig
bone.constraints"Child Of"].subtarget = "pelvis" #we're copying the pelvis transforms
bone.constraints"Child Of"].use_rotation_x = False
bone.constraints"Child Of"].use_rotation_y = False
bone.constraints"Child Of"].use_rotation_z = False #disable rotation - we don't want to copy the rotation of the pelvis (original pelvis already does this)
context_copy = bpy.context.copy()
context_copy"constraint"] = bone.constraints"Child Of"]
bpy.context.active_object.data.bones.active = bone.bone
bpy.ops.constraint.childof_set_inverse(context_copy, constraint="Child Of", owner='BONE') # set inverse - resets the root bone to original location
else:
bone.constraints.new(type="COPY_ROTATION") #add an empty constraint for now
for constraint in bone.constraints:
if constraint.type == "COPY_ROTATION":
if constraint.target == None: #make sure we're accessing the empty constraint
constraint.target = target_rig
constraint.subtarget = bone.name #set the target bone to the same name as the selected bone
- The UE4tools rig should snap into place. Playing back the animation should work.
- Run this second script to set the frame start and frame end for the scene.
import bpy
rig = bpy.context.selected_objects[0]
target_rig = bpy.data.objects'root']
action = target_rig.animation_data.action
bpy.data.scenes[0].frame_start = action.frame_range[0]
bpy.data.scenes[0].frame_end = action.frame_range[1] #set frame ranges for the animation
- Export the skeleton and set the skeleton to the skeleton of your character in UE4. You should now have root motion! If you’re doing some crazy rotations in your animations it might not work because I disabled rotation on the root bone. This way it only moves and has a fixed rotation which is probably a good idea in most cases.
After you’ve run the first script once you don’t have to touch it again. Just save the .blend file and run the second script when you’ve got a new animation. To import more animations import the animations, select the “root” rig, open the dope sheet, go to the action editor and choose the new animation from the other rig/animation you imported. Then you can delete the extra rig.
You may notice that you’re getting hitching in the animations if you’re using low quality animations. To make sure it loops correctly in UE4 you can edit the animation in Blender.
Making sure animations loop correctly (use in case of hitching for feet etc)
- Select the “root” armature and enter pose mode.
- Go to the first frame of animation, select all of the bones and do Pose - Copy Pose.
- Go to the frame after the last frame (the one without a yellow keyframe line), do Paste Pose and press “i” and choose LocRot.
- The root bone (pelvis bone for Mixamo based animation) will be at the wrong location. Look at the two frames before the last keyframe you created and see how much the root bone moves.
- Go to the next to last frame and copy the root bone location for the axis it’s moving in.
- Go to the last frame and paste the root bone location, then add the difference between the frames before so it moves at a constant pace.
- Run the second script again and export the animation. It should now loop better.