Exécuter le code dans l'éditeur

Que signifie tool ?

tool est une puissante ligne de code qui, lorsqu'elle est ajoutée en haut de votre script, lui permet de s'exécuter dans l'éditeur. Vous pouvez également définir quelles parties du script s'exécutent dans l'éditeur, dans le jeu, ou les deux.

Vous pouvez l'utiliser pour faire beaucoup de choses, mais c'est surtout utile dans la conception de niveaux pour représenter visuellement des choses qui sont difficiles à prévoir nous-mêmes. Voici quelques cas d'utilisation :

  • Si vous avez un canon qui tire des boulets de canon affectés par la physique (gravité), vous pouvez dessiner la trajectoire du boulet de canon dans l'éditeur, ce qui facilite grandement la conception des niveaux.
  • Si vous avez des tremplins avec différentes hauteurs de saut, vous pouvez dessiner la hauteur maximum que le joueur atteindrait s'il sautait sur l'un d'eux, facilitant encore une fois la conception du niveau.
  • Si votre personnage n'utilise pas de sprite mais se dessine lui même depuis le code, vous pouvez faire en sorte que ce code de dessin s'exécute dans l'éditeur, vous permettant ainsi de voir votre joueur.

Danger

Les scripts tool s'exécutent à l'intérieur de l'éditeur, et vous permettent d'accéder à l'arbre de la scène en cours d'édition. Il s'agit d'une fonctionnalité puissante qui s'accompagne également de mises en garde, car l'éditeur n'inclut pas de protections contre les mauvaises utilisations des scripts tool. Soyez extrêmement prudent lorsque vous manipulez l'arbre de la scène, en particulier en utilisant Node.queue_free car cela peut causer des plantages si vous libérez un nœud pendant que l'éditeur exécute une logique l'impliquant.

Comment l'utiliser

Pour transformer un script en outil, ajoutez le mot-clé tool en haut de votre code.

Pour vérifier si vous êtes actuellement dans l'éditeur, utilisez : Engine.editor_hint.

Par exemple, si vous souhaitez exécuter du code uniquement dans l'éditeur, utilisez :

if Engine.editor_hint:
    # Code to execute when in editor.
if (Engine.EditorHint)
{
    // Code to execute when in editor.
}

En revanche, si vous voulez exécuter du code uniquement dans le jeu, il suffit d'utiliser la négation de l'expression précédente :

if not Engine.editor_hint:
    # Code to execute when in game.
if (!Engine.EditorHint)
{
    // Code to execute when in game.
}

Les morceaux de code qui n'utilisent aucune des 2 conditions ci-dessus seront exécutés à la fois dans l'éditeur et dans le jeu.

Voici à quoi une fonction _process() pourrait ressembler pour vous :

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.
public override void _Process(float delta)
{
    if (Engine.EditorHint)
    {
        // Code to execute in editor.
    }

    if (!Engine.EditorHint)
    {
        // Code to execute in game.
    }

    // Code to execute both in editor and in game.
}

Note

Les modifications dans l'éditeur sont permanentes. Dans notre cas, lorsque nous supprimons le script, le nœud conserve sa rotation. Faites attention à ne pas faire de modifications non souhaitées.

Testez-le

Ajoutez un nœud Sprite à votre scène et donnez lui la texture de l'icône Godot. Attachez-lui un script, ouvrez-le, et changez-le en ceci :

tool
extends Sprite

func _process(delta):
    rotation_degrees += 180 * delta
using Godot;
using System;

[Tool]
public class MySprite : Sprite
{
    public override void _Process(float delta)
    {
        RotationDegrees += 180 * delta;
    }
}

Sauvegardez le script et revenez à l'éditeur. Vous devriez maintenant voir votre objet tourner. Si vous lancez le jeu, il tournera également.

../../_images/rotating_in_editor.gif

Note

Si vous ne voyez pas les modifications, rechargez la scène (fermez-la et ouvrez-la à nouveau).

Choisissons maintenant quel code fonctionne à quel moment. Modifiez votre fonction _process() pour qu'elle ressemble à ceci :

func _process(delta):
    if Engine.editor_hint:
        rotation_degrees += 180 * delta
    else:
        rotation_degrees -= 180 * delta
public override void _Process(float delta)
{
    if (Engine.EditorHint)
    {
        RotationDegrees += 180 * delta;
    }
    else
    {
        RotationDegrees -= 180 * delta;
    }
}

Sauvegardez le script. Maintenant, l'objet tournera dans le sens horaire dans l'éditeur, mais si vous exécutez le jeu, il tournera dans le sens antihoraire.

Édition des variables

Ajouter et exporter une vitesse variable au script. La fonction set_speed après "setget" est exécutée avec votre entrée pour modifier la variable. Modifiez _process() pour inclure la vitesse de rotation.

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
using Godot;
using System;

[Tool]
public class MySprite : Sprite
{
    private float speed = 1;

    [Export]
    public float Speed {
        get => speed;
        set => SetSpeed(value);
    }

    // Update speed and reset the rotation.
    private void SetSpeed(float newSpeed)
    {
        speed = newSpeed;
        RotationDegrees = 0;
    }

    public override void _Process(float delta)
    {
        RotationDegrees += 180 * delta * speed;
    }
}

Note

Le code des autres nœuds ne s'exécute pas dans l'éditeur. Votre accès aux autres nœuds est limité. Vous pouvez accéder à l'arbre et aux nœuds, ainsi qu'à leurs propriétés par défaut, mais vous ne pouvez pas accéder aux variables définies par l'utilisateur. Si vous voulez le faire, les autres nœuds doivent également s'exécuter dans l'éditeur. Les nœuds chargés automatiquement (Autoload) ne sont pas du tout accessibles dans l'éditeur.

Instancier des scènes

Vous pouvez instancier des scènes emballées normalement et les ajouter à la scène actuellement ouverte dans l'éditeur. Assurez-vous de définir la racine de la scène comme étant le propriétaire de tous les nœuds créés de cette manière, sinon les nœuds ne seront pas visibles dans l'éditeur.

Si vous utilisez un tool :

func _ready():
    var node = Spatial.new()
    add_child(node) # Parent could be any node in the scene
    node.set_owner(get_tree().edited_scene_root)
public override void _Ready()
{
    var node = new Spatial();
    AddChild(node); // Parent could be any node in the scene
    node.Owner = GetTree().EditedSceneRoot;
}

Si vous utilisez 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)
    node.set_owner(get_scene())
public override void _Run()
{
    var parent = GetScene().FindNode("Parent"); // Parent could be any node in the scene
    var node = new Spatial();
    parent.AddChild(node);
    node.Owner = GetScene();
}

Avertissement

L'utilisation inappropriée de tool peut entraîner de nombreuses erreurs. Il est conseillé d'écrire d'abord le code comme vous le souhaitez, et seulement ensuite d'ajouter le mot-clé tool en haut. Veillez également à diviser votre code en une partie qui fonctionne dans l'éditeur et une partie qui s'exécute dans le jeu. De cette manières, vous pourrez trouver les bogues plus facilement.