Blender has a handy script built-in that lets us export multiple selected objects in our scene as separate objects. I remember mentioning this principle in a beefy article focussing on Unreal Engine workflow, but thought it would be neat to turn it into its own article. Here it is!
Let’s assume we have several objects in our scene, and rather than exporting a combined version, we want separate files. Select all objects you want to export, then head over to the Scripting Tab. You’ll see a small version of your viewport, and a large empty window in the middle.
Click on Templates – Python – Batch Export and the following script will load.
Save your scene to a folder that you’d like to save your objects to, then click the little play button at the top right. Blender will go to work and export all your selected objects out as FBX files. Neat, huh?
If you prefer to export as OBJ, change line 29 of the code into the following (replacing FBX with OBJ twice):
bpy.ops.export_scene.obj(filepath=fn + ".obj", use_selection=True)
This script has changed a tad over the years, and this version works in Blender 3.0 (in fact that’s where I’ve lifted it from). Just in case you can’t find it, or something changes, here is the OBJ version in its entirety:
# exports each selected object into its own file
import bpy
import os
# export to blend file location
basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
view_layer = bpy.context.view_layer
obj_active = view_layer.objects.active
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
obj.select_set(True)
# some exporters only use the active object
view_layer.objects.active = obj
name = bpy.path.clean_name(obj.name)
fn = os.path.join(basedir, name)
bpy.ops.export_scene.obj(filepath=fn + ".obj", use_selection=True)
# Can be used for multiple formats
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
obj.select_set(False)
print("written:", fn)
view_layer.objects.active = obj_active
for obj in selection:
obj.select_set(True)
I love yo man!!!! Thank you!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
This is almost what I was looking for. the one issue is that all the object origins default to the same spot when importing to Unreal Engine. Anyway to fix that?
Assuming all your objects are already split, you should be able to select them all, then choose Object – Set Origin – Origin to Geometry. This will give each mesh an origin at its middle rather than a centralised origin point. I’ve seen sets that have been split, and every object has the same origin point somewhere in the middle (very much off centre). Hope this works!
Alternatively you could probably do this in code just before export, but I’m no good with Blender script. I found this article that may come in handy for such ventures: https://blender.stackexchange.com/questions/186008/setting-the-origin-for-each-object-to-geometry
Thanks for the post Jay.
Fabio, I also wanted the same thing so I added a few lines to save the location, set to 0,0,0 export and then reset the original location.
Please see below updated code:
exports each selected object into its own file
import bpy
import os
export to blend file location
basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
view_layer = bpy.context.view_layer
obj_active = view_layer.objects.active
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
for obj in selection:
obj.select_set(True)
#save object location
obj_x = obj.location.x
obj_y = obj.location.y
obj_z = obj.location.z
#set object location to 0,0,0
obj.location.x = 0
obj.location.y = 0
obj.location.z = 0
some exporters only use the active object
view_layer.objects.active = obj
name = bpy.path.clean_name(obj.name)
fn = os.path.join(basedir, name)
bpy.ops.export_scene.obj(filepath=fn + ".obj", use_selection=True)
Can be used for multiple formats
bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
#restore original location
obj.location.x = obj_x
obj.location.y = obj_y
obj.location.z = obj_z
obj.select_set(False)
print("written:", fn)
view_layer.objects.active = obj_active
for obj in selection:
obj.select_set(True)
Ha, code doesn’t show well in comment section..
Add this after the line “obj.select_set(True)”
obj_x = obj.location.x
obj_y = obj.location.y
obj_z = obj.location.z
obj.location.x = 0
obj.location.y = 0
obj.location.z = 0
and add this after the line ” # bpy.ops.export_scene.x3d(filepath=fn + “.x3d”, use_selection=True)”
obj.location.x = obj_x
obj.location.y = obj_y
obj.location.z = obj_z
anyway to use this and keep material , its very useful as it is though 🙂
Sadly no, the OBJ and FBX format are very limited in what they can reference. You can only get the base/diffuse and normal maps referenced, none of the other PBR or parametric nodes.