ゲーム制作勉強中!あこがれだったプログラマーに今からなろう!

昔、あこがれていたプログラマー。今からでも勉強してみようと思い立ち、チャレンジ開始! 勉強メモや、悪戦苦闘な日々の記録です。

Unity経験者によるGodot実践メモ:変数とスクリプト・処理ルーチンについて

GodotとUnityの変数は宣言の仕方がちょっと違います。
Unityであれば、

private int a=3;

の様に、アクセス修飾子、変数の型、変数名と書いて宣言しますが、Godotの場合は、

var c : int	

の様に、varで宣言し、変数名の後ろに型を書きます。
そして、Unityの様にインスペクターで変更できるようにするには、publicではなく、

@export var max_speed:int = 18

の様に、頭に@exportをつけます。
注意しないといけないのは、@exportはあくまでインスペクターから編集できる様になるだけで、Unityのpublicの様に、
これだけで他のクラス(Godotで言えばシーン)と共有できる変数にはなりません。
Godotで他のシーンと変数を共有するには、Globalシーンを作って、そこで宣言したGlobal変数を作るか、引数で他のシーンに渡すかなどの工夫が必要みたいです。

また、Unity経験者にとってちょっとびっくりなのが、list型というのは存在しない様です。
配列型で代用する感じなのでしょうか。
この辺りはこれからゆっくりと学んでいこうと思います。

そして、スクリプトの基本的な構造もかなり違います。
Unityの様なクラス名の宣言はありません。
ファイル名がそのままクラス名になるようで、その名前の宣言すら省略されてしまったということでしょうか。
確かに、Unityでもファイル名とクラス名が違っているとエラーになるので、ならば最初から2箇所に書く必要ない!という事なのかもしれません🤣

最初の1行目に書くのは、このクラスが継承するものになります。

Unityの場合、

awake:GameObjectのインスタンス直後
start:Updateの直前
Update:毎フレーム実行(厳密には違う)
FixedUpdate:一定間隔で実行(厳密には違う)(物理関連の処理タイミング)

という処理順です。

Godotの場合、
_init:ノードのインスタンス直後
_ready:シーン内の全ノードが初期化された直後
_process:毎フレーム実行
_physics_process:一定間隔で実行(物理関連の処理タイミング)

になります。

変数名や関数名には命名規則があり、基本的には関数名は_から始まる様です。
また、単語と単語の間に_をいれ、「array_change_key_case」の様に記載します。
これは絶対ルールではない様ですが、エンジンが作成する関数名などが標準的に、この表記になるので、慣れの問題かもしれません。

スクリプト中のコメントは//ではなく、

# これはコメントです。

の様に#をつけます。

extends CharacterBody3D

@export var speed = 14
@export var fall_acceleration = 75
@export var jump_impulse = 20
@export var bounce_impulse = 16

var target_velocity = Vector3.ZERO

func _physics_process(delta):
	# We create a local variable to store the input direction
	var direction = Vector3.ZERO

	# We check for each move input and update the direction accordingly
	if Input.is_action_pressed("move_right"):
		direction.x = direction.x + 1
	if Input.is_action_pressed("move_left"):
		direction.x = direction.x - 1

最初の行でextednsで継承するクラスを指定します。
ちなみに、このCharacterBody3DはPhysicsBody3Dを継承している様です。

次に変数の宣言があるのは、似たイメージですが、関数の宣言の仕方が違います。
func 関数名:で関数を宣言します。
そして、Unityの様に{} は使いません。
代わりに、インデントを使う様です。

func _physics_process(delta):
	# We create a local variable to store the input direction
	var direction = Vector3.ZERO

この行の頭がインデントという空白で、GDScriptではこのインデントが同じ間はUnityでいう{}の範囲とみなす様です。
このあたり、Pythonを知っている人は馴染み深いそうですが、残念ながら僕はPythonを知らないので、
最初は違和感だらけでした🤣
そして、行の後ろに;も入りません。
楽といえば、楽なんですが、これも慣れるまでは違和感でした。

あと、Unityではpublic関数のように他クラスから使用可能な関数を作れますが、Godotではこういう概念はない様で、
インスタンス化されたシーンのスクリプトにある関数は、rootシーンからのパスが分かれば実行可能な様です。