静的型付けGDScript¶
このガイドでは、次の内容について学習します:
GDScriptで型を使用する方法
静的型はバグの回避に役立ちます
この新しい言語機能をどこで、どのように使うかは完全にあなた次第です!
静的型は、変数、定数、関数、パラメータ、戻り値の型に使用できます。
注釈
型付きGDScriptはGodot 3.1から使用できます。
静的型付けの概要¶
型付きのGDScriptを使うことで、Godotはさらに多くのエラーを、あなたの書いたコードから検出することができます。メソッドを呼び出すと引数の型が表示されるため、あなたとチームメイトは作業中により多くの情報が得られます。
あなたが在庫管理システムをプログラミングしていると想像してください。 Item
ノード、次に Inventory
をコーディングします。アイテムをインベントリに追加するには、あなたのコードを操作する人々は常に Item
を Inventory.add
メソッドに渡すべきだとします。型を設定すれば、これを強制できます:
# In 'Item.gd'.
class_name Item
# In 'Inventory.gd'.
class_name Inventory
func add(reference: Item, amount: int = 1):
var item = find_item(reference)
if not item:
item = _instance_item_from_db(reference)
item.amount += amount
型付きGDScriptのもう1つの重要な利点は、新しい警告システムです。バージョン3.1以降のGodotではコードを記述する際に警告が表示されます: 実行時に問題を引き起こす可能性のあるコードのセクションが識別されますが、コードをそのままにしておくかどうかを決めることができます。これについては後で説明します。
静的型を使用すると、コード補完も改善されます。以下に、 PlayerController
というクラスを例に動的な型と静的な型の補完の違いを示します。
あなたはおそらく以前に変数にノードを格納していて、オートコンプリートの提案なしでピリオドが残るようにタイプしました:

これは動的コードによるものです。Godotは、関数に渡されているノードまたは値の型を認識できません。ただし型を明示的に記述すると、すべてのpublicメソッドと変数がノードから取得されます:

将来的には、型付きGDScriptによってコードのパフォーマンスも向上します。ジャストインタイムコンパイルやその他のコンパイラの改善はすでにロードマップに盛り込まれています!
概して、型付きプログラミングはより構造化された経験をあなたに与えます。それはエラーを防ぎ、あなたのスクリプトを自己文書化の面で改善するのを助けます。これはチームや長期的なプロジェクトで作業している場合に特に役立ちます:調査によると他の人が書いたコードを読んだり、過去に自分が書いたスクリプトの内容を忘れている事に、開発者が大半の時間を費やしています。コードが明確で構造化されているほど、速く理解ができ、速く前に進むことができます。
静的型付けの使用方法¶
変数または定数の型を定義するには、変数の名前の後にコロンを書き、その後に指定する型を書きます。例: var health: int
。 これにより、変数の型は常に保持されます:
var damage: float = 10.5
const MOVE_SPEED: float = 50.0
コロンを書いて型を省略すると、Godotは型を推測しようとします:
var life_points := 4
var damage := 10.5
var motion := Vector2()
現在、使えるのは3つのタイプの… 型 (type) です:
コアクラスとノード (
Object
、Node
、Area2D
、Camera2D
など)Your own custom classes. Look at the new class_name feature to register types in the editor.
注釈
Godotは割り当てられた値から自動的に型を設定するので、定数の型ヒントを書く必要はありません。ただしコードの意図をより明確にするために、これを自分で行うこともできます。
カスタム変数型¶
カスタムクラスを含む任意のクラスを型として使用できます。スクリプトで使用する方法は2つあります。最初の方法は、定数の型として使用するスクリプトをプリロードすることです:
const Rifle = preload("res://player/weapons/Rifle.gd")
var my_rifle: Rifle
2番目の方法は、作成時に class_name
キーワードを使用することです。上記の例では、Rifle.gdは次のようになります:
extends Node2D
class_name Rifle
class_name
を使用する場合、GodotはRifle型をグローバルにエディタに登録します。定数にプリロードすることなく、どこでも使用できます:
var my_rifle: Rifle
変数のキャスト¶
型キャストは型付き言語の重要な概念です。キャストは、ある型から別の型への値の変換です。
extends Area2D
であなたのゲームに敵がいると仮定してください。あなたはそれを PlayerController
と呼ばれるスクリプトが付いている KinematicBody2D
と衝突させたいのです。衝突を検出するには on_body_entered
シグナルを使用します。型付きコードでは、 _on_body_entered
コールバックでは、検出したボディは一般的な PhysicsBody2D
になり、 PlayerController
にはなりません。
この PhysicsBody2D
がプレイヤーであるかどうかを確認するには、 as
キャストキーワードを使用し、再度コロン :
を使用して変数にこの型を使用させます。これにより、変数は PlayerController
タイプに固定されます:
func _on_body_entered(body: PhysicsBody2D) -> void:
var player := body as PlayerController
if not player:
return
player.damage()
ここではカスタムされた型を扱っているため、 body
が PlayerController
を継承しない場合、 player
変数は null
に設定されます。これを使って、bodyがplayerかどうかを確認できます。このキャストのおかげで、player変数の完全なオートコンプリートもできるようになります。
注釈
組み込み型でキャストしようとして失敗すると、Godotはエラーをスローします。
セーフ・ライン¶
セーフ・ラインを確保するためにキャストを使用することもできます。セーフ・ラインは、はGodot 3.1の新しいツールで、あいまいなコード行(ライン)が安全(セーフ)な型であることを教えてくれます。型指定されたコードと動的なコードを混在させると、Godotは実行時に命令がエラーを引き起こすかどうかを知るための十分な情報が得られない場合があります。
これは子ノードを取得したときに起こります。たとえばタイマーを考えてみましょう。動的コードでは、$Timer
でノードを取得できます。GDScriptは ダック・タイピング をサポートしているので、あなたのタイマーが Timer
型であっても、それは Node
であり Object
でもあり、その2つのクラスを継承しています。動的GDScriptでは、ノードが呼び出す必要のあるメソッドを持っている場合、その型については気にする必要はありません。
ノードを取得したときに期待される型をGodotに伝えるためにキャストを使用できます: ($Timer as Timer)
、 ($Player as KinematicBody2D)
など。Godotは、そのタイプが機能することを確認し、機能する場合は、行番号がスクリプトエディタの左側で緑に変わります。

セーフ・ラインではない行(line 7)とセーフ・ライン (line 6 とline 8)¶
注釈
セーフ・ラインの色分けをオフにしたり、エディタ設定でカラーを変更することができます。
アロー(->)による関数の戻り値の定義¶
関数の戻り値の型を定義するには、宣言の後に ->
を記述し、その後に戻り値の型を記述します:
func _process(delta: float) -> void:
pass
void
型は、関数が何も返さないことを意味します。変数と同様に、任意の型を使用できます:
func hit(damage: float) -> bool:
health_points -= damage
return health_points <= 0
独自のノードを戻り値の型として使用することもできます:
# Inventory.gd
# Adds an item to the inventory and returns it.
func add(reference: Item, amount: int) -> Item:
var item: Item = find_item(reference)
if not item:
item = ItemDatabase.get_instance(reference)
item.amount += amount
return item
静的と動的: どちらかのみを利用する¶
型付きGDScriptと動的GDScriptは、同じプロジェクト内に共存できます。しかし、コードベースの一貫性のためにも、仲間のためにも、どちらかスタイルに統一することをお勧めします。同じガイドラインに従うことで全員が協力しやすくなり、他の人が書いたコードを素早く読んで理解できるようになります。
型付けされたコードはもう少し記述が必要ですが、上で説明したような利点があります。次に、同じ空のスクリプトを例にあげます。動的なスタイルでは:
extends Node
func _ready():
pass
func _process(delta):
pass
そして静的型付けでは:
extends Node
func _ready() -> void:
pass
func _process(delta: float) -> void:
pass
このように、エンジンの仮想メソッドで型を使用することもできます。シグナルのコールバックも、他のメソッドと同様に、型を使用できます。動的スタイルの body_entered
シグナルは次のとおりです:
func _on_Area2D_body_entered(body):
pass
同じコールバックをタイプヒントとともに使用します:
func _on_area_entered(area: CollisionObject2D) -> void:
pass
パラメータを自動的にキャストするには、例えば``CollisionObject2D`` などを独自の型に自由に置き換えます:
func _on_area_entered(bullet: Bullet) -> void:
if not bullet:
return
take_damage(bullet.damage)
bullet
変数にはここで任意の CollisionObject2D
を保持できますが、それが独自に作成したノードである Bullet
であることを確認します。それ以外の、 Area2D
のような Bullet
を継承していないノードの場合、 bullet
変数は null
になります。
警告システム¶
注釈
GDScriptの警告システムについてのドキュメントは GDScript警告システム に移動しました。
型の指定ができない場合¶
この紹介の締めくくりに、タイプヒントを使用できないいくつかのケースを取り上げましょう。 以下の例はすべてエラーを引き起こすでしょう。
Enumを型として使うことは出来ません:
enum MoveDirection {UP, DOWN, LEFT, RIGHT}
var current_direction: MoveDirection
配列の個々のメンバの型を指定することはできません。これにより、エラーが発生します:
var enemies: Array = [$Goblin: Enemy, $Zombie: Enemy]
for
キーワード・ループの各要素にはすでに異なる型があるため、 for
ループ内で型の割り当てを強制することはできません。したがって、次のように書くことは**できません**:
var names = ["John", "Marta", "Samantha", "Jimmy"]
for name: String in names:
pass
2つのスクリプトは、循環するようにに相互に依存することはできません:
# Player.gd
extends Area2D
class_name Player
var rifle: Rifle
# Rifle.gd
extends Area2D
class_name Rifle
var player: Player
概要¶
型付きGDScriptは強力なツールです。Godotのバージョン3.1から利用できるようになり、より構造化されたコードの記述、一般的なエラーの回避、スケーラブルシステムの作成に役立ちます。将来的には、コンパイラーの最適化によって静的型のパフォーマンスも大幅に向上するでしょう。