Import Model with child node as the scene tree root node #7157
Replies: 4 comments 13 replies
-
What about not using scene inheritance? You can create a new scene where you instantiate the imported scene, and use editable children to modify it. |
Beta Was this translation helpful? Give feedback.
-
Unity by default will exclude the root node of a scene with only one root node. So by default, the imported file would be CheeseWedge-rigid. Unity does still have an importer option called "preserve hierarchy" which will keep the root node the same way Godot does now. Perhaps Godot could have a similar checkbox to the only root node as the root node of the imported scene?
|
Beta Was this translation helpful? Give feedback.
-
Couldn't agree more. When importing an object with the Since it's been a few months, did you manage to find a sane way to deal with this? |
Beta Was this translation helpful? Give feedback.
-
I've come up with an import script that solves this. Full explanation here, but here's the code: @tool
extends EditorScenePostImport
func _post_import(scene):
# If the imported asset has only a single root node, that's the only node
# we're interested in:
if scene.get_child_count() == 1:
print("Imported asset only contains a single root note; discarding outer root node.")
return _remove_root_node(scene)
# If the asset contains animation, Godot's importer will put them into an
# AnimationPlayer node. If there's only a single root object, but we also
# have animations, we need to handle this explicitly:
elif scene.get_child_count() == 2 and scene.get_child(1) is AnimationPlayer:
print("Imported asset contains a single root note and an AnimationPlayer; discarding outer root node.")
# First, convert the scene using our little trick.
var new_scene := _remove_root_node(scene)
# Now grab the AnimationPlayer that was generated from the asset's animations.
var anim_player : AnimationPlayer = scene.get_child(1)
# The following might seem a little verbose, but we have to be this
# exact in order to not trigger various Godot warnings.
scene.remove_child(anim_player)
anim_player.owner = null
new_scene.add_child(anim_player)
anim_player.owner = new_scene
return new_scene
# In all other cases, we will just return the scene as originally imported.
else:
return scene
func _remove_root_node(scene: Node) -> Node:
var new_root: Node = scene.get_child(0)
# Keep the original name so instances of this scene will have the
# imported asset's filename by default
new_root.name = scene.name
# Recursively set the owner of the new root and all its children
_set_new_owner(new_root, new_root)
# That's it!
return new_root
func _set_new_owner(node: Node, owner: Node):
# If we set a node's owner to itself, we'll get an error
if node != owner:
node.owner = owner
for child in node.get_children():
_set_new_owner(child, owner) Don't forget that adding this script to your project is not enough; you must also select it in the "Import Script - Path" field in the import settings of each asset you want to import this way (I'm currently trying to find a way to automate this.) Update (2024-07-15): I've updated the script to also handle files with animations correctly. |
Beta Was this translation helpful? Give feedback.
-
One of the problems I've been having is where I want to import a GLTF model. I have all of the important flags on the objects in Blender and I have everything parented exactly how I like it. But then when I go to make an inherited scene so I can add interactive elements and script(s), It comes with a root node on top of all of the object nodes I set in Blender. I know I can define what type that inserted root node is, but I would much rather have one of my object nodes be the root. Specifically when I am importing a model with the
-rigid
flag, I want the rigid body to be the root.Ideally the feature I would like would be to allow importing a model where a child node can be set as the scene's root node. I'm not familiar with the GLTF specification or how Godot handles model importing. But I imagine adding a path to the sub-node would allow just loading that branch of the file.
I'm totally open to if this has some existing solution I just haven't found yet. But here's some example pictures to show more of what I mean.
Tree In Blender (with flags assigned)
Godot Import View of tree
Scene Tree of inherited scene (from the GLB file)
Beta Was this translation helpful? Give feedback.
All reactions