Cyaoeu's bag of Blender tricks

In this thread I will list some tips and tricks regarding Blender - UE4 workflows, one post for each technique. Eventually it will have information about a bunch of subjects like animation and scripting, but for now I just wanted to share how you could edit the FBX exporter in order to avoid an issue in UE4.

You’re free to share your own tips and techniques as well!

(huge list of topics and posts under those categories here later)

Export pipeline
How to fix: reimporting a single mesh from an .fbx with many meshes in it causes the mesh to turn into a huge mesh (all of the meshes in the .fbx combined)

Adding support for static mesh LOD export in Blender

Animation
Setting up perfect Mixamo - UE4tools retargeting using pose assets

Add root motion to root bone from pelvis bone animation (for Mixamo/marketplace animations)

How to fix: reimporting a single mesh from an .fbx with many meshes in it causes the mesh to turn into a huge mesh (all of the meshes in the .fbx combined)

Object names
In Blender when you duplicate an object, let’s say Cube, you get a new object with the name Cube.001. However when you export that file to UE4 the importer automatically renames the mesh to Cube_001 because UE4 does not support periods in filenames. This is fine, but what happens when you try to reimport a renamed file? In this example you would reimport the mesh Cube_001, and UE4 then looks in the original .fbx for Cube_001, but it doesn’t exist, since it was originally named Cube.001. So UE4 says “screw it, better get everything then” or something like that. Better than crashing I guess!

You can fix this by editing the binary FBX exporter in Blender. You can find that in BlenderFolder\2.78\scripts\addons\io_scene_fbx, there’s a file called export_fbx_bin.py which is what you want. First save a duplicate of the file if anything goes wrong, then edit the file by searching for the row:


fbx_data_object_elements(objects, ob_obj, scene_data)

It should be line 2791 or around there. Then, right before that line, add this:


ob_obj.name = ob_obj.name.replace(".","_") #replace dots in object names with underscores

Important: first off, make sure you’re using the same spacing! Which means, only use spaces and not tabs. Or you’ll confuse the python code. Secondly the code needs to be at the same “depth”, so it should be aligned with the next row vertically.

When you’re done save the file, and try exporting an .fbx file with objects that have periods in their names. Try importing that file back into Blender and you should see the periods have been replaced with underscores, which is what you want. Now you should be able to reimport Blender meshes with periods in the name without strange things happening!

Mesh names

Mesh names are only used in Import into level for now. Not really necessary until reimporting of single assets in Import into level actually works, but for when it does:

In the same file as above, search for me_key, me, free = scene_data.data_meshes[me_obj].
Add this under that line. me.name = me.name.replace(".","
")
That’s it!

thanks for share !!!

Morph Targets - tip: to export morph targets from blender and make recognizable for ue4, export FBX with version 6.1 instead 7.4… at least works for me!

Morph targets should work with 7.4 too, at least the binary exporter. At least mine do!

Setting up perfect Mixamo - UE4tools retargeting using pose assets

Not a Blender specific technique but I’ll put it here anyway. Note: recent UE4 version is required for the pose asset options in the retarget manager.

Getting the required assets (UE4 mannequinn, UE4tools rig and Mixamo rig)

  1. Upload a UE4tools rig to Mixamo. Get some animation (what animation doesn’t really matter), download it with a T-pose.
  2. In Blender import the mesh, we’ll call it UE4tools rig. It should import with a T-pose, but the rest pose should still be the original A-pose. Leave the T-pose on frame 1 and go to frame 2, in pose mode select all bones and reset rotations. Make sure all bones are selected and insert LocRot keyframes.
  3. Add the AnimStarterPack to your project, that way you get the UE4 mannequinn skeleton you need.
  4. Finally we’ll need a normal mixamo rig. Download a bunch of animations you want with a Mixamo character selected, for example Y-bot.
  5. Import the UE4 tools rig with animations. Import the Mixamo rig with animations as well.

Setting up the retargeting

  1. The most time consuming part is selecting the correct bones for the Mixamo rig. In the Mixamo skeleton select the retarget manager and pick Humanoid under Select Rig. Then for each bone select the correct target bone, this should be pretty straightforward since you can see the hierarchy in the popup, just go from up to down, shoulder to hand and so on. Don’t forget the fingers under Advanced!
  2. Repeat this process for the UE4 tools skeleton and the UE4 mannequinn skeleton. This should be a lot easier because they already have the right names, so you only need to pick Humanoid and the rest should be done automatically for you.
  3. Finally for each skeleton set up the Preview Mesh under Skeleton. Just choose the mesh in the dropdown.

Creating and using pose assets in retargeting in order to avoid manually changing the base pose (which takes a lot of time)

  1. You should have a 2 frame animation for the UE4tools rig with a T-pose and an A-pose. Right click this animation and choose Create - Create Pose Asset. Next in the skeleton, in the retarget manager click Modify Pose and there should be a field saying None - click that and choose the pose asset. Choose the first pose which should be the T-pose.
  2. Now right click the 2 frame animation again and retarget it to the Mixamo skeleton. The skeletons should have the same T-pose in the retargeting preview.
  3. Now you’ve got the 2 frame animation with a T-pose and an A-pose for the Mixamo skeleton as well. Repeat 1. for the Mixamo skeleton, but instead of choosing the first pose, choose the second with the A pose.
  4. In the UE4tools skeleton you don’t want the T-pose for retargeting anymore, so go to the retarget manager and click Modify Pose and then Reset.

Retargeting animations

  1. You will need to retarget animations from the Mixamo skeleton to the Mannequinn skeleton, then finally to the UE4 tools rig. This will make sure you don’t run into strange issues where animations play in the wrong orientation for example.
  2. Select the Mixamo skeleton animations and retarget them to the UE4 mannequinn.
  3. Select the newly retargeted UE4 mannequinn animations, retarget them to the UE4 tools rig.

That’s it! From this point on you can import any Mixamo animation by importing them to the Y-bot Mixamo skeleton and retargeting them to the UE4 Mannequinn skeleton and then finally to the UE4tools skeleton.

A final point - if you’re seeing the animation flying a bit above the ground this can be caused by the physics asset. In the UE4 tools rig make sure the physics bodies for the feet are lined up correctly. By default they are a bit too big and too low, just move them up and it should look better.

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.

  1. Retarget a Mixamo animation to your UE4tools rig (use the method in the post above).
  2. Open the newly retargeted animation and do Create Asset - Create Animation - Current Animation - Preview Mesh.
  3. Export the animation that was created to an .fbx by right clicking it and selecting Asset Actions - Export.
  4. Create a new .blend file and either append your rig or create a new UE4tools rig if you’re using the default setup anyway.
  5. 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


  1. The UE4tools rig should snap into place. Playing back the animation should work.
  2. 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



  1. 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)

  1. Select the “root” armature and enter pose mode.
  2. Go to the first frame of animation, select all of the bones and do Pose - Copy Pose.
  3. Go to the frame after the last frame (the one without a yellow keyframe line), do Paste Pose and press “i” and choose LocRot.
  4. 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.
  5. Go to the next to last frame and copy the root bone location for the axis it’s moving in.
  6. 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.
  7. Run the second script again and export the animation. It should now loop better.

Adding support for static mesh LOD export in Blender

Credits to Pavel Křupala for this method. Blender does not have LOD support for UE4 by default but this can be added easily. This method will allow you to create an Empty object named “LOD_(objectnamehere)” which you parent your static meshes to and end up with a single LODed static mesh in UE4.

We’ll accomplish this by editing the binary FBX exporter in Blender. You can find that in BlenderFolder\2.78\scripts\addons\io_scene_fbx, there’s a file called export_fbx_bin.py which is what you want. First save a duplicate of the file if anything goes wrong, then edit the file by searching for the row:


null.add_string(fbx_name_class(empty.name.encode(), b"NodeAttribute"))

Comment out the line


null.add_string(b"Null")

by adding a # before it so it looks like this:


#null.add_string(b"Null")

Then paste this:


if empty.parent is None and empty.name.startswith("LOD"):
    null.add_string(b"LodGroup")
else:
    null.add_string(b"Null")

The if line should line up with the previous line.

If Blender was open close it and open it again. Next in Blender create an Empty object and name it LOD_(objectnamehere). The important thing is that it has LOD in the beginning of the name. Next you need to parent your objects to this Empty. Note that the order you parent the objects is important, parenting them all at once won’t necessarily work. Parent the objects one at a time, starting with LOD0, after that LOD1 and so on. The order in which you parent these objects will have an effect on the final LOD ordering in UE4.

Then export the objects (including the empty) and you should up with a single static mesh with LODs. That’s it!

Here’s a simple script to create the empty and parent everything automatically. It assumes you’re naming things with _LOD0, _LOD1, _LOD2 suffixes in the object names.



import bpy

flip = 0                                                          
empty = bpy.data.objects.new("empty", None)
bpy.context.scene.objects.link(empty)
for obj in bpy.context.selected_objects:
    if obj.name.endswith("_LOD0"):
        LOD0 = obj
    if obj.name.endswith("_LOD1"):
        LOD1 = obj
    if obj.name.endswith("_LOD2"):
        LOD2 = obj
splitname = LOD0.name.split("_")
empty.name = "LOD_" + splitname[0]
bpy.ops.object.select_all(action='DESELECT')
LODArray = [LOD0, LOD1, LOD2]
for LOD in LODArray:
    LOD.select = True
    bpy.context.scene.objects.active = empty
    bpy.ops.object.parent_set()
    bpy.ops.object.select_all(action='DESELECT')


Hi Cyaouu

Great info here.
Would you perhaps know how to go ‘the other way’? I want to take animations from the UE4 animation pack and use them on a character that was made in blender and has a Mixamo skeleton.
The Mixamo animations work fine in UE4 but when I try to retarget so that I can use the UE4 animations I either get a character that is just a couple of bones and who knows what else moving around and showing that it is microscopicly small or UE4 (4.17) crashes. I have tried many things but with little success

@cyaoeu

Blender 2.79a has some changes:

null.add_string(val.encode() if val and isinstance(val, str) else b"Null")

instead of null.add_string(b"Null")

Do we still comment out that new line to get it all working ?

Did you figure out what needed to be done for it to work with 2.79a? Would be nice to know.

I haven’t tried :o

In 2.79 we dont have to make changes in code, we have to add empty to scene and add custom properties to this empty:
fbx_type LodGroup

86e5edc3227e83d272b8fd3e94f7c2a4.png

@cyaoeu

By chance, have you tried LOD trick with Blender 2.8 and its FBX exporter ?

That doesn’t work for me :confused:

Nothing special is needed. Here is a test .blend for 2.79b: UE4_LODs_test279.blend - Google Drive (LOD order is wrong, but that’s Blender’s BS)

Make sure you have mesh, empty and custom properties checked in the FBX exporter UI in Blender.

So, what’s the fastest way to export in the correct LOD order. Tried renaming the LODs and parenting them in different orders, but the export LOD order stays the same.

https://forums.unrealengine.com/development-discussion/engine-source-github/1709564-fbx-blender-lod-name-import

Just a heads up for anyone having issues with the LODs being out of order - order of creation also causes issues. I had 3 LODs that I created out of order and couldn’t get it to export no matter what order I parented them in. I had to copy each object in LOD order then reparent them so they were created in the correct order.