The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

+1 vote

I have a tool script with an exported variable:

tool
extends Spatial

class_name Satellite

export var orbit_radius = 30.0

func _ready():
    var mesh = get_node("MeshInstance")
    mesh.transform.origin = Vector3(orbit_radius, 0, 0)

In the Editor, however, the mesh is always at (0, 0, 0). When I run the game, the mesh will appear at its proper destination, e.g. (30, 0, 0).

How can I have the value of orbit_radius affect the position of the mesh in the 3D editor?

================
EDIT:

Based on Lopy's answer, I changed the code to this:

tool
extends Spatial

class_name Satellite

export var orbit_radius = 30.0 setget _set_radius
var mesh

func _ready():
    if mesh == null:
        mesh = get_node("MeshInstance")

func _set_radius(value):
    orbit_radius = value
    if mesh == null:
        mesh = get_node("MeshInstance")
    mesh.transform.origin = Vector3(orbit_radius, 0, 0)

I placed a breakpoint in the line mesh = get_node("MeshInstance") of the _ready() function. The line does not even execute before I get an error:

E 0:00:00.654 get_node: Node not found: MeshInstance. <C++ Error>
Condition "!node" is true. Returned: __null <C++ Source>
scene/main/node.cpp:1381 @ get_node() Satellite.gd:28
@ _set_radius()

So it seems the editor tries to run the setter before even calling _ready(), however the tree is not set up at this moment. It does work in the editor though!

Godot version v3.2.stable.mono.official
in Engine by (13 points)
edited by

Just to be sure, was the scene reloaded to check the tool script?

Not by me on purpose. How would I do that?

1 Answer

+1 vote

You should be able to use a setget for that. The Editor does not call your _ready() regularly. It calls _init when the scene is saved, but your get_node() would probably fail inside an _init.

export var orbit_radius = 30.0 setget _set_radius

func _set_radius(value):
    orbit_radius = value
    var mesh = get_node("MeshInstance")
    mesh.transform.origin = Vector3(orbit_radius, 0, 0)
func _ready():
    _set_radius(orbit_radius) # Force the setter to be called
by (2,720 points)
edited by

Sorry, accepted too soon :/ Now it ONLY works in the editor. When I run the game, get_node("MeshInstance") does not find the node

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 Frequently asked questions and 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 [email protected] with your username.