godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Add a batch "Save Branch as Scene" option when selecting multiple branches #7911

Open loafbrr opened 1 year ago

loafbrr commented 1 year ago

Describe the project you are working on

game asset packs Godot_v4 1 1-stable_win64_Cuekj18IWy Godot_v4 1 1-stable_win64_TpFluBXPSe

Describe the problem or limitation you are having in your project

saving the pieces one by one takes a little bit of time and hurts my wrists after repeating ec2Famw4wd

Describe the feature / enhancement and how it helps to overcome the problem or limitation

saving multiple branches as scenes into a folder will result in faster and more convenient way of putting objects from fbx/obj/gltf files into scenes

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

A gimp-2 10_34ehPVibZQ B image

save multiple branches as scenes button(A) -into> tscn files(B)

If this enhancement will not be used often, can it be worked around with a few lines of script?

maybe, i don't know

Is there a reason why this should be core and not an add-on in the asset library?

its just convenient, add-on or not

passivestar commented 9 months ago

would also help if dragging multiple branches onto the filesystem dock was supported because it's faster than going through the popup

TheoLeeCJ commented 4 months ago

I came across a similar issue with manually saving each branch. Here is a script that may be able to do it in the interim. The code is partially written by Claude after a bit of prompting. However, an intermediary Node3D is generated.

Further filtering can be done on the if child is Node3D and child.visible: line.

@tool
extends EditorScript

func _run():
    var current_scene = get_scene()
    if not current_scene:
        print("No scene is currently open.")
        return

    var export_path = current_scene.scene_file_path.get_base_dir() + "/exported_areas/"
    var dir = DirAccess.open(export_path)
    if not dir:
        DirAccess.make_dir_absolute(export_path)

    for child in current_scene.get_children():
        if child is Node3D and child.visible:
            var packed_scene = PackedScene.new()

            # Create a new Node3D to act as the root for our exported scene
            var root = Node3D.new()
            root.name = child.name

            # Duplicate the Area3D and its entire hierarchy
            var duplicated_area:Node3D = child.duplicate(Node.DUPLICATE_GROUPS | Node.DUPLICATE_SCRIPTS | Node.DUPLICATE_SIGNALS)
            duplicated_area.position = Vector3(0, 0, 0)
            root.add_child(duplicated_area)
            duplicated_area.owner = root

            # Recursively set owner for all children
            for descendant in duplicated_area.get_children():
                set_owner_recursive(descendant, root)

            packed_scene.pack(root)
            var save_path = export_path + child.name + ".scn"
            var error = ResourceSaver.save(packed_scene, save_path)
            if error == OK:
                print("Exported: " + save_path)
            else:
                print("Failed to export: " + child.name)

    print("Export complete. Files saved to: " + export_path)

func set_owner_recursive(node: Node, new_owner: Node):
    node.owner = new_owner
    for child in node.get_children():
        set_owner_recursive(child, new_owner)