0 votes

Hello everyone.

I am trying to add a bunch of nodes I create at runtime, but I can't get it to work. I know this is a duplicate question, but all the methods I found here and elsewhere didn't work, furthermore, the geteditedscene_root() method returns Nil.

So here's what I tried so far, following the suggestions from this Q&A page:

  1. Create a new node: var newNode = Spatial.new()

  2. Get the current scene root to add it there: var scene =
    gettree().geteditedsceneroot()

  3. Add the child: scene.add_child(newNode)

  4. Set owner: newNode.set_owner(scene)

It doesn't matter if I set the owner before or after adding the child, it just doesn't work. As you might have guessed I am working in the 3D editor, but that shouldn't make a difference I hope.

Since gettree().geteditedsceneroot() returns Nil, I have tried some other ways with no luck, like gettree().getroot().getchild(0) and gettree().getcurrentscene()

What are your thoughts about this? btw, I'm using Godot 2.1.3.

asked Jun 6, 2017 in Engine by rredesigns (365 points)

I think adding nodes to the editor tree might only be possible via making a plugin (and then following the procedure you described).

The problem lies in the line

scene = gettree().geteditedsceneroot()

Not sure what node you want to add the spatial to. If it the same node the script is on leave it out and just use "add_child(newNode)" and it will add it as a child of the node the script is attached to.

Well, I saw in other question that getting the current scene like that was best to add children to the scene root. And the person that asked the question said that was a solution and worked for him.

So I figured I would try it the same way.

1 Answer

+4 votes

Adding nodes from a script in the editor doesn't necessarily require a plugin, and is possible using the tool keyword, so you can execute code in the editor in the first place.
However these nodes will neither be visible nor saved unless you set their owner to be the edited scene root.

I had a dig in my work and found this: https://github.com/Zylann/godot_terrain_plugin/blob/master/addons/zylann.terrain/terrain.gd#L183

So you need to do this in a tool script:

var node = Spatial.new()
# the parent can be get_tree().get_root() or some other node
parent.add_child(node)
# ownership is different, I think it's not the same root as the root node
node.set_owner(get_tree().get_edited_scene_root())

Note that because this explicitely gives ownership to the editor, this node will be saved in the scene file once once you do "Save scene" or Ctrl+S.

answered Jun 7, 2017 by Zylann (26,787 points)

I will give it a try then. I used the tool keyword on top of my script before but nothing happened, so I don't know. How can I make it run in the editor, I mean, how do I force it to run?

Then the question is, when do you want it to run?

Well, I can't seem to make it work. I even created a setget function and all, as in Andreas Essau tutorial but it just won't run, furthermore, if I try to use the slider to change the var from the editor it crashes.

Anyway, I made this after I saw your procedural terrain plugin. I can create pretty cool grass on a mesh on runtime, but I'd like to put them in the editor so I can then change the target mesh and spawn some other vegetation.

I hope you can help me with this.

I suppose it should run as soon as I change an exported var, right? I don't know, I thought it would actually keep the nodes created at runtime. I never used the tool mode before, so I'm blind.

Normally not even setget properties run in editor. The tool keyword means your script will run in the editor, just as in game, so setget will work (it also means you can crash the editor if you do an infinite loop as well).

Now I ask again: when do you want your script to run? There can be many places, mostly known ones are setget, _process, _ready.... but the EditorPlugin also allows you to listen to editor events such as input on the viewport (to paint grass like you said^^).

Oh, you mean when in my code? Well, the whole script is used to that purpose only, so all of it should execute, actually.

I'm not painting, that would be incredibly difficult and probably slow to do with GDScript. I just place meshes on other meshes, because placing grass in a huge map is imposible with Godot's 3D preview.

I posted a video on YouTube to demonstrate how it works. I want to release it later as a tool to populate maps with vegetation, but if I can't add them to the editor that's kind of a problem.

Here's the video. It has a lot of potential because you can spawn things in a ring around the player to create all sorts of effects with billboards and particles. If you want the project to see if you can make it work, that would be awesome.

I want to create those nodes into the editor tree so later it can be used to spawn other things with the same script, just changing the target and some parameters. So with 3 executions you can have grass, bushes and trees in no time.

EDIT:
Now that I think about it, it doesn't need to run in the editor. All I need is that the nodes created at runtime get to be stored with the scene. That would be preferable, so the user can roam around to see if the map looks good, then when the game is stopped the nodes should be there to save with the rest of the scene.

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.