Blender animation to UE4 - Weird rotation

Hello, I posted this question in answerhub and was recommended to also post it in the forums for a second opinion. Instead of copy pasting the entire question, it makes a little more sense to link to the answer hub question:

Does anyone here have any thoughts on this issue?

Thanks,

Robert.

Read through this thread. I also made a Answerhub report here. Told me to use the version 6.1 format.

If I’m correct in my assumptions about your issue here, I think this bug is the same bug that show up in just about every exported animation from Blender fbx io. Most times, if there is no animation in a parent bone, the child bones take some of the transforms of the parent bones. What you can try to do is try adding a tiny bit of change to each bone to force some change, then re-export. Keying is not enough. There needs to be actually changes in value between any two keyframes.

Oh yeah! I read your post (23 hours and counting working on this issue before posting a question…), I couldn’t determine that it had enough information to help my issue.

How would I efficiently add a tiny amount of change to every bone? I read about some people writing python scripts but I am not good enough at programming to be able to just go ahead and do that.

I don’t have time to test just yet, but I don’t think the 6.1 format will be acceptable for my purposes, I’ll update this post once I do test that.

For something simple, you can simply just manually key change in each bone.

Writing a script would be the more efficient way. You’d need to write a script that would iterate through each bone in pose mode and add some change although you’d need some understanding of linear algebra and vector math. I wrote a small script for my personal use that isn’t well commented and the algorithm may be suspect. However, if the version 7.4 format is necessary, then I’ll paste my script for you to use and modify. I would’ve used version 6.1, but I need the blend shapes that the Blender 7.4 fbx output provides.

For the script, it’s not really an install-able script since I only use it personally based on my workflow. I could write the script as a real install-able Blender script but I haven’t bothered since I’m hoping for an official fix to the bug sooner or later. I just run the script using a text window in Blender. Open up a Blender window, create a new text data block with the “+” sign, paste in the script, and press the “Run Script” button with your armatures selected at preferably an already keyframed pose. That will run through all your armatures selected, pose each bone a small amount and key the pose. Basically, I animate first. Then after I animate, I apply the script to one of the keyframes. If the animation is a loop (like a walk, run, or idle), I apply the script to one of the keyframes in the between the first and last keyframes as to not dirty the first and last keys. In truth, the changes made by the script will not be visible to the naked eye so you can drop the dirty frame anywhere as long as it doesn’t mess up the timing on your animation.

Note: The Blender script interpreter is based off Python. Whitespace matters. If the script doesn’t work after being pasted, you’ll probably need to format the script so that the whitespace is correct. Hopefully, the CODE tag here will preserve the whitespace so you won’t have fix whitespace issues.


import bpy
import mathutils

# Create translation matrix to move translatable bones a trivial amount
mat_loc = mathutils.Matrix.Translation((0.0001, 0.0001, 0.0001))

# Create rotation matrices to rotate each bone a small amount on each axis
# TODO: Possibly better to create matrix from quaternion, my linear algebra sucks
mat_rot_X = mathutils.Matrix.Rotation(0.000001, 4, 'X')
mat_rot_Y = mathutils.Matrix.Rotation(0.000001, 4, 'Y')
mat_rot_Z = mathutils.Matrix.Rotation(0.000001, 4, 'Z')

# Create a transform matrix to apply translation and rotations
transform = mat_loc * mat_rot_X * mat_rot_Y * mat_rot_Z

# List to hold all selected armatures
armatureList = ]

# Set selection mode to OBJECT to be able to obtain object reference for each armature
bpy.ops.object.mode_set(mode='OBJECT')

# For each object selected, check if object is an armature
# and if so, add to armatureList
for obj in bpy.context.selected_objects:
    if(obj.type == 'ARMATURE'):
        armatureList.append(obj)
        
# Iterate through each armature and
# iterate through each pose bone
# Key each bone based off precomputed transform matrix
for armature in armatureList:
    armature.select = True
    bpy.ops.object.mode_set(mode='POSE')
    for bone in armature.pose.bones:
        bone.matrix = bone.matrix * transform
    bpy.ops.pose.select_all(action='TOGGLE')
    bpy.ops.anim.keyframe_insert_menu(type='WholeCharacter')
    bpy.ops.object.mode_set(mode='OBJECT')

Thanks for the script code, I’m familiar enough with blender’s text editor and python syntax that I should be able to debug any issues I create when attempting to use this code.

It didn’t work, at least my initial try didn’t work. I’ll try again tomorrow.

Seems like there was movement on the Blender side. Might be worth trying out the latest build and seeing if it fixes things for you.

https://developer.blender.org/T41719

If it works, that means likely the fix will be in the next stable release. I looked at the commit and it seems like the new code changes will do what my script is doing by exposing an extra option (turned on by deafult) to “force” keying all bones. Bastien (fbx/io maintainer) has noted that the change is a hack, but it’ll probably work for our uses. I tried exporting a few troubled rigs and things look good so far.