🕌

Godot公式「最初の2Dゲーム(Godot3)」をGodot4で実装した話

2023/04/16に公開

はじめに

Godot公式が公開してるチュートリアルゲーム「最初の2Dゲーム」は、投稿時点(2023/04/16)ではGodot3を用いて説明されています。最新版のGodot4を用いてトライする際、言語差異によってチュートリアル通りに実装出来ない個所についてまとめます。
私と同じくGodot4の学習を志す方の一助になれば幸いです!

対象者

  • Godotにはじめて触れる方
  • 基礎的なプログラミング知識を有している方

使用環境

  • Windows10
  • Godot 4.0.2

言語差異について

チュートリアルの章立てに沿っていきます

1. プロジェクトの設定

「Stretch」オプションの設定

Modeの設定

画面の拡大縮小に関して、Modeには「2D」を指定するようありますが、Godot4では「canvas_items」に変更されているようです。

3. プレイヤーのコーディング

メンバー変数の宣言

exportの宣言

exportの宣言スタイルが変更されています。

# Godot3.x
export var speed = 400 

# Godot4.x
@export var speed = 400	

4. 敵の作成

ノードの設定

子ノードの追加

VisibilityNotifier2Dを子ノードに追加するようありますが、Godot4ではネーミングが変更されているため、VisibleOnScreenNotifier2Dを追加します。
最終的に下記の構成になります。

  • RigidBody2D( Mob という名前)
    • AnimatedSprite2D
    • CollisionShape2D
    • VisibleOnScreenNotifier2D

アニメーションの設定

インスペクタの Playingプロパティを「オン」に設定するようありますが、該当のメニューがインスペクタに存在しないため、無視で問題ありませんでした。
アニメーションの確認自体は、シーン一覧のAnimatedSprite2D>画面下部の「アニメーションフレーム:」の再生ボタンから可能です。

Enemyスクリプト

_ready()の実装

AnimatedSprite2DのPropertiesのネーミングに変更があります。
詳細はGodot Docs参照

# Godot3.x
func _ready():
    $AnimatedSprite.playing = true
    var mob_types = $AnimatedSprite.frames.get_animation_names()
    $AnimatedSprite.animation = mob_types[randi() % mob_types.size()]

# Godot4.x
func _ready():
    $AnimatedSprite2D.play()
    var mob_types = $AnimatedSprite2D.sprite_frames.get_animation_names()
    $AnimatedSprite2D.animation = mob_types[randi() % mob_types.size()]

5. メインシーン

ノードの設定

子ノードの追加

Position2Dを子ノードに追加するようありますが、Godot4ではネーミングが変更されているため、Marker2Dを追加します。
最終的に下記の構成になります。

  • Node( Main という名前)
    • Timer( MobTimer という名前)
    • Timer( ScoreTimer という名前)
    • Timer( StartTimer という名前)
    • Marker2D( StartPosition という名前)

Mainスクリプト

exportの宣言

既に触れましたが、exportの宣言スタイルが変更されているため、注意が必要です。

# Godot3.x
export(PackedScene) var mob_scene
var score

# Godot4.x
@export var mob_scene:PackedScene
var score

_on_MobTimer_timeout():の実装

PathFollow2DのProperties、PackedSceneのMethods、乱数生成関数の一部にネーミング変更があります。

# Godot3.x
    var mob = mob_scene.instance()

    var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
    mob_spawn_location.offset = randi()

    var direction = mob_spawn_location.rotation + PI / 2

    mob.position = mob_spawn_location.position

    direction += rand_range(-PI / 4, PI / 4)
    mob.rotation = direction

    var velocity = Vector2(rand_range(150.0, 250.0), 0.0)
    mob.linear_velocity = velocity.rotated(direction)

    add_child(mob)
    
# Godot4.x
    var mob = mob_scene.instantiate()	# 3: instance -> 4: instantiate
    
    var mob_spawn_location = get_node("MobPath/MobSpawnLocation")
    mob_spawn_location.progress = randi()	# 3: offset -> 4: progress

    var direction = mob_spawn_location.rotation + PI / 2

    mob.position = mob_spawn_location.position

    direction += randf_range(-PI / 4, PI / 4)	# 3: rand_range -> 4: randf_range
    mob.rotation = direction

    var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
    mob.linear_velocity = velocity.rotated(direction)

    add_child(mob)

6. ヘッドアップディスプレイ

show_game_over():の実装

タイマー制御に用いる関数がyieldからawaitに変更されています。

# Godot3.x
func show_game_over():
    show_message("Game Over")
    yield($MessageTimer, "timeout")
    
    $Message.text = "Dodge the\nCreeps!"
    $Message.show()
    yield(get_tree().create_timer(1), "timeout")
    $StartButton.show()
    
# Godot4.x
func show_game_over():
    show_message("Game Over")
    await $MessageTimer.timeout	# 3: yield -> 4: await
    
    $Message.text = "Dodge the \nCreeps!"
    $Message.show()
    await get_tree().create_timer(1.0).timeout	# 3: yield -> 4: await
    $StartButton.show()

まとめ

チュートリアル中に存在する修正内容は以下の通りです。

  • Stretchオプションのネーミング変更
    • Modeの「2D」 → 「canvas_items」
  • exportの宣言の変更
    • expert ~~ → @export
    • export(△△) var ○○ → @export var ○○:△△
  • ノード名の変更
    • VisibilityNotifier2D → VisibleOnScreenNotifier2D
    • Position2D → Marker2D
  • AnimatedSprite2DのPropertiesの変更
    • $AnimatedSprite.playing = true → $AnimatedSprite2D.play()
    • frames → sprite_frames
  • PathFollow2DのPropertiesの変更
    • instance -> instantiate
  • PackedSceneのMethodsの変更
    • offsetprogress
  • 乱数生成関数のネーミング変更
    • rand_range → randf_range
  • タイマー制御の関数の変更
    • yield → await

参考

https://docs.godotengine.org/ja/stable/index.html
https://docs.godotengine.org/en/latest/index.html

Discussion