GDScript

マニュアルから多少順番が前後している。

export

@export系の注釈は値をインスペクターで編集可能にする

1 @export var n = 3
2 @export var s: String
3 @export_range(0, 100) var r

@onready

ノードの読み込みが終わるまで変数の初期化を遅延する(_ready)

1 @onready var child = get_node("foo")

ドキュメントコメント

シャープ二つで始める

1 ## x + 2
2 func add2(x: int) -> int:
3     ## add2
4     return x + 2

アサーション

1 assert(1 == 0, "ERROR!")

シグナル

シグナルを定義

1 signal hoge

シグナルによって呼び出されるメソッドを定義

1 func _on_hoge(args) -> void:
2     print("called signal: hoge", args)

シグナルを接続。呼び出し。

1 self.connect("hoge", _on_hoge)
2 var s: Signal = Signal(hoge)
3 s.emit([1, 2, "cat"])

呼び出し可能オブジェクト

Godotの関数は基本的にメソッドなのでselfを渡す必要があるようだ。

1 var x = Callable(self, "add2")
2 assert(x.call(3) == 5)

変数

変数はvarで宣言する。

静的変数にはstatic修飾子をつける。これはクラススコープになる。

1 var x = 1
2 var x: int = 1
3 static var y = 2

定数はconst修飾子で宣言する

1 const x: int = 1

列挙型

自動的に値が割り振られる定数のようなもの。クラスのトップレベルでないと宣言できないようだ。

1 enum e {foo, bar, baz}

関数

大体、思った通りに動く。関数は常にselfを持つので指定する必要はない。

 1 ## x + 2
 2 func add2(x: int) -> int:
 3     ## add2
 4     return x + 2
 5 
 6 func add1(x: int) -> int: return x + 1
 7 
 8 func add3(x = 1): return x + 3
 9 
10 func fcf(f: Callable) -> int:
11     return f.call(1)

if

まあ普通

for

pythonとほぼ同じ

match

pythonと同じ

クラス

スクリプトファイルは無名クラスである。

ファイルの先頭で名前とアイコンを設定できる。

クラスに名前をつけるとノードの追加パネルで参照できるようになる。

1 @icon("res://icon2.png")
2 class_name MyClass

継承

1 extends Node

スーパークラスを参照するときはsuperキーワードが使える

コンストラクタは_init

* * *

load, preload

Godotのファイルシステムからスクリプトを読み込むときには必要になるらしいが、今のところ使用しなくても動作している。あとで、検証。

* * *

ツール

シーンを実行しなくてもエディタ(2D, 3D)などから実行できる。

1 @tool
2 extends Sprite2D
3 
4 func _process(delta: float) -> void:
5     if Engine.is_editor_hint():
6         self.rotation += PI * delta
7     else:
8         self.rotation -= PI * delta
9     

エクスポート

ドキュメントコメント

##二つで開始するだけ。ファイルの先頭および、各種メンバーに設定できる。

静的型付け

キャストが必要になるケースがあるようだが、まあ、それは実際に直面するまで。

## フォーマット文字列

基本的に%sだけ覚えておけばいいと思う。

1 f = func():
2     const x: String = "foo %s bar"
3     const y: String = x % 2
4     print(y)
5     print("%s, %s, %s", [22, "foo", self])
6 f.call()

デバッグ

複数インスタンスを同時にデバッグすることもできるようだ。あとで検証したい。

ブレークポイントはテキストエディタの行番号の左側をクリックするか、breakpointキーワードで設定できる。

アイドルとプロセス

グループ

右ペインのグループからグループを作成できる。グループに登録されているノードをまとめて選択するための機能のようだ。

手動でグループに登録するにはシーンエディタでノードを選択してから、グループペインのチェックボックスをオンにする。

1 add_to_group("hoge")

ノードとシーンインスタンス

ノードを取得。

1 const node = self.get_node(foo)
2 node.show()

ノードをインスタンス化。クラス名をつけておく必要がある。

1 var sp = Sprite2D.new()
2 self.add_child(sp)
3 sp.queue_free()
4     
5 var nd = Foo.new()
6 nd.show()
7 nd.show()
8 nd.queue_free()

シーンのインスタンス化

シーンはツールバーから作成するようだ。この部分の説明が欠けているためにわかりにくい。

インスタンス化は次のようにする。

1 const scene = preload("res://foo.tscn")
2 var instance = scene.instantiate(PackedScene.GEN_EDIT_STATE_DISABLED)
3 self.add_child(instance)

オーバーライド可能なメソッド

基本的に毎フレーム呼び出されるメソッド。それをオーバーライドして使う。

今はスクリプトに集中したいので、あとで。

一時停止

一時停止というよりはSceneTreeが重要だろう。しかし、動かせないと動作が分かりにくいので、あとで。

ファイルシステム

リソース

preloadで読み込むことができる。

シーンはパックされたリソースなので、インスタンス化する必要がある。

シングルトン

グローバル変数の代わりに自動ロードされるシングルトンクラスを使うのがよい。ということらしい。

プロジェクト設定から設定する。

SceneTree

プログラムが起動すると、ルートシーンが作られ、そこにルートビューポートが作られる。それらは以下のようにして取得できる。

1 var tree = get_tree()
2 print(tree)
3 var root = tree.root
4 print(root) 

シーンの固有ノード

ボタンなどがパスが変わるとアクセスできなくなるので、パスではなく固有名でアクセスするようにする。ノードペインのコンテキストメニューから選択できる。