エディタでコードを実行する

tool とは何ですか?

`` tool``は強力なコード行で、スクリプトの先頭に追加すると、エディタで実行できるようになります。スクリプトのどの部分をエディタで実行し、どの部分をゲームで実行するか、または両方で実行するかを決定することもできます。

多くの目的のためにそれを使用できますが、レベル設計をするときに、予測が難しいものを視覚的に提示するためにとても役立ちます。使用例は次のとおりです:

  • 物理演算(重力)の影響を受ける砲弾を発射する大砲を持っている場合、エディタで砲弾の軌跡を描くことができ、レベル設計がはるかに簡単になります。
  • ジャンプの高さが異なるジャンプパッドがある場合、プレイヤーがジャンプした場合に到達する最大ジャンプ高を描画でき、レベル設計も容易になります。
  • プレイヤーがスプライトを使用せず、コードを使用して描画を行う場合に、エディタでその描画コードを実行してプレイヤーを表示できます。

危険

tool スクリプトはエディタ内で実行され、現在編集されているシーンのシーンツリーにアクセスできます。エディタには tool スクリプトの潜在的な誤用に対する保護が含まれていないため、これは警告も伴う強力な機能です。特に Node.queue_free を介してシーンツリーを操作するときは、エディタがそれに関連するロジックを実行している間にノードを解放するとクラッシュする可能性があるため、非常に注意してください。

使用方法

スクリプトをツールにするには、コードの先頭に tool キーワードを追加します。

現在エディタで実行されているかどうかを確認するには、Engine.editor_hint を使用します。

たとえば、エディタでのみコードを実行する場合は、次を使用します:

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

一方、ゲームでのみコードを実行する場合は、前の表現を単純に否定します:

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

上記の2つの条件のいずれにも該当しないコードは、エディタとゲームの両方で実行されます。

以下は _process() 関数がどのように見えるかです:

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.

注釈

エディタでの変更は永続的です。この場合、スクリプトを削除すると、ノードは回転方向を維持します。不要な変更を加えないように注意してください。

やってみましょう

シーンに Sprite ノードを追加し、テクスチャをGodotアイコンに設定します。スクリプトをアタッチして開き、次の手順に変更します:

tool
extends Sprite

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

スクリプトを保存して、エディタに戻ります。これで、オブジェクトが回転するのが見えるはずです。ゲームを実行すると、ゲームも回転します。

../../_images/rotating_in_editor.gif

注釈

変更が表示されない場合は、シーンをリロードします(閉じてからもう一度開きます)。

次に、どのコードがいつ実行されるのかを選択しましょう。_process() 関数を次のように変更します:

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

スクリプトを保存します。これで、オブジェクトはエディタでは時計回りに回転しますが、ゲームを実行すると、反時計回りに回転します。

Editing variables

Add and export a variable speed to the script. The function set_speed after "setget" is executed with your input to change the variable. Modify _process() to include the rotation speed.

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

注釈

他のノードからのコードはエディタで実行されません。他のノードへのアクセスは制限されています。ツリーとノード、およびそれらのデフォルトのプロパティにはアクセスできますが、ユーザー変数にはアクセスできません。そうしたい場合は、他のノードもエディタで実行する必要があります。 AutoLoadノードにはエディタではまったくアクセスできません。

シーンのインスタンス化

You can instantiate packed scenes normally and add them to the scene currently opened in the editor. Be sure to set the scene root as the owner of all the nodes created this way or the nodes won't be visible in the editor.

If you are using 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)

If you are using 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())

警告

tool を不適切に使用すると、多くのエラーが発生する可能性があります。最初にあなたが望むようにコードを書き、次に tool キーワードを追加することをお勧めします。また、エディタで実行する部分とゲームで実行する部分にコードを分割してください。これにより、バグを簡単に見つけることができます。