Can't add child to editor tree node from Editor Plugin bottom panel button

Godot Version

4.2.2 stable mono

Question

So I’m trying to add the “PhysRig3D.tscn” (or when using C# like I am “PhysRig3D_CS.tscn”) as a node when “CreatePhysRigBtn” is clicked. But for some reason my script won’t add the scene instance as a child of the currently selected node. I get no errors in the output though.

So to reiterate, my question is what can be changed to get the script to add the scene instance as a child of the currently selected node when “CreatePhysRigBtn” is clicked.

Output when the plugin enters the tree:

[Phys Animator]: Using C# compatible runtimes.

Output when “CreatePhysRigBtn” is clicked:

[Phys Animator]: 3D Mode selcted.
[Phys Animator]: Added Phys Rig to PhysicsRig object.

plugin.gd:

@tool
extends EditorPlugin

const editor_anim_tl = preload("./scenes/editor/editor_animator_timeline.tscn")
var docked_scene

var has_mono: bool
var phys_rig_3d
var phys_rig_2d
var phys_rig_2_5d

func _enter_tree():
	docked_scene = editor_anim_tl.instantiate()
	add_control_to_bottom_panel(docked_scene, "Phys Anim | Timeline")
	has_mono = Engine.has_singleton("GodotSharp")
	if has_mono:
		phys_rig_2d = preload("./scenes/runtime/PhysRig2D_CS.tscn")
		phys_rig_3d = preload("./scenes/runtime/PhysRig3D_CS.tscn")
		print("[Phys Animator]: Using C# compatible runtimes.")
	else:
		phys_rig_2d = preload("./scenes/runtime/PhysRig2D.tscn")
		phys_rig_3d = preload("./scenes/runtime/PhysRig3D.tscn")
		print("[Phys Animator]: Using GDScript (exclusive) runtimes.")
	
	var button: Button = docked_scene.get_node("EditorTimeline/TimelineControls/CreatePhysRigBtn") as Button
	button.connect("pressed", _create_phys_rig_btn_press)

func _exit_tree():
	remove_control_from_bottom_panel(docked_scene)
	docked_scene.free()

func _create_phys_rig_btn_press():
	var editor = get_editor_interface()
	var selected = editor.get_selection().get_selected_nodes()
	
	if selected and selected.size() > 0:
		var dmode: float = 0.0
		if selected[0] is Node3D:
			dmode = 3.0
			print("[Phys Animator]: 3D Mode selcted.")
		elif selected[0] is Node2D:
			dmode = 2.0
			print("[Phys Animator]: 2D Mode selcted.")
		else: return
		
		var new_phys_rig: Node
		
		if dmode == 3.0:
			new_phys_rig = phys_rig_3d.instantiate()
		elif dmode == 2.0:
			new_phys_rig = phys_rig_2d.instantiate()
		elif dmode == 2.5:
			return # TODO: add 2.5D functionality
		else: return
		
		selected[0].add_child(new_phys_rig)
		print("[Phys Animator]: Added Phys Rig to `" + selected[0].name + "` object.")
		
		if selected.size() > 1:
			var phys_bones = []
			
			for i in range(1, selected.size()):
				if dmode == 3.0:
					if not selected[i] is Node3D:
						return
					phys_bones.append(Node3D.new())
					new_phys_rig.add_child(phys_bones.back())
				if dmode == 2.0:
					if not selected[i] is Node2D:
						return
					phys_bones.append(Node2D.new())
					new_phys_rig.add_child(phys_bones.back())
				else: return
				new_phys_rig.bones.append(selected[i])
				phys_bones.back().position = selected[i].position

Thank you for your time.
– Samm

Edit: If you have any questions please feel free to ask.

You need to assign an Node.owner to the nodes as explained here Running code in the editor — Godot Engine (stable) documentation in English

1 Like

Thank you so much… That works.