+2 votes

Hey, i'm currently developing some level building tools and I want to replicate some of the functionality seen in nodes like OmniLight, where the wireframe that represents it's sphere of influence dims when unselected and brightens when selected, as it helps distinguish between what is and isn't selected when editing.

I currently can't find any default notifications or signals I can catch to detect when a node is selected or unselected to make this happen inside a tool script however. If anyone knows how, that would be great to know w

in Engine by (23 points)

1 Answer

+3 votes

EditorInterface retrieved from EditorPlugin or EditorScript allows to fetch selected nodes via special EditorSelection object.

EditorSelection has selection_changed signal that you can use to check whether any nodes are selected in the scene tree dock. In order to connect to selection_changed signal:

var eds = get_editor_interface().get_selection()

func _enter_tree():
    # Plugin initialization, etc
    eds.connect("selection_changed", self, "_on_selection_changed")

Now you can handle it in a callback, for instance:

func _on_selection_changed():
    # Returns an array of selected nodes
    var selected = eds.get_selected_nodes() 

    if not selected.empty():
        # Always pick first node in selection
        var selected_node = selected[0]

This works in Godot 3.1.

by (1,364 points)

Xrayez, thanks for pointing this way.
I would like to give a warning thou, because I actually had some problems building the game with this approach.
EditorPlugin is meant to be used inside plugins only: so don't do like I did :D

THIS IS NOT THE CORRECT WAY OF DOING IT
IT WONT GIVE YOU A VALID RELEASE BUILD

var eds
func _ready():
    if Engine.editor_hint:
        eds = EditorPlugin.new().get_editor_interface().get_selection()
        eds.connect("selection_changed", self, "_on_selection_changed")

func _on_selection_changed():
    var sel = eds.get_selected_nodes()
    if not sel.empty():
        if self == sel[0]:
            #draw stuff in editor

Even if excluded from the script with an if statement it will ruin the build for release because this class won't be in the export template: here is a link to the highlighted issue on github #4082

I understand, but this is expected if you write a tool script/plugin, which this question explicitly asked for. In general, don't assume that classes which are named after Editor will work after export, because export templates are compiled without tools enabled.

Xrayez, are you saying that a script using tool will break your project outside the editor? Because I think that's wrong. Using Editor classes does, using tool scripts shouldn't.

Using Editor classes does, using tool scripts shouldn't.

Correct, I didn't mean to imply that tool scripts won't work outside the editor in this context. tool simply allows to run code in the editor, regardless whether core or editor-only classes are used in a tool script.

It's just that every EditorPlugin requires tool keyword, and in order to solve the problem asked by the author, this does require writing an EditorPlugin, which is editor-only.

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.