初めてのスクリプト作成

In this lesson, you will code your first script to make the Godot icon turn in circles. As we mentioned in the introduction, we assume you have programming foundations.

This tutorial is written for GDScript, and the equivalent C# code is included in another tab of each codeblock for convenience.

../../_images/scripting_first_script_rotating_godot.gif

参考

To learn more about GDScript, its keywords, and its syntax, head to the GDScript section. To learn more about C#, head to the C#/.NET section.

プロジェクトの設定

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

../../_images/scripting_first_script_icon.svg

We need to create a Sprite2D node to display it in the game. In the Scene dock, click the Other Node button.

../../_images/scripting_first_script_click_other_node.webp

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

../../_images/scripting_first_script_add_sprite_node.webp

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

../../_images/scripting_first_script_scene_tree.webp

A Sprite2D node needs a texture to display. In the Inspector on the right, you can see that the Texture property says <empty>. To display the Godot icon, click and drag the file icon.svg from the FileSystem dock onto the Texture slot.

../../_images/scripting_first_script_setting_texture.webp

注釈

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

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

../../_images/scripting_first_script_centering_sprite.webp

新規スクリプトの作成

To create and attach a new script to our node, right-click on Sprite2D in the Scene dock and select Attach Script.

../../_images/scripting_first_script_attach_script.webp

The Attach Node Script window appears. It allows you to select the script's language and file path, among other options.

Change the Template field from Node: Default to Object: Empty to start with a clean file. Leave the other options set to their default values and click the Create button to create the script.

../../_images/scripting_first_script_attach_node_script.webp

注釈

C#スクリプトの名前は、そのクラス名に一致する必要があります。この場合では、ファイル名を MySprite2D.cs とします。

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

extends Sprite2D

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

注釈

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

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

注釈

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

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

ハロー、ワールド!

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

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

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

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

注釈

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

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

../../_images/scripting_first_script_print_hello_world.webp

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

回転させるには

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

var speed = 400
var angular_speed = PI

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

注釈

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

アイコンを移動するには、ゲームループ内のフレームごとにアイコンの位置と回転を更新する必要があります。 Node クラスの _process() 仮想関数を使用できます。 Sprite2Dなどの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 は、 Sprite2D が拡張する Node2D クラスから継承されたプロパティです。これはノードの回転を制御し、ラジアン単位で指定します。

Tip

In the code editor, you can Ctrl + Click (Cmd + Click on macOS) on any built-in property or function like position, rotation, or _process to open the corresponding documentation in a new tab.

シーンを実行して、Godot アイコンがその場で回転することを確認します。

../../_images/scripting_first_script_godot_turning_in_place.gif

注釈

C#では、 _Process() が受け取る delta 引数は double である点に注意して下さい。このため回転に適用する際には、その値を float に変換する必要があります。

前進させるには

ノードを動かしてみましょう。次の2行を _process()関数に追加し、前の行の rotation += angular_speed * delta と同様にインデントします。

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

注釈

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

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

完全なスクリプト

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

extends Sprite2D

var speed = 400
var angular_speed = PI


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

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

    position += velocity * delta