Ejecutando código en el editor

¿Qué es tool?

tool es una poderosa línea de código que, cuando se agrega en la parte superior de tu script, hace que se ejecute en el editor. También puedes decidir qué partes del script se ejecutan en el editor, cuáles en el juego y cuáles en ambos.

Puedes usarlo para hacer muchas cosas, pero es especialmente útil en el diseño de niveles para presentar visualmente cosas que son difíciles de predecir por nosotros mismos. Aquí hay algunos casos de uso:

  • Si tienes un cañón que dispara balas de cañón afectadas por la física (gravedad), puedes dibujar la trayectoria de las balas de cañón en el editor, lo que facilitará mucho el diseño de niveles.

  • Si tienes plataformas de salto (jumppads) con alturas de salto variables, puedes dibujar la altura máxima a la que llegaría un jugador si saltara sobre una, lo que también facilitaría el diseño de niveles.

  • Si tu jugador no utiliza un sprite, sino que se dibuja a sí mismo usando código, puedes hacer que ese código de dibujo se ejecute en el editor para ver a tu jugador.

Peligro

Los scripts con tool se ejecutan dentro del editor y te permiten acceder al árbol de escena de la escena que se está editando actualmente. Esta es una característica poderosa que también viene con advertencias, ya que el editor no incluye protecciones contra un posible mal uso de los scripts con tool. Sé extremadamente cauteloso al manipular el árbol de escena, especialmente mediante Node.queue_free, ya que puede causar bloqueos si liberar un nodo mientras el editor está ejecutando lógica que involucra a ese nodo.

Cómo usarlo

Para convertir un script en una herramienta (tool), agrega la palabra clave tool en la parte superior de tu código.

Para verificar si actualmente te encuentras en el editor, utiliza: Engine.editor_hint.

Por ejemplo, si desea ejecutar algún código solo en el editor, use:

if Engine.editor_hint:
    # Code to execute when in editor.

Por otro lado, si desea ejecutar código solo en el juego, simplemente niegue la misma declaración:

if not Engine.editor_hint:
    # Code to execute when in game.

Los fragmentos de código que no tienen ninguna de las 2 condiciones mencionadas anteriormente se ejecutarán tanto en el editor como en el juego.

Aquí tienes cómo podría lucir una función _process() para ti:

func _process(delta):
    if Engine.editor_hint:
        # Code to execute in editor.

    if not Engine.editor_hint:
        # Code to execute in game.

    # Code to execute both in editor and in game.

Nota

Las modificaciones realizadas en el editor son permanentes. Por ejemplo, en el siguiente caso, cuando eliminamos el script, el nodo mantendrá su rotación. Ten cuidado de evitar realizar modificaciones no deseadas.

Pruebalo

Agrega un nodo Sprite a tu escena y establece la textura como el ícono de Godot. Adjunta y abre un script, y cámbialo a esto:

tool
extends Sprite

func _process(delta):
    rotation_degrees += 180 * delta

Guarda el script y regresa al editor. Ahora deberías ver que tu objeto rota. Si ejecutas el juego, también rotará.

../../_images/rotating_in_editor.gif

Nota

Si no ves los cambios, recarga la escena (ciérrala y ábrela nuevamente).

Ahora elijamos qué código se ejecutará cuándo. Modifica tu función _process() para que se vea así:

func _process(delta):
    if Engine.editor_hint:
        rotation_degrees += 180 * delta
    else:
        rotation_degrees -= 180 * delta

Guarda el script. Ahora el objeto girará en sentido horario en el editor, pero si ejecutas el juego, girará en sentido antihorario.

Editando variables

Agrega y exporta una variable speed al script. La función set_speed después de "setget" se ejecutará con tu entrada para cambiar la variable. Modifica la función _process() para incluir la velocidad de rotación.

tool
extends Sprite


export var speed = 1 setget set_speed


# Update speed and reset the rotation.
func set_speed(new_speed):
    speed = new_speed
    rotation_degrees = 0


func _process(delta):
    rotation_degrees += 180 * delta * speed

Nota

El código de otros nodos no se ejecuta en el editor. Tu acceso a otros nodos está limitado. Puedes acceder al árbol y a los nodos, así como a sus propiedades predeterminadas, pero no puedes acceder a las variables de usuario. Si deseas hacerlo, otros nodos también deben ejecutarse en el editor. Los nodos AutoLoad no pueden ser accedidos en el editor en absoluto.

Instanciación de escenas

Puedes instanciar escenas empaquetadas normalmente y agregarlas a la escena que está abierta actualmente en el editor. Por defecto, los nodos o escenas añadidos con Node.add_child(node) no son visibles en el panel del árbol de escena (Scene tree dock) y no se guardan en el disco. Si deseas que el nodo o la escena sean visibles en el panel del árbol de escena y se guarden en el disco al guardar la escena, debes establecer la propiedad owner del nodo hijo en el nodo raíz de la escena que está siendo editada actualmente.

Si usted está usando tool:

func _ready():
    var node = Spatial.new()
    add_child(node) # Parent could be any node in the scene

    # The line below is required to make the node visible in the Scene tree dock
    # and persist changes made by the tool script to the saved scene file.
    node.set_owner(get_tree().edited_scene_root)

Si estás usando EditorScript:

func _run():
    var parent = get_scene().find_node("Parent") # Parent could be any node in the scene
    var node = Spatial.new()
    parent.add_child(node)

    # The line below is required to make the node visible in the Scene tree dock
    # and persist changes made by the tool script to the saved scene file.
    node.set_owner(get_scene())

Advertencia

Usar tool de manera inapropiada puede generar muchos errores. Se recomienda primero escribir el código como se desea y luego agregar la palabra clave tool en la parte superior. Además, asegúrate de separar el código que se ejecuta en el editor del código que se ejecuta en el juego. De esta manera, puedes encontrar errores más fácilmente.