チュートリアル:「ACTION GAME MAKER をゼロから使う」—第3章

第3章:弾を発射して敵を倒す

第3章の目標

第2章では、以下のことを達成しました。

  • プレイヤーキャラクターが歩いたりジャンプしたりできるシンプルなステージを作成した。

本章ではさらに一歩進み、以下の機能の実装方法を説明します。

  • プレイヤーが弾を発射して敵を倒す。

第3章を完了した後の効果の例を動画でご覧ください。


「プレイヤーが射撃して敵を倒す」の実装方法の計画

まずは、どのようなステップが必要か考えてみましょう。

  • プレイヤー(Player)Shot(射撃)状態 を追加する必要があります。
  • 弾を発射するためには、新しい Bullet(弾)オブジェクト を作成する必要があります。
  • 現在、敵がいないため、Enemy(敵)オブジェクト も作成する必要があります。

したがって、第3章の目標は以下の通りです。

  1. Bulletオブジェクト を作成する
  2. Playerに Shot状態 を追加する
  3. Enemyオブジェクト を作成する

そして、実際に 敵を倒す を実現するには、ダメージを与えるプロセス、つまり 攻撃システム(Attack System) を実装する必要があります。

ACTION GAME MAKERには、攻撃とダメージを処理するための専用システムが用意されています。
したがって、本格的に制作を始める前に、
このシステムがどのように機能するかを少し詳しく説明しましょう。

ACTION GAME MAKER における「攻撃(Attack)」と「ダメージ(Damage)」

攻撃ヒット(Attack Hits)

Player オブジェクトに含まれる
HitArea2D / HitCollision
および
AttackArea2D / AttackCollision
というノードを覚えていますか?

ACTION GAME MAKER では、
AttackArea2D からの AttackCollision
HitArea2D からの HitCollision と衝突した際に、
システムが自動的にダメージ計算を処理します。

さらに、Godot に搭載されている
CollisionLayer(衝突レイヤー)
および
CollisionMask(衝突マスク)
機能を使用することで、
「どのオブジェクトが衝突できるか、できないか」を細かく制御できます。


CollisionLayer と CollisionMask

以前、壁の衝突について説明したように、
Godot は CollisionLayerCollisionMask
という仕組みを使って衝突関係を制御しています。

これらを、
衝突判定に「深さ」のルールを追加するものと捉えることができます。

設定パネルでは、それぞれ以下の意味を持ちます:

  • Layer(レイヤー) → 「このオブジェクトがどのレイヤーに属するか」
  • Mask(マスク) → 「このオブジェクトがどのレイヤーと衝突できるか」

たとえば:

  • AttackCollision のマスクが 第1レイヤー第2レイヤー のみにチェックされている場合、
    第3レイヤー に存在する HitCollision には当たらない

この仕組みにより、
例えばキャラクターの攻撃判定が自分自身の攻撃判定領域に当たるような、
不自然な状況を回避できます。


ダメージ処理フロー(Damage Processing)

攻撃が成功してヒットした場合、
ACTION GAME MAKER は自動的に以下の処理フローを実行します:

  1. 被攻撃オブジェクトの HP から、
    攻撃オブジェクトの 攻撃力(Attack Power)
    (攻撃力の値は BaseSettings で設定)を引く。

  2. その後、無敵時間(Invincibility)
    (これも BaseSettings で設定)を有効にし、
    受傷オブジェクトが一定時間、再びダメージを受けないようにする。


:white_check_mark: これらのシステムにより、
ACTION GAME MAKER は攻撃とダメージの中心的なロジックを自動で処理します。
あなたは、適切にノードとパラメータを設定するだけで済みます。

「いいね!」 1

弾丸オブジェクト(Bullet Object)の作成

攻撃システムの基本的なメカニズムを理解した後、次に実際に 弾丸(Bullet) を作成していきます。

弾丸もまた Game Object(ゲームオブジェクト) であるため、プレイヤーキャラクターを作成するのと同様の手順になります。

  • 画像の指定
  • 移動速度などの設定の調整
  • 可視化スクリプト(Visual Script)による処理

ただし、弾丸には重要な違いがあります。
弾丸はプレイヤーの入力デバイスによって直接制御されないことです。

弾丸の発射と移動は、「Shoot Bullet(弾丸を発射)」 アクションによって行われるため、弾丸に別途複雑な移動ロジックを書く必要はありません。


弾丸用のGame Objectを作成する

  1. 新しいシーンタブを開き、ルートノードとして Game Object を選択します。

  1. Create New Object(新規オブジェクト作成) ウィンドウで以下の設定を行います。
  • Object Name:bullet
  • Template:bullets
  • Type:bullet_base

  1. 弾丸オブジェクトのテンプレートが読み込まれます。
  • [unsaved (*)] を右クリックし、シーンを bullet.tscn として保存します。


弾丸の画像を設定する

次に、弾丸に画像を指定します。
弾丸にアニメーションをつけて、よりクールな効果を出すこともできますが、このチュートリアルではシンプルにするために静止画像を使用します。

  1. 下の画像を右クリックして、自分のコンピューターに保存します。

bullet

  1. 保存した bullet.png を、エディタ内の FileSystem(ファイルシステム) パネルにドラッグアンドドロップします。

  2. Scene(シーン)パネルSprite2D ノードを選択します。

  • Inspectorで、Texture 属性(現在は <empty>)に bullet.png をドラッグアンドドロップします。

弾丸のMoveAndJumpSettingsを調整する

弾丸の速度はプレイヤーよりも速くしたいです。
プレイヤーの移動速度は 300 なので、弾丸の速度を 600 に設定します。

  1. Scene(シーン)パネルMoveAndJumpSettings ノードを選択します。

  1. Inspectorで、以下の値をすべて 600 に設定します。
  • Horizontal Speed(水平速度)
  • Vertical Speed(垂直速度)


:white_check_mark: これで、画像表示と独立した速度設定を持つ基本的な弾丸オブジェクトが作成されました。

弾の攻撃判定範囲(Attack Hitbox)の調整

AttackArea2D での Collision Layer と Mask の設定

デフォルトでは、このオブジェクトは Layer 1 にあり、
その Mask1 と 2 に設定されています。
つまり、第 1 層と第 2 層にあるオブジェクトに当たる可能性があります。

しかし、Player(プレイヤー)Layer 1 にあり、
同様に Mask 1、2 を使用しています。
このままでは、弾が発射された瞬間にプレイヤーと衝突してしまいます。

これを防ぐために、弾の衝突設定を
Layer 3 に移動し、Layer 3 とのみ衝突するようにします。

  1. Scene(シーン)パネルAttackArea2D を選択します。

  2. Inspector(インスペクター)Collision(衝突) セクションを展開します。

  1. Collision Layer / Mask を選択するパネルが表示されます。
  • Layer1 → 3 に変更
  • Mask1, 2 → 3 だけをチェック に変更

これで、弾はもはやプレイヤーと衝突しなくなります。


AttackCollision のサイズ調整

現在、弾の攻撃判定範囲は弾のスプライト画像よりもはるかに大きいです。
これを縮小し、弾本体に合わせる必要があります。

  1. Scene(シーン)パネルAttackCollision を選択します。

  2. エディタビューで、形状の周りのオレンジ色の制御点をドラッグしてサイズを調整します。

  • 攻撃判定領域が弾の画像よりわずかに大きい程度に調整します。


:white_check_mark: これで、弾の衝突設定は正しく完了しました:

  • 弾はもはやプレイヤー自身に当たらない
  • 攻撃判定範囲も弾のサイズに適切にマッチしています

弾のスクリプトの設定(Bullet Script)

弾の壁との衝突(CollisionShape2D)のサイズはすでに適切なので、調整は不要です。
基本的な設定が完了したら、次に弾用のスクリプトを作成します。

弾が消えるべき状況は以下の通りです:

  • に命中したとき
  • タイル(Tile) に命中したとき
  • カメラの視界の外に移動したとき

そのため、2つの状態(Move と Disappear)だけあれば十分です。
以下に設定手順を説明します。


スクリプトの追加

  1. Bullet(GameObject) ノードを選択します。

  2. Scene(シーン)パネルで、:scroll:+(Attach Script、スクリプトの追加) ボタンをクリックします。

  1. 既定のオプションのまま、Create をクリックして、bullet.vs という名前の新しいスクリプトを作成します。


「Move」状態の設定

デフォルトの State001 を Move 状態として使用します。
弾の移動は「シューター(Shooter)」によって制御されるため、この状態自体に追加のアクション設定は必要ありません。

  1. State001 を選択します。

  2. Inspector で、TitleMove に変更します。


「Disappear」状態の作成

  1. Move 状態の右側を右クリックし、Add State(状態の追加) を選択します。

  2. 新しく表示された State001 を選択し、TitleDisappear に名前を変更します。

  3. Inspector で、+ Add Executable Action をクリックします。

  1. RemoveSelf を選択し、Add をクリックします。

  • これで、弾が Disappear 状態に入ると、すぐにシーンから削除されます。

Move → Disappear の接続

以下のいずれかの条件が満たされたら、弾は Disappear 状態に入るべきです:

  • と衝突したとき
  • タイルと衝突したとき
  • カメラの範囲の外に移動したとき

複数の条件を AND(かつ) / OR(または) で組み合わせて、1つのリンクに設定できます。

ここでは OR ロジックを使用します:

敵に命中 OR タイルに命中 OR カメラの範囲外

手順は以下の通りです:

  1. Move 状態を右クリックし、Add Link(リンクの追加) を選択します。

  2. リンクを Disappear 状態に接続します。

  3. 新しく作成されたリンクを選択し、Inspector で + Add Condition をクリックします。

  1. ContactWithHitArea を選択します。

  2. Select All Sides(すべての方向を選択) をチェックし、Add をクリックします。

  1. 再度 + Add Condition をクリックします。

  2. 今回は ContactWithTile を選択します。

  3. 方向を All Directions に設定し、論理条件を OR にし、Add をクリックします。

  1. 次に + Add Other Condition をクリックし、3つ目の条件を追加します。

  2. 下にスクロールして、Offscreen(画面外) を選択します。

  3. Target TypeThis Node に設定し、論理条件を OR にし、Add をクリックします。

  1. 条件の設定が以下の図の通りになっていることを確認します。

  • AND / OR の設定が正しくない場合は、アイコンをクリックして切り替えることができます。

なぜ「ContactWithHitArea」は AND にしないのか?

AND / OR の設定は、前の条件との関係を表します。
ContactWithHitArea最初の条件なので、AND でも OR でも結果に影響はありません。

しかし、これを他の条件の下に移動すると、AND が効いてきます。
混乱を避けるため、ここでは OR のままにしておきましょう。


:white_check_mark: 弾のスクリプトの設定はこれで完了です!
シーンを保存を忘れないでください。

Player オブジェクトを修正して弾を発射するようにする

プレイヤーが弾を発射できるようにするには、4つのステップを完了する必要があります。

A. 射撃アニメーションの作成
B. BulletsSettings ノードの追加と設定
C. Connector ノードの追加と設定(発射位置)
D. ビジュアルスクリプトに 「Shoot Bullet(射撃)」 ステートを作成する

それでは、最初のステップから始めましょう:射撃アニメーションの追加

A. 射撃アニメーションの作成

まず、プレイヤーがいつ射撃を行うかを考えましょう。
このチュートリアルでは 『ロックマン(Mega Man)』のようなデザイン を採用しているため、
直感的には以下の3つの射撃状態が必要になるように思えます。

  • 立ち射撃
  • 移動中射撃
  • 空中射撃

しかし、以前作成した Move(移動)アニメーション は、
キャラクターが走りながら手を前に伸ばす姿勢であり、
これは「移動中射撃」のアニメーションとしてそのまま使用できます。

つまり、実際には 2つの新しいアニメーション を作成するだけでよいのです。

  • Ground Shot(地面射撃)
  • Air Shot(空中射撃)

先ほどと同様に、必要な射撃のポーズはすでにロード済みのスプライトシートに含まれています。
全体のフローは以下の通りです。

アニメーションの作成 → キーフレームの挿入 → Animation Set へのロード


「Ground Shot」と「Air Shot」アニメーションの作成

  1. Scene タブPlayer に切り替え、
    エディタービューを 2D に設定します。

  2. AnimationPlayer ノードを選択します。

  3. 下部の Animation パネルで、Animation をクリックして新しいアニメーションを作成します。

  1. 新しいアニメーションに Ground Shot と名付けます。

  1. Sprite2D を選択し、Inspector で Animation 属性を展開します。

  2. Frame1 に設定します(地面に立って手を前に伸ばしたフレーム)、
    そして :key:+(Add Keyframe、キーフレーム追加) ボタンをクリックします。

  1. 表示されたウィンドウで Create RESET Track をチェック外し、
    Create をクリックします。

  1. ステップ 2~3 を繰り返し、もう一つのアニメーションを作成します。
    今回は Air Shot と名付けます。

  1. Sprite2D を選択したまま、Frame2 に設定します(空中で手を前に伸ばしたフレーム)、
    そして :key:+(Add Keyframe) ボタンを押してキーフレームを挿入します。


アニメーションを Animation Set に登録する

  1. Player(GameObject) ノードを選択します。

  2. Inspector で Bulk Load Animations(アニメーション一括ロード) ボタンをクリックします。

  1. これにより、Ground ShotAir Shot が自動的に Animation Set に追加されます。

B. BulletsSettings ノードの追加と設定

  1. Scene(シーン) ウィンドウの左上隅にある +(Add Child Node、子ノードの追加) ボタンをクリックします。

  1. BulletsSettings を選択し、Create をクリックします。

  1. Inspector(インスペクター) で、Array\[BulletData\] フィールドをクリックして、弾丸リストを展開します。

  2. + Add Bullet ボタンをクリックします。

  3. 表示された空の項目をクリックし、New BulletData を選択します。

  1. 新しく作成された BulletData の項目をクリックし、その詳細設定を展開します。

  2. Bullet Base Settings を展開し、
    Bullet Object Path の右側にある :page_with_curl: アイコンをクリックし、
    以前に作成した bullet.tscn を選択します。

  1. Unlimit ShotsOn に設定します。
    これは、シーン内に無限数の弾丸が存在できることを意味します。

  1. Initial Behavior(初期動作) を展開します。

  1. Initial BehaviorFireObjectDirection に設定します。

  1. これで、bullet.tscn は無制限に生成され、
    そして弾丸を発射したオブジェクトが向いている方向に自動的に飛行するようになります。

C. Connector ノードの追加と設定

Connector ノードは、ビジュアルスクリプト内で「位置」を指定するために使用します。
たとえば、弾丸の発射開始位置や、オブジェクトの生成位置などです。

今回は、Connector弾丸の発射点として使用するため、
射撃アニメーション中のキャラクターの手の先端の位置に配置する必要があります。

  1. Player(GameObject) ノードを選択します。

  2. 左上にある +(Add Child Node、子ノードの追加) ボタンをクリックし、
    Create New Node(新規ノード作成) ウィンドウを開きます。

  1. Connector を選択し、Create をクリックします。

  1. AnimationPlayer ノードを選択し、
    現在のアニメーションを Ground Shot に切り替えます。

  1. 再度 Connector ノードを選択します。

  2. エディタのツールを Move Mode(移動モード) に切り替えます。

  1. ✛(接続点のマーク) をドラッグし、
    キャラクターの手の先端の位置に配置します。

これで、Connector の設定は完了です

「いいね!」 1

D. 射撃状態(Shoot State)の追加

次に、弾を発射するための状態を追加します。
必要な射撃状態は以下の通りです:

  • Ground Shot(地面射撃)
  • Moving Shot(移動中射撃)
  • Air Shot(空中射撃)

ただし、空中射撃には特別な処理が必要です
もし単に Air Shot から Jump に戻してしまうと、
毎回射撃がジャンプ動作を再びトリガーし、キャラクターがどんどん跳ね上がってしまいます。

この問題を解決するため、Jump 状態を2つの状態に分割する必要があります:

  • Jump
  • Air

それぞれの役割は以下の通りです:

  • Jump 状態は「ジャンプの起動」のみを担当し、すぐにAirに切り替わる
  • Air 状態はキャラクターが空中にある状態を表す
  • Air 状態下で、キャラクターの足元が地面に接触した場合(下方向にTileに衝突した場合)、Idle に戻る
  • Air Shot は終了後に Air に戻ることで、ジャンプ動作の繰り返しを防ぐ

それでは、順を追って構築していきましょう。


Ground Shot と Moving Shot 状態の作成

  1. Script(スクリプト) タブに切り替えます。

  2. Idle 状態の左側に新しい状態を作成します。

  3. 新しく作成した State001Ground Shot と名付けます。

  4. Select Animation でアニメーションを Ground Shot に指定します。

  1. + Add Execution Action(実行アクションの追加) をクリックします。

  2. 実行アクションとして FireBullet を選択します。

  3. Bullet Data で、以前に作成した弾のオブジェクトを指定します。

  4. Connector 右側の Assign ボタンをクリックします。

  5. Select Node ウィンドウで、以前に作成した Connector ノードを選択します。

  1. Bullet Data = bulletConnector = Connector が正しいことを確認し、Add をクリックします。

  2. 次に Moving Shot を作成します。Ground Shot をコピーして使用します:

    • Ground Shot を右クリックし、Copy を選択

- **Move** 状態の右側を右クリックし、**Paste State** を選択
- 新しく作成された状態を **Moving Shot** と名付けます
  1. Continue Previous Animation をチェックします。
    Moving Shot は Move と同じアニメーションを使用するため、アニメーションの切り替えは不要です。


Idle ↔ Ground Shot と Move ↔ Moving Shot の接続

キャラクターが Idle または Move 状態にあるとき、
Attack キーを押すと対応する射撃状態に入ります。
射撃は 0.3秒 後に元の状態に戻ります。

  1. Idle を右クリックし、Ground Shot への Link を追加します。

  2. 属性で Trigger On Input をチェックします。

  3. Input Operations List(Array\[InputCondition\]) を展開します。

  4. + Add Input をクリックして新しい入力条件を追加します。

  5. 空白の項目をクリックし、New Input Condition を選択します。

  1. Input Condition を展開し、Input Key = Attack に設定します。

  1. その Link を右クリックし、Copy を選択します。

  1. Move を右クリックし、Paste Link を選択します。

  1. その Link を Moving Shot に接続します。

  2. Ground Shot を右クリックし、Idle に戻る Link を追加します。

  3. Inspector で + Add Condition をクリックします。

  1. 条件として Elapsed Time を選択します。

  2. 時間を1秒から 0.3秒 に変更します。

  1. その Link を右クリックし、Copy を選択します。

  2. Moving Shot を右クリックし、Paste Link を選択し、Move に戻るリンクを接続します。

これで、地面射撃関連の状態は完了です。


地面射撃のテスト

  1. 右上隅の Run Project(F5) をクリックします。

  2. Idle または Move 状態で X を押すと、弾が発射されるはずです。

  3. 正常に動作しない場合は、以下の点を確認してください:

    • アニメーションが再生されない → 状態のアニメーション設定と AnimationPlayer を確認
    • アニメーションは再生されるが弾が発射されない → FireBullet アクションの設定を確認
    • 弾は出現するが移動しないまたは方向が間違っている → BulletsSettings を確認

問題がなければ、テストウィンドウを閉じます。


Jump を Jump と Air 状態に分割

  1. Jump の左側に新しい状態を作成します。

  2. State001Air と名付けます。

  3. その AnimationJump(空中での表示用)に設定します。

  1. Jump を右クリックし、Air への Link を追加します。

  2. Inspector で、Conditions for SwitchingUnconditional(無条件)に設定します。
    (Jump はすぐに Air に切り替わる)

  1. 既存の Jump → Idle の Link を切り取ります:選択後、右クリック → Cut

  1. Air を右クリックし、Paste Link を選択し、Idle に接続します。

  2. これにより、着地判定は Air から Idle に戻るようになります。

  1. テストを行い、ジャンプ → 空中 → 着地 の流れが正しく動作するか確認します。

Air Shot の作成と接続

Air ShotGround Shot と同じロジックを持ち、アニメーションのみ異なるため、
既存の状態を再利用できます。

  1. Ground Shot を右クリックし、Copy を選択します。

  2. Air 状態の左側に貼り付けます。

  1. Ground Shot (1)Air Shot と名付けます。

  2. Inspector で、AnimationAir Shot に変更します。

  1. Idle → Ground Shot の Link をコピーします。

  2. Air を右クリックし、その Link を貼り付け、Air Shot に接続します。

  1. Ground Shot → Idle の Link をコピーします。

  2. Air Shot を右クリックし、その Link を貼り付け、Air に戻るリンクを接続します。


最終テスト

プロジェクトを再度実行します:

  • Idle または Move 状態で X を押す → プレイヤーが弾を発射
  • Z でジャンプした後、空中で X を押す → プレイヤーが空中射撃

この2つの状況がともに正常に動作すれば、
:tada: あなたの射撃システムは完成です!

「いいね!」 1

敵オブジェクトの作成

次に、敵オブジェクトを作成していきます。
まずは最も簡単な敵から始めましょう——左右に移動するだけの敵です。

プレイヤーキャラクターを作成するときと同じ手順で進めます。

  • ステージの作成
  • 画像とアニメーションの設定
  • 各ノードの設定
  • 可視化スクリプトを使って動作を記述

enemy GameObjectの作成

  1. エディタビューをScriptから2Dに戻します。

  2. 新しいシーンタブを作成し、Create Root NodeGameObjectを選択します。

  1. Create New Objectウィンドウで以下の設定を行います。

    • Object Nameenemy
    • Template:Character
    • Type:2DSprite Character Base
    • Object Group:Enemy

  1. Unsavedを右クリックし、シーンをenemy.tscnとして保存します。

敵の画像とアニメーションの設定

次に、敵の画像とアニメーションを設定します。
弾丸のように左右対称の円形とは異なり、この敵は非対称なキャラクターです。
移動方向に応じて左右反転する必要があります。

左右反転はAnimation Setによって自動的に処理されるため、
このプロセスはプレイヤーのキャラクターとまったく同じになります。

  • Sprite2D を使ってテクスチャを設定する
  • AnimationPlayer を使ってアニメーションを作成する
  • 敵(GameObject)ノードに Animation Set を設定する

Sprite2Dの設定

  1. 下の画像を右クリックして、パソコンに保存します。

enemy

  1. 保存した画像をエディタのFileSystemにドラッグアンドドロップしてインポートします。

  2. SceneパネルでSprite2Dノードを選択します。

  3. Inspectorで、enemy.pngTextureプロパティにドラッグアンドドロップします。
    画像を複数のフレームに分割する必要がないため、これでSpriteの設定は完了です。


CollisionShape2Dを使って衝突形状を調整する

現在の衝突領域はキャラクターの画像よりも明らかに小さいため、サイズを調整する必要があります。

  1. SceneパネルでCollisionShape2Dノードを選択します。

  2. 衝突ボックスの四隅にあるオレンジ色の制御点をドラッグして、
    キャラクターの画像のサイズにほぼ一致するように調整します。


AnimationPlayerの設定とAnimation Setの作成

Animation Setを使用するには、少なくとも1つのアニメーションが必要です。
この敵はフレームの切り替えを必要としないため、単純なアニメーションを1つ作成するだけで十分です。

  1. AnimationPlayerノードを選択します。

  2. 下部のアニメーションウィンドウで、AnimationNewをクリックします。

  1. 新しいアニメーションにMoveと名付け、作成します。
    トラックを追加する必要がないため、このアニメーションはすでに完了しています。

  1. **enemy(GameObject)**ノードを選択します。

  2. InspectorAnimationPlayerをクリックします。

  3. 正しいAnimationPlayerが指定されていることを確認し、OKをクリックします。

  1. Inspectorで**Bulk Load Animations(アニメーションを一括読み込み)**ボタンをクリックします。

  2. Animation Setを展開し、Moveアニメーションが正しく登録されていることを確認します。

敵の BaseSettings(基本設定)を調整する

敵を本当に倒せるようにするには、HP(ヒットポイント)無敵時間 などの設定を調整する必要があります。


ヒットポイント(HP)の設定

  1. BaseSettings ノードを選択します。

  2. Inspector で、HPMax HP の両方を 1 から 3 に変更します。

  • これにより、敵は 3ポイントのダメージ を受けると HP が 0 になります。

無敵時間(Invincibility)の設定

無敵時間 は、オブジェクトが一度ダメージを受けた後、極めて短い時間内に複数回 HP が減るのを防ぐためのものです。
この仕組みがないと、敵が一瞬で複数の弾に同時に命中して即死してしまう可能性があります。

プレイヤーの射撃間隔は 0.3秒 に設定されているため、
無敵時間を 約0.2秒 に設定するのが適切です。

  • 0.4秒 に設定すると、連射中の2発目を敵が無視してしまう可能性があります。
  • 正確に0.3秒 に設定すると、近距離で射撃した場合、2発目が正しく命中判定されない可能性があります。

また、無敵システムには 点滅効果 も組み込まれており、
無敵状態のキャラクターは周期的に点滅します。

無敵時間を 0.2秒 に設定する場合、
点滅間隔を 0.1秒 にすると、点滅効果がより明確に観察できます。

  1. Inspector で、Invincibility Duration1.0 から 0.2 に変更します。

  2. その後、Blink Duration1.0 から 0.1 に変更します。

敵のヒットボックスの調整

次に、敵のヒットボックス領域を設定します。
以前に弾オブジェクトの衝突レイヤーをレイヤー3に設定したため、
敵もレイヤー3に配置する必要があります。これにより、弾との正しい相互作用が可能になります。


HitArea2D で Collision Layer と Mask を設定する

  1. HitArea2D ノードを選択します。

  2. Inspector で Collision セクションを展開します。

  3. LayerMask の両方を 3 に設定します。

  • これにより、敵のヒットボックスが弾の攻撃衝突と正しく作用するようになります。

HitCollision のサイズ調整

現在の HitCollision 領域は大きすぎるので、調整が必要です。

  1. Scene パネルで HitCollision ノードを選択します。

  2. 衝突ボックスの四隅にあるオレンジ色のコントロールポイントをドラッグし、
    敵の可視画像よりやや大きめになるように調整します。

敵の攻撃判定(Attack Collision)の調整

次に、敵の攻撃判定領域を設定します。
弾丸とは異なり、敵の攻撃判定はプレイヤーとのみ相互作用すればよいです。

プレイヤーの衝突レイヤー(Collision Layer / Mask)はデフォルト設定のままなので、
ここではレイヤーやマスクの設定を変更する必要はありません
攻撃判定のサイズを調整するだけでOKです。

  1. Scene パネルで AttackCollision ノードを選択します。

  2. 攻撃衝突ボックスの四隅にあるオレンジ色のコントロールポイントをドラッグし、
    敵のヒットボックス(Hitbox)のサイズと一致または近いサイズに調整します。

敵のスクリプトの設定(Enemy Script)

敵は左右に移動し、HPが0になったら消えるだけでよいです。
理論的には、Move Left(左に移動)Move Right(右に移動)Vanish(消える) の3つの状態で実現できますが、
ここでは Template Movement(テンプレート移動) アクションを利用します。これは簡単なパトロール移動を自動で処理します。

そのため、ここでは 2つの状態 を作成するだけで済みます:

  • Template Move
  • Vanish

敵のHPが0になると、Template MoveからVanishに切り替わり、敵が消えます。


ビジュアルスクリプトのバインド(Visual Script)

  1. enemy(GameObject) ノードを選択します。

  2. Attach Script(スクリプトをバインド) ボタンをクリックします。

  1. デフォルトの名前 enemy.vs のまま、Create をクリックします。


「Template Move」と「Vanish」状態の作成

  1. デフォルトの State001Template Move にリネームします。

  2. Inspectorで、Animation CategoryMove に設定します。

  3. + Add Executable Action(実行アクションを追加) をクリックします。

  1. MovementTemplate を選択します。

  2. Move Time3 に設定し、Can’t Fall Off Ledges(崖から落ちない) にチェックを入れます。

    • これにより、敵は3秒間ある方向に歩き、
      崖にぶつかると自動で方向を反転します。

  1. Add をクリックします。

  2. Template Move 状態の右側の空白領域を右クリックし、Add State を選択します。

  3. 新しく作成された State001Vanish にリネームします。

  4. + Add Executable Action をクリックします。

  1. RemoveSelf を選択して追加します。

状態構造が以下の図と一致していれば、状態の作成は完了です。


Template Move → Vanish の接続

  1. Template Move 状態を右クリックし、Add Link を選択して Vanish に接続します。

  2. Inspectorで + Add Condition をクリックします。

  1. HPIsZero を選択します。

  2. デフォルト設定(TargetType:This Node)のまま Add をクリックします。

接続状態が例と一致していれば、設定は完了です。


敵をStage1シーンに配置する

敵の準備が整ったので、次に stage1 シーンに配置し、プレイヤーと一緒にテストします。

  1. エディタビューを Script から 2D に戻します。

  2. stage1 シーンのタブに切り替えます。

  3. Sceneパネルで Player ノードを選択します。

  4. Playerが選択された状態で、FileSystemから enemy.tscn をシーンにドラッグ&ドロップし、
    Playerの右側に配置します。

  1. ゲームを実行してテストします。

すべて正しく設定されていれば:

  • 敵は約 3秒 ごとに左右にパトロールします
  • 3発の弾 に当たると消えます


トラブルシューティングチェックリスト(Troubleshooting Checklist)

  • 敵が左右に移動しない
    Template Move 状態内の設定を確認してください

  • 敵が方向転換しても向きが反転しない
    → 敵ノードの Animation Set を確認し、Template Move状態で正しいアニメーションが指定されているか確認してください

  • 敵が1発の弾で消える
    → 敵の BaseSettings 内の HP、Max HP、Invincibility の設定を確認してください

  • 弾が敵に当たらない
    → 敵の HitArea Collision Layer / Mask
    弾の AttackArea Collision Layer / Mask を確認してください

  • 弾が当たっても消えない
    → 弾のスクリプト内の Move → Disappear のリンクを確認し、
    Disappear状態に RemoveSelf アクションが設定されているか確認してください

「いいね!」 1

プレイヤーにダメージ処理を追加

これまでに、このセクションの目標は達成しました:
「プレイヤーは射撃によって敵を倒すことができる。」

しかし、まだ問題が残っています:

  • 敵には攻撃判定(Attack Hitbox)がすでに存在しますが、
    プレイヤーが攻撃を受けた際に
    何の反応もありません
  • さらに、プレイヤー自身にも攻撃判定があるため、
    現在はプレイヤーが敵と接触するだけで敵を倒せてしまいます。

次に、プレイヤーの設定を調整して、より合理的な動作を実現します:

  • プレイヤーがダメージを受けた際に反応を示す
  • **「ダメージアニメーション」**を再生する
  • 攻撃を受けた後は**無敵時間(Invincibility)**に入る
  • プレイヤーの**ヒットボックス(Hitbox)アタックボックス(Attack Box)**を正しく調整する
  • 最後に、**ビジュアルスクリプト(Visual Script)**に対応するダメージ処理ロジックを追加する

「ダメージを受けた(Damage Taken)」アニメーションを追加し、Animation Set に登録する

  1. エディタのビューを 2D に戻し、シーンタブを player に切り替えます。

  2. AnimationPlayer ノードを選択します。

  3. 下部のウィンドウで Animation ボタンをクリックし、New を選択します。

  1. アニメーション名を DamageTaken と入力し、OK をクリックします。

  1. Sprite2D ノードを選択します。

  2. 「ダメージを受けた」状態に使用するフレームは、1行目右端の画像(フレーム 4)です。
    Inspector の Animation プロパティで、Frame4 に設定します。

  1. Frame の右側にある :key:+(Add Keyframe、キーフレームを追加) ボタンをクリックします。

  2. 表示されたウィンドウで、Create RESET Track のチェックを外し、Create をクリックします。

  1. これで「DamageTaken」アニメーションの作成は完了です。
    次に、これを Animation Set に登録します。
    Player(GameObject) ノードを選択してください。

  2. Inspector で Bulk Load Animations(アニメーションを一括読み込み) ボタンをクリックします。

  1. 一見何も追加されていないように見えますが、実際にはアニメーションは2ページ目にあります。
    Load All Animations ボタンの上にある \u003e(表示は \u003c1/2\u003e)をクリックして、2ページ目に切り替えます。

  1. リストに DamageTaken アニメーションが表示されていることを確認します。

BaseSettingsで無敵時間(Invincibility Time)を調整する

次に、プレイヤーの無敵時間を設定します。
プレイヤーのキャラクターなので、少し長めの無敵時間が適切です。
ここでは無敵時間を 1秒 に設定し、点滅間隔0.2秒 にします。

また、無敵状態中は攻撃判定(Hitbox)を無効化する必要があります。
無敵状態ではHPが減らないものの、Hitboxを無効化しないと、攻撃との衝突が発生してしまうためです。


設定手順

  1. BaseSettings ノードを選択します。

  2. Inspectorで、Blink Duration1.0 から 0.2 に変更します。

  1. Blink Duration の下にある Disabled Hit Collision List(Array…) を展開し、
    + Add Element をクリックします。

  2. 表示された空白の項目をクリックし、New DisableCollisionData に設定します。

  1. 項目が DisableCollisionData に変更されたら、それをクリックして設定を展開します。

  2. Assign ボタンをクリックします。

  3. 表示されたノード選択ウィンドウで、HitCollision を選択し、OK をクリックします。


設定が完了すると以下のようになります:

  • プレイヤーがダメージを受けたとき
  • 1秒間の無敵状態に入る
  • その間、キャラクターは 0.2秒間隔で点滅する
  • さらに HitCollisionが無効化され、再び攻撃判定が発生しない

攻撃判定と被弾判定の調整(Attack / Hit Collisions)

まず、HitCollision(被弾判定) のサイズを調整しましょう。
現在のサイズは大きすぎるので、少し小さくします。

また、このチュートリアルでは ロックマン(Mega Man)スタイル のシステムを採用しているため、
プレイヤーキャラクター自体には攻撃判定(Attack Hitbox)は必要ありません。

(近接攻撃キャラクターを作る場合、この判定は重要になりますが、
本チュートリアルでは近接攻撃は追加しません。)

したがって、ここでは AttackArea2D を完全に削除します。


HitCollision のサイズ調整

  1. HitCollision ノードを選択します。

  2. コリジョンボックスの四隅の制御点をドラッグして、
    壁のコリジョン(CollisionShape2D)よりわずかに大きくなるように調整します。


AttackArea2D の削除

  1. AttackArea2D ノードを右クリックします。

  2. メニューの下部から Delete(削除) を選択します。

  1. 以下のような確認ウィンドウが表示されます。
    AttackArea2D とその子ノードの AttackCollision を削除するか尋ねられます。
    OK をクリックして削除を完了します。