Godot: Cannot change root node type by script

Created on 16 Jan 2020  路  2Comments  路  Source: godotengine/godot

Godot version:
3.0-3.2 (probably older too)

Issue description:
There is no way to change the type of the root node of a scene by script. It can be done by right clicking the node in the tree list and choosing Change Type however. If trying replace_by( new_node ) the following error is thrown in 3.2 : Cannot get path of node as it is not in a scene tree.. The same error is thrown if you remove the current root node and add another to replace it (or first add new node and then remove old - it happens when the old root gets removed).

Steps to reproduce:

  1. Make a new scene.
  2. Add the root node of whatever type, and attach a tool script to it.
  3. Try to replace the root node with another node, either by: replace_by( ) or writing a custom script to do the replacing.
  4. Click the root node and change type manually - it works.

Workarounds:

  • My current workaround is to ask the user to do it, the script will handle other parts of the process of which changing the node type is one (Node2D <-> KinematicBody2D).
  • Another one would be to duplicate the whole scene and save it on the disk and then open it in a new tab (or possibly use reload on the existing path, if has been saved). But this is even hackier.

<-- Or am I missing a command, is there something else besides replace_by to change the node type ?

Update - solved:

  • The edited scene root can be "hard swapped" by: orig_root_node.get_node("/root/EditorNode").set_edited_scene(new_root_node)
archived

Most helpful comment

Here is the code the SceneTreeDock uses to ensure that the node is properly reinstated as the current scene:
https://github.com/godotengine/godot/blob/e7ee9e01a64bb1296431d82f9f1d888a90b6ea1c/editor/scene_tree_dock.cpp#L2130-L2134

All 2 comments

Here is the code the SceneTreeDock uses to ensure that the node is properly reinstated as the current scene:
https://github.com/godotengine/godot/blob/e7ee9e01a64bb1296431d82f9f1d888a90b6ea1c/editor/scene_tree_dock.cpp#L2130-L2134

Thanks a lot! (Also for the help on other issues!)

There "magical" line I was missing is that set_edited_scene. Couldn't find it in the docs, though finally found this: Adding a root node from a script. Other part of missing magic is the EditorNode (no docs about it?) - I earlier had actually tried set_edited_scene_root on the EditorPlugin and EditorInterface, but had no luck.

Btw. Do you have any more info on the set_editable_instances ? EditorNode (nor the Plugin or Interface) don't seem to have corresponding methods. What does it do (hoping it's related to Editable Children - and will solve other horrible hacks for me) and how to use it in tool GDScripts?

Anyway, here's the current solution (without Editable Instances) for anyone with the same problem:
```

"Hard-Swap" the root node.

static func swap_root_node(orig_root : Node, new_root : Node):
# Get EditorNode.
var editor := orig_root.get_node("/root/EditorNode")
# Do the magical swap. No need to add_child, remove_child nor owner stuff.
editor.set_edited_scene(new_root)

Was this page helpful?
0 / 5 - 0 ratings