初めてのスクリプト作成

このレッスンでは、GDScript を使ってGodotアイコンを回転させるスクリプトをコーディングします。 in the introduction で触れたように、プログラミングの基礎知識があることを前提にしています。同等の C# コードは、便宜上、別のタブに含まれています。

../../_images/scripting_first_script_rotating_godot.gif

参考

GDScript、そのキーワード、およびその構文の詳細については、 GDScript reference にアクセスしてください。

参考

C#の詳細については、C# basics を参照してください。

プロジェクトの設定

では 新規project を作成して下さい、白紙の状態から始めます。プロジェクトには1つの画像ファイルが含まれている必要があります。今回はコミュニティでのプロトタイピングによく使用されるGodotアイコンを使います。

ゲームに表示するには、Spriteノード を作成する必要があります。シーンドックで、[Other Node] ボタンをクリックします。

../../_images/scripting_first_script_click_other_node.png

検索バーに「Sprite」と入力してノードをフィルタリングし、Spriteをダブルクリックしてノードを作成します。

../../_images/scripting_first_script_add_sprite_node.png

これで、[シーン]タブにスプライトノードのみが追加されました。

../../_images/scripting_first_script_scene_tree.png

スプライトノードを表示するにはテクスチャが必要です。右側のインスペクターで、Textureプロパティが「[空]」と表示されていることがわかります。 Godotアイコンを表示するには、ファイル icon.png をFileSystemドックからTextureスロットにドラッグアンドドロップします。

../../_images/scripting_first_script_setting_texture.png

注釈

また ビューポートに画像をドラッグアンドドロップすることで、スプライトノードを自動的に作成することもできます。

../../_images/scripting_first_script_dragging_sprite.png

次に、ビューポートの Godotアイコン をドラッグし、ゲームビューの中央に配置します。

../../_images/scripting_first_script_centering_sprite.png

新規スクリプトの作成

新しいスクリプトを作成してノードにアタッチするには、シーンドックでスプライトを右クリックし、[スクリプトをアタッチ]を選択します。

../../_images/scripting_first_script_attach_script.png

「ノードにスクリプトをアタッチする」("Attach node Script")ウィンドウが表示されます。このウィンドウでは、スクリプトの言語やファイルパスなどのオプションを選択できます。

テンプレートを デフォルト から Empty に変更して、クリーンなファイルから始めます。デフォルトで他のオプションを変更せず、[作成]ボタンをクリックしてスクリプトを作成します。

../../_images/scripting_first_script_attach_node_script.png

スクリプトワークスペースに新しいSprite.gd ファイルが開いて下記のコードが表示されます。

extends Sprite

すべてのGDScriptファイルは暗黙的なクラスです。 extends キーワードは、このスクリプトが継承または拡張クラスであることを定義します。この場合 スクリプトの Sprite クラスは、 Node2DCanvasItemNode など、拡張クラスを含む、Spriteノードのすべてのプロパティと関数にアクセスできます。

注釈

GDScriptでは、 extends キーワードの行を省略した場合 Reference 、 Godotがアプリケーションのメモリを管理するために クラスは暗黙的に拡張されます。

継承されたプロパティには、ノードの texture のように、インスペクタードックに表示されるプロパティも含まれます。

注釈

デフォルトでは、インスペクタータブ内ではノードのプロパティを「Title Case」(タイトルケース)で表示し、大文字の単語をスペースで区切ります。 GDScriptコード内では、これらのプロパティは「snake_case」(スネークケース)およびアンダースコアで区切られた小文字で表記します。

インスペクター内で任意のプロパティの名前にカーソルを合わせると、その説明とコード内での識別子が表示されます。

ハロー、ワールド!

現在、スクリプトは何もしません。 手始めに「Hello、world!」というテキストを下部[出力]パネルに表示させましょう。

スクリプトに次のコードを追加します。

func _init():
    print("Hello, world!")

こまかく見てみましょう。 func キーワードは、 _init という名前の新しい関数を定義します。これは、クラスのコンストラクターの特別な名前です。この関数を定義すると、エンジンがメモリ内にオブジェクトまたはノードを作成すると _init() が初期化のため呼ばれます。

注釈

GDScriptはインデントベースの言語です。コードが機能するには、 print() という行の先頭にあるタブが必要です。これを省略したり、行を正しくインデントしなかったりすると、エディターはそれを赤で強調表示し、"Unexpected indentation(予期しないインデント)" というエラーメッセージを表示します。

シーンをまだ保存していない場合は保存し、 F6 を(macOSでは Cmd + R )押して実行します。展開された下部の ** [Output]** パネルを確認します。 "Hello, world!"と表示されているはずです。

../../_images/scripting_first_script_print_hello_world.png

次に _init() 関数を削除して、 extends Sprite という行だけを残します。

回転させるには

スプライトノードを移動および回転させるときが来ました。そのために、スクリプトに2つのメンバー変数を追加します。1秒あたりのピクセル数で表した移動速度と1秒あたりのラジアンで表した角速度です。

var speed = 400
var angular_speed = PI

メンバー変数は、スクリプトの先頭付近、"extends" 行の後、関数の前に置かれます。このスクリプトがアタッチされているすべてのノードインスタンスは、 speed (速度)プロパティと angular_speed (角速度)プロパティの独自のコピーを持つことになります。

注釈

Godotの角度はデフォルトではラジアン単位で計算されますが、度単位で角度を計算したい場合に使える組み込み関数やプロパティも用意されています。

アイコンを移動するには、ゲームループ内のフレームごとにアイコンの位置と回転を更新する必要があります。 Node クラスの _process() 仮想関数を使用できます。 SpriteなどのNodeクラスの拡張クラスで定義すると、Godotはフレームごとに関数を呼び出し、最後のフレームからの経過時間である delta という名前の引数を渡します。

注釈

ゲームは、1秒あたりに数多くの画像をレンダリングすることで機能します。各画像はフレームと呼ばれ、ループしてレンダリングされます。ゲームが画像を生成する速度をフレーム/秒(FPS)で測定します。ほとんどのゲームは60FPSを目指していますが、低速のモバイルデバイスでは30 FPS、バーチャルリアリティゲームでは90〜240のような数値が見られる場合があります。

エンジンとゲームの開発者は、一定の時間でゲームの世界を更新しレンダリングするために最善を尽くしますが、フレームのレンダリング時間には常に小さな変動があります。これはエンジンがフレームレートに依存しないモーションを作成するため提供するデルタタイムです。

スクリプトの最後に、関数を定義します。

func _process(delta):
    rotation += angular_speed * delta

func キーワードは新しい関数を定義します。その後、関数名と引数を括弧で囲んで記述する必要があります。コロンで定義を終了し、それに続くインデントされたブロックが関数のコンテンツまたは命令になります。

注釈

_init()_process() のように関数の先頭がアンダースコアで始まることに注意してください。慣例により、Godotの仮想関数、つまり、エンジンとやりとりするため オーバーライドされる組み込み関数は、アンダースコアから始まります。

関数内の行 rotation += angular_speed * delta は、フレームごとにスプライトの回転角をインクリメントします。ここで、 rotation は、 Sprite が拡張する Node2D クラスから継承されたプロパティです。ノードの回転を制御し、ラジアンで指定します。

ちなみに

コードエディタで、「position」、「rotation」、「_ process」などの組み込みプロパティまたは関数をCtrlキーを押しながらクリックすると対応する説明文が新しいタブで開きます。

シーンを実行して、Godotアイコンが指定した位置で回転することを確認します。

../../_images/scripting_first_script_godot_turning_in_place.gif

前進させるには

ノードを動かしてみましょう。次の2行を _process()関数に追加し、前の行にそろえインデントします。

var velocity = Vector2.UP.rotated(rotation) * speed

position += velocity * delta

すでに見たように、 var キーワードは新しい変数を定義します。スクリプトの先頭に配置すると、クラスのプロパティとして定義されます。関数内で定義されたものはローカル変数となり、関数のスコープ内でのみ参照されます。

velocity という名前のローカル変数を定義します、方向と速度の両方を表す2Dベクトルです。ノードを前進させるには、Vector2クラスの定数 Vector2.UP(上向きのベクトル)を用います、回転は Vector2.rotated() メソッドを呼び出して実行します。この式 Vector2.UP.rotated(rotation) は、アイコンに対して前方を指すベクトルです。 speed プロパティを掛けることで、ノードを前方に移動するための速度が得られます。

ノードのpositionvelocity * deltaを追加して移動しています。このposition自体は Vector2 というタイプで、2次元ベクトルを表すGodotの組み込み型です。

シーンを実行してGodotの頭がぐるぐる回るのを確認してください。

../../_images/scripting_first_script_rotating_godot.gif

注釈

このようなノードの移動では、壁や床との衝突は考慮されません。 ref:doc_your_first_2d_game では、衝突を検出しながらオブジェクトを移動させる別のアプローチを学びます。

このノードは現在、ノード自身で移動します。次のパート プレイヤーの入力を聞く では、プレイヤーの入力を使ってノードをコントロールします。

完全なスクリプト

参考までに、Sprite.gdファイル全体は次のようになります。

extends Sprite

var speed = 400
var angular_speed = PI


func _process(delta):
    rotation += angular_speed * delta

    var velocity = Vector2.UP.rotated(rotation) * speed

    position += velocity * delta