投射物の発射

ℹ️ 留意事項

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

課題

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

解決策

この例では、CharacterBody3D:移動操作 で設定した「ミニ戦車」を使用します。

弾丸の設定

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

 Area3D: Bullet
     MeshInstance
     CollisionShape

メッシュには、Godotに標準で備わっているプリミティブ形状を使用するか、以下のようなものを作成できます。

alt alt

メモ

ここに掲載している弾丸モデルを使用したい場合は、Kenney’s “Blaster Kit”から入手できます。

メッシュを MeshInstance に追加し、衝突形状もそれに合わせてスケール調整してください。

警告

必ず MeshInstanceArea3D ノードの前方方向(-Z 軸)と揃えてください。そうしないと、弾丸が正しく飛んでいるように見えませんよ!

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

extends Area3D

signal exploded

@export var muzzle_velocity = 25
@export var g = Vector3.DOWN * 20

var velocity = Vector3.ZERO


func _physics_process(delta):
    velocity += g * delta
    look_at(transform.origin + velocity.normalized(), Vector3.UP)
    transform.origin += velocity * delta


func _on_Shell_body_entered(body):
    emit_signal("exploded", transform.origin)
    queue_free()

カスタムの重力ベクトル g を使用することで、戦車の砲弾が綺麗な弧を描くように、大砲からどのように飛ぶかを制御できます。もし、飛び道具を直線的に移動させたい場合は、_physics_process() で重力を適用している行を削除してください。

look_at() をフレームごとに使用すると、弾丸は常に進行方向を向くようになります。

また、explodedシグナルも発出します。これを利用して爆発エフェクトやダメージ効果を実装できます(ただし詳細な実装は別のレシピで解説します)。

射撃

タンク内(または射撃オブジェクト)の任意の位置に、弾丸が出現させたい場所に Marker3D 子要素を追加してください。今回の戦車の場合、砲身の先端部分に配置します。

alt alt

次に、インスタンス化する弾シーンを追加する方法です。

@export var Bullet: PackedScene

そして、_process() または _unhandled_input()(入力をキャプチャしている箇所)に、以下のコードを追加して弾丸を生成してください。

if Input.is_action_just_pressed("shoot"):
    var b = Bullet.instantiate()
    owner.add_child(b)
    b.transform = $Cannon/Muzzle.global_transform
    b.velocity = -b.transform.basis.z * b.muzzle_velocity

これで完了です。シーンを実行して実際に試してみます。

関連レシピ

–>