I have created a script in blender that batch exports FBX static mesh, textures, collision and LOD (LOD in separate FBX Files) for unreal engine. This script is very useful for indie game developers who want to keep a library of assets in a scene ready for export to Unreal. Advantage is if you have 100 models in your scene and you need to make changes or modifications to models this script will quickly batch export based on selected models.
Paste script in blender> save scene> select all desired mesh> click batch export.
The script takes each mesh resets the transformation to the center of grid and exports each mesh out as an fbx in the saved scene directory. No need to select collision mesh and LOD, they will get exported automatically based on the base model selection. Accidentally selected a collision mesh or LOD, export still works. No Collision mesh or no LOD, export still works!
Exporting base model+collision mesh in blender for unreal compatibility in one fbx file requires the collision mesh to have the same name with a prefix, [UBX_…(Box Collision),USP…(Sphere Collision), UCX_… (Convex Collision)].
eg. UBX_Cube (collision mesh) and Cube (Base Mesh)>Select both meshes> Export FBX.
Exporting LOD and base model in one FBX file in blender is not supported. LOD is exported separately.
LOD must be saved with a suffix …_1, up to …_6 LOD is supported.
eg. Cube (Base Model), Cube_1 (First LOD), Cube_2 (Second LOD)…
Textures are mostly created in Unreal. You can add different materials to different objects, join the objects and export it out to Unreal. In unreal you can assign different textures to the different materials.
*** IF SOMEONE AT BLENDER OR EPIC COULD PLEASE CREATE BLENDER-UNREAL LOD AND BASE MODEL SUPPORT IN ONE FBX FILE THIS SCRIPT WOULD BE PERFECT ***
or if anyone could help me figure this out that would be great.
I will continue adding more to this script. If anybody has any questions, errors or ideas, please post I would be happy to hear your feedback.
Unreal Developers Group:eyebrowlift:
http://blenderartists.org/forum/group.php?groupid=261
https://wiki.unrealengine.com/Static_Mesh_from_Blender
Epic Games has become a main sponsor of the Blender Development Fund, donating €10,000 to improve Blender’s FBX export capabilities: :eek:
[FOR UNREAL TOOLS FULL SCRIPT PLEASE VISIT LINK BELOW]
Here is my script:
#UNREAL TOOLS v1.01
#NIKHIL JEEWA
#2014
import bpy
import os
#################### BATCH EXPORT ###################
class UnrealTools(bpy.types.Panel):
bl_space_type="VIEW_3D"
bl_region_type="TOOLS"
bl_category = "Unreal"
bl_label = "Unreal Tools"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
col.label(text="Blender>Unreal FBX Batch Export:")
row = col.row(align=True)
row.operator("wm.batch_export", text="Batch Export", icon='EXPORT')
class wm_batch_export(bpy.types.Operator):
bl_idname="wm.batch_export"
bl_label="Minimal Operator"
def execute(self,context):
basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
collision=[]
mesh=[]
lod=[]
print ("")
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
if not obj.name.startswith("UBX_") and not obj.name.startswith("USP_") and not obj.name.startswith("UCX_"):
if not obj.name.endswith("_1") and not obj.name.endswith( "_2") and not obj.name.endswith( "_3") and not obj.name.endswith( "_4") and not obj.name.endswith( "_5") and not obj.name.endswith( "_6"):
mesh.append(obj)
print (mesh)
bpy.ops.object.select_by_type(type='MESH')
col = bpy.context.selected_objects
for obj in col:
if obj.name.startswith("UBX_") or obj.name.startswith("USP_") or obj.name.startswith("UCX_"):
collision.append(obj)
if obj.name.endswith("_1") or obj.name.endswith( "_2") or obj.name.endswith( "_3") or obj.name.endswith( "_4") and not obj.name.endswith( "_5") or obj.name.endswith( "_6"):
lod.append(obj)
bpy.ops.object.select_all(action='DESELECT')
for obj in mesh:
meshX=obj.name
meshXo=obj
obj.select=True
hasCollision=0
for obj in collision:
colX = (obj.name[4:])
if colX==meshX:
hasCollision=1
obj.select=True
locc = obj.location.xyz
rotXc = obj.rotation_euler[0]
rotYc = obj.rotation_euler[1]
rotZc = obj.rotation_euler[2]
scac = obj.scale.xyz
obj.location.xyz = [0,0,0]
obj.rotation_euler = [0,0,0]
obj.scale.xyz = [1,1,1]
locm = meshXo.location.xyz
rotXm = meshXo.rotation_euler[0]
rotYm = meshXo.rotation_euler[1]
rotZm = meshXo.rotation_euler[2]
scam = meshXo.scale.xyz
meshXo.location.xyz = [0,0,0]
meshXo.rotation_euler = [0,0,0]
meshXo.scale.xyz = [1,1,1]
name = bpy.path.clean_name(meshX)
fn = os.path.join(basedir, name)
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True,axis_forward='-Z', axis_up='Y')
obj.location.xyz = (locc)
obj.rotation_euler = [rotXc,rotYc,rotZc]
obj.scale.xyz =(scac)
meshXo.location.xyz = (locm)
meshXo.rotation_euler = [rotXm,rotYm,rotZm]
meshXo.scale.xyz =(scam)
obj.select=False
for obj in lod:
lodX=(obj.name[:-2])
if lodX==meshX:
meshXo.select=False
obj.select=True
loc = obj.location.xyz
rotX = obj.rotation_euler[0]
rotY = obj.rotation_euler[1]
rotZ = obj.rotation_euler[2]
sca = obj.scale.xyz
bpy.ops.object.location_clear()
bpy.ops.object.rotation_clear()
bpy.ops.object.scale_clear()
name =bpy.path.clean_name(obj.name)
fn = os.path.join(basedir,name)
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True,axis_forward='-Z', axis_up='Y')
obj.location.xyz = (loc)
obj.rotation_euler = [rotX,rotY,rotZ]
obj.scale.xyz =(sca)
meshXo.select=True
obj.select=False
bpy.ops.object.select_all(action='DESELECT')
if hasCollision==0:
locm = meshXo.location.xyz
rotXm = meshXo.rotation_euler[0]
rotYm = meshXo.rotation_euler[1]
rotZm = meshXo.rotation_euler[2]
scam = meshXo.scale.xyz
meshXo.location.xyz = [0,0,0]
meshXo.rotation_euler = [0,0,0]
meshXo.scale.xyz = [1,1,1]
name = bpy.path.clean_name(meshX)
fn = os.path.join(basedir, name)
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True,axis_forward='-Z', axis_up='Y')
meshXo.location.xyz = (locm)
meshXo.rotation_euler = [rotXm,rotYm,rotZm]
meshXo.scale.xyz =(scam)
obj.select=False
for obj in lod:
lodX=(obj.name[:-2])
if lodX==meshX:
meshXo.select=False
obj.select=True
loc = obj.location.xyz
rotX = obj.rotation_euler[0]
rotY = obj.rotation_euler[1]
rotZ = obj.rotation_euler[2]
sca = obj.scale.xyz
bpy.ops.object.location_clear()
bpy.ops.object.rotation_clear()
bpy.ops.object.scale_clear()
name =bpy.path.clean_name(obj.name)
fn = os.path.join(basedir,name)
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True,axis_forward='-Z', axis_up='Y')
obj.location.xyz = (loc)
obj.rotation_euler = [rotX,rotY,rotZ]
obj.scale.xyz =(sca)
meshXo.select=True
obj.select=False
bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
obj.select = True
return {'FINISHED'}
###########################################
if __name__== "__main__":
bpy.utils.register_module(__name__)