"""Create a reusable blockout mech, preserve other scenes, export selected asset.""" import bpy from pathlib import Path root_path = Path('D:/vibeCoding/unityRouge') source_path = root_path / 'SourceAssets/Blender/Mechs' export_path = root_path / 'Assets/Game/Art/Models/Mechs' source_path.mkdir(parents=True, exist_ok=True) export_path.mkdir(parents=True, exist_ok=True) scene = bpy.data.scenes.get('UnityRouge_Assets') or bpy.data.scenes.new('UnityRouge_Assets') bpy.context.window.scene = scene collection = bpy.data.collections.get('Mech_Scout_A') if collection is None: collection = bpy.data.collections.new('Mech_Scout_A') scene.collection.children.link(collection) else: for obj in list(collection.objects): bpy.data.objects.remove(obj, do_unlink=True) def material(name, color, metal=0.0): mat = bpy.data.materials.get(name) or bpy.data.materials.new(name) mat.use_nodes = True node = next(n for n in mat.node_tree.nodes if n.type == 'BSDF_PRINCIPLED') node.inputs['Base Color'].default_value = (*color, 1) node.inputs['Metallic'].default_value = metal node.inputs['Roughness'].default_value = 0.4 mat.diffuse_color = (*color, 1) return mat armor = material('Armor', (0.18, 0.28, 0.30), 0.65) dark = material('Mechanism', (0.035, 0.055, 0.065), 0.7) light = material('Trim', (0.55, 0.63, 0.62), 0.5) glow = material('Reactor', (0.05, 0.9, 0.78), 0.3) root = bpy.data.objects.new('Mech_Root', None) collection.objects.link(root) def box(name, pos, size, mat, parent=root): bpy.ops.mesh.primitive_cube_add(size=1, location=pos) obj = bpy.context.object obj.name = name for old in list(obj.users_collection): old.objects.unlink(obj) collection.objects.link(obj) obj.dimensions = size bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) obj.data.materials.append(mat) bevel = obj.modifiers.new('ManufacturedEdges', 'BEVEL') bevel.width = 0.055 bevel.segments = 2 obj.parent = parent return obj for side, x in [('L', -0.48), ('R', 0.48)]: box('Foot_' + side, (x, -0.16, 0.18), (0.64, 1.05, 0.36), dark) box('Shin_' + side, (x, 0.04, 0.66), (0.5, 0.54, 0.7), armor) box('Knee_' + side, (x, -0.28, 1.02), (0.52, 0.2, 0.3), light) box('Thigh_' + side, (x, 0.02, 1.32), (0.43, 0.48, 0.6), dark) box('Shoulder_' + side, (x * 1.9, 0, 2.5), (0.65, 0.72, 0.65), armor) box('Arm_' + side, (x * 1.95, -0.05, 2.0), (0.42, 0.48, 0.65), dark) box('Gauntlet_' + side, (x * 1.95, -0.25, 1.78), (0.52, 0.65, 0.45), armor) box('Thruster_' + side, (x * 0.9, 0.58, 2.18), (0.32, 0.38, 0.8), dark) box('ThrusterGlow_' + side, (x * 0.9, 0.6, 1.75), (0.24, 0.27, 0.14), glow) box('Pelvis', (0, 0, 1.65), (1.1, 0.58, 0.34), armor) box('Core', (0, 0.0, 2.32), (1.28, 0.7, 0.94), armor) box('BreastPlate', (0, -0.4, 2.4), (0.8, 0.2, 0.5), light) box('CoreGlow', (0, -0.52, 2.4), (0.45, 0.07, 0.09), glow) box('Head', (0, -0.04, 2.98), (0.62, 0.58, 0.45), dark) box('Visor', (0, -0.35, 3.0), (0.49, 0.08, 0.14), glow) box('Weapon_Main', (1.0, -0.7, 1.95), (0.35, 1.5, 0.35), dark) box('Weapon_Trim', (1.0, -0.8, 2.15), (0.2, 1.0, 0.08), light) for name, pos in [('Mount_Primary',(1.0,-1.48,1.95)), ('Mount_Secondary',(-0.92,-0.5,2.5)), ('View_Cockpit',(0,-0.22,2.85))]: marker = bpy.data.objects.new(name, None) collection.objects.link(marker) marker.location = pos marker.parent = root scene.unit_settings.system = 'METRIC' scene.unit_settings.scale_length = 1.0 bpy.ops.object.select_all(action='DESELECT') for obj in collection.objects: obj.select_set(True) bpy.context.view_layer.objects.active = root bpy.ops.wm.save_as_mainfile(filepath=str(source_path / 'Mech_Scout_A.blend')) bpy.ops.export_scene.fbx(filepath=str(export_path / 'Mech_Scout_A.fbx'), use_selection=True, add_leaf_bones=False, axis_forward='-Z', axis_up='Y', apply_unit_scale=True, bake_anim=False) print({'source': str(source_path / 'Mech_Scout_A.blend'), 'export': str(export_path / 'Mech_Scout_A.fbx'), 'objects':len(collection.objects)})