投射物の発射

ℹ️ 留意事項

この記事は Godot 3から Godot 4 へ内容の書き換え中です。 Godot4では存在しない変数、関数が含まれている場合があります。もしその場合はリポジトリのIssuesまでご報告ください。

課題

プレイヤー/モブなどから投射物を発射させたい。

解決策

弾丸の設定

まず、インスタンス化可能な「弾丸」オブジェクトを設定します。使用するノードは以下の通りです。

 Area2D: Bullet
     Sprite2D
     CollisionShape2D

Sprite2Dのテクスチャは、好きな画像を使用できます。以下は例です。

alt alt

ノードの設定とスプライトおよび衝突判定形状を構成します。テクスチャが上向きに配置されている場合(上記例のように)は、Sprite ノードを 90° 回転させて右方向に向け、親オブジェクトの「前方」方向に一致するように調整してください。

スクリプトを追加し、Area2Dbody_enteredシグナルに接続してください。

extends Area2D

var speed = 750

func _physics_process(delta):
    position += transform.x * speed * delta

func _on_Bullet_body_entered(body):
    if body.is_in_group("mobs"):
        body.queue_free()
    queue_free()

この例では、オブジェクトが何かを衝突した場合、即座に弾丸を除去します。また、「mobs」グループにタグ付けされた対象物もすべて削除します。

射撃

弾丸の出現位置を設定が必要です。Marker2Dコンポーネントを追加し、弾丸を出現させたい場所に配置してください。以下は具体例で、銃身の先端に設置しています。「Muzzle」という名前を付けています。

alt alt

「プレイヤーが回転するにつれ、Muzzleのtransformは銃に対して常に同じ向きを保つことに注目してください。これは弾丸をスポーンさせる際に非常に便利です。変換行列を使用することで、適切な位置と方向を簡単に取得できるからです。新しい弾丸のtransformは、単にMuzzleのものと等しく設定するだけで済みます。

ヒント

この手法は「回転・移動」スタイルに限らず、あらゆる文字タイプに適用できます。単に、弾丸を表示させたい位置に Marker2D タグを挿入するだけで済みます。

キャラクタースクリプト内で、インスタンス化用の弾丸シーンを保持する変数を追加してください。

@export var Bullet : PackedScene

入力アクションが定義されているか確認してください。

    if Input.is_action_just_pressed("shoot"):
        shoot()

これでshoot()関数内では、弾丸インスタンスを生成しツリーに追加できます。よくあるミスとして、プレイヤーノードの子要素として直接追加してしまうケースがあります

func shoot():
    var b = Bullet.instantiate()
    add_child(b)
    b.transform = $Muzzle.transform

問題は、弾丸がプレイヤーの子オブジェクトであるため、プレイヤーが移動または回転した際に影響を受ける点です。

alt alt

この問題を解決するには、弾丸をワールドに追加が必要です。ここではプレイヤーのシーンルートノードを参照する owner 変数を使います。ただし、銃口の グローバル 変換行列も適用する必要がある点に注意してください。これを行わないと、弾丸が想定した位置に表示されない可能性があります。

func shoot():
    var b = Bullet.instantiate()
    owner.add_child(b)
    b.transform = $Muzzle.global_transform

alt alt

関連レシピ

–>

プロジェクトのダウンロード

プロジェクトコードはこちらからダウンロードできます。https://github.com/godotrecipes/2d_shooting