+2 votes

Just started using the engine so i don't know if im dumb or this is a bug

I have a script with a class_name and in tool mode that I intend to use as a custom node, the code in _ready() runs when I add it through the editor. It checks if there's a canvas layer and if the scene i want to add (Interface.tscn) is in that canvas layer. If not, it creates them.

tool
extends Node
class_name Holder

func _ready():  
    if !has_node("CanvasLayer"):
        var canvas = CanvasLayer.new()
        get_tree().get_edited_scene_root().add_child(canvas)
        canvas.set_owner(get_tree().get_edited_scene_root())

    if !has_node("CanvasLayer/Interface"):
        var interface = load("res://Scenes/Interface.tscn").instance()
        var canvas = get_tree().get_edited_scene_root().get_node("CanvasLayer")
       canvas.add_child( interface )
       interface.set_owner( canvas )

The canvas layer works as intended, but the scene doesn't get added no matter what i do. It even appears in the viewport but not in the Scene tree panel. When I reload the scene it's not anywhere. There are no errors in the console.

It only works properly when I add the scene in the root node like the CanvasLayer

I also tried simply doing it like in-game code:

var canvas = get_node("CanvasLayer")
    canvas.add_child(interface)
    interface.set_owner(canvas)

But It just gives me "Node not found: CanvasLayer." in the console

And using "gettree().getroot()" like:

var canvas = get_tree().get_root().get_node("CanvasLayer")
    canvas.add_child( interface )
    interface.set_owner( canvas )

Adds the interface scene to the editor itself

in Engine by (52 points)

I'd try preloading the scene into an onready var first and then instance that. Or, use calldeferred for adding the child inside of _ready(). From memory: calldeferred("addchild", childnode) - something like that.

I tried using preload onready and:

func _ready():
  if !root_node.has_node("CanvasLayer/Interface"):
    print("no interface")
    var interface = preload("res://Scenes/Interface.tscn").instance()
    var canvas = root_node.get_node("CanvasLayer")
    canvas.call_deferred("add_child", interface)
    interface.call_deferred("set_owner", canvas)

Same result on both (and combined), the scene "Interface" appears on the viewport but not in the scene tree, and when I reload the scene it's on the same state or just simply gone

I just had the same problem when trying to make an editor plugin. Did you find a solution or should we raise an issue on GitHub?

Nope, I gave up long ago, I made my custom node not interact with anything. I don't really plan to use this anymore but it would be pretty neat to have all the necessary nodes automatically appear to avoid problems, but I realised you can have them all in one tscn if you really need it...

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.