Skip to content

Instantly share code, notes, and snippets.

@williamgs
Last active May 14, 2018 06:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save williamgs/4966912faef38770514eab2a9b182c5e to your computer and use it in GitHub Desktop.
Save williamgs/4966912faef38770514eab2a9b182c5e to your computer and use it in GitHub Desktop.
Export script for instanced meshes to Unreal from Blender (FBX + T3D)
"""
Work in progress. It works, but no file output options and T3D currently prints to console
references:
https://forums.unrealengine.com/community/community-content-tools-and-tutorials/1257-3ds-max-object-placement-scripts
https://forums.unrealengine.com/community/community-content-tools-and-tutorials/11358-introducing-3ds-max-to-ue4-fbx-and-t3d-exporter-maxscript
"""
# exports each selected object into its own file
import bpy
import os
import math
# OPTIONS =====================================================================
# unreal path to imported assets
packagename = "/Game/Meshes/"
# TODO OPTIONS
# do FBX export
# FBX output path
# do FBX export from origin
# do T3D export
# T3D output path
# T3D scale x100
# export to blend file location
basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
scene = bpy.context.scene
obj_active = scene.objects.active
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
unique_objects=[]
t3dstring="\n"
t3dstring += ("Begin Map\n")
t3dstring += (" Begin Level\n")
for obj in selection:
obj.select = True
scene.objects.active = obj
obj_name = bpy.path.clean_name(obj.name)
data_name = bpy.path.clean_name(obj.data.name)
fn = os.path.join(basedir, data_name)
# find unique object data and export only those FBXs
if data_name not in unique_objects:
unique_objects.append(data_name)
# 1 store matrix
#obj_matrix = obj.matrix_world
loc, rot, scale = obj.matrix_world.decompose()
# 2 reset matrix
#obj.matrix_world.identity()
bpy.ops.object.location_clear(clear_delta=False)
bpy.ops.object.rotation_clear(clear_delta=False)
bpy.ops.object.scale_clear(clear_delta=False)
# 3 export
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True)
# 4 restore matrix
#obj.matrix_world = obj_matrix
#bpy.context.scene.update()
bpy.context.object.location = loc
bpy.context.object.rotation_euler = rot.to_euler()
bpy.context.object.scale = scale
# generate T3D for each object instance, reference unique FBX names
t3dstring += (" Begin Actor Class=StaticMeshActor Name=" + obj_name + " Archetype=StaticMeshActor'/Script/Engine.Default__StaticMeshActor'\n")
t3dstring += (" Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 Archetype=StaticMeshComponent'Default__StaticMeshActor:StaticMeshComponent0'\n")
t3dstring += (" End Object\n")
t3dstring += (" Begin Object Name=StaticMeshComponent0\n")
t3dstring += (" StaticMesh=StaticMesh'" + packagename + data_name + "." + data_name + "'\n")
t3dstring += (" RelativeLocation=(")
t3dstring += ("X=" + str(obj.location[0]*100.0) + ",")
t3dstring += ("Y=" + str(obj.location[1]*-100.0) + ",")
t3dstring += ("Z=" + str(obj.location[2]*100.0) + ")\n")
t3dstring += (" RelativeRotation=(")
t3dstring += ("Roll=" + str(math.degrees( obj.rotation_euler[0])) + ",")
t3dstring += ("Pitch=" + str(math.degrees( obj.rotation_euler[1])) + ",")
t3dstring += ("Yaw=" + str(math.degrees(-obj.rotation_euler[2])) + ")\n")
t3dstring += (" RelativeScale3D=(")
t3dstring += ("X=" + str(obj.scale[0]) + ",")
t3dstring += ("Y=" + str(obj.scale[1]) + ",")
t3dstring += ("Z=" + str(obj.scale[2]) + ")\n")
t3dstring += (" End Object\n")
t3dstring += (" StaticMeshComponent=StaticMeshComponent0\n")
t3dstring += (" RootComponent=StaticMeshComponent0\n")
t3dstring += (" ActorLabel=\"" + obj_name + "\"\n")
t3dstring += (" End Actor\n")
obj.select = False
t3dstring += (" End Level\n")
t3dstring += ("Begin Surface\n")
t3dstring += ("End Surface\n")
t3dstring += ("End Map\n")
print(t3dstring)
unique_objects.clear()
# restore selection
for obj in selection:
obj.select = True
scene.objects.active = obj_active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment