チュートリアル: 「0からはじめるACTION GAME MAKER」第三章

第三章:弾を撃って敵を倒せるようにしよう

第三章の目標

第二章では、

「プレイヤーキャラクターが歩いて、ジャンプする簡単なステージを作る」

ところまでを達成しました。

今回は「プレイヤーがショットで敵を倒す」ところまでを解説します。

第三章の完成イメージはこんな感じです。

「プレイヤーがショットで敵を倒す」の作り方を考える

まずは作り方を考えてみましょう。

プレイヤーには「ショット」のステートが必要になりそうですが、打ち出す弾が必要になりますから、「弾」のオブジェクトを作る必要もあります。

また、「敵」のオブジェクトもまだないので作る必要があります。

第三章では、「弾」オブジェクトを作る。プレイヤーに「ショット」ステートを作る。最後に「敵」を作る、というところを目指していきましょう。

そして、「敵」を倒す、ということはダメージを与える「攻撃」の処理を作ることになりますが、「ACTION GAME MAKER」では、攻撃や被ダメージの処理を専用に用意しています。そこで、実際に制作に入る前に、このシステムについて学びましょう。

「ACTION GAME MAKER」の「攻撃」と「被ダメージ」

攻撃の命中

プレイヤーオブジェクトにHitArea2D/HitCollisionとAttackArea2D/AttackCollisionというものがあったのを覚えているでしょうか。

「ACTION GAME MAKER」では、AttackArea2DのAttackCollisionが、HitArea2DのHitCollisionにぶつかった際にダメージの処理を行うようになっています。

さらに、Godotの機能であるCollisionLayerとCollisionMaskという機能で「あたる」「あたらない」という機能を調整できます。

CollisionLayerとCollisionMask

前のパートの「壁判定」でも説明を行いましたが、Godotでは、衝突をCollisionLayerとCollisionMask機能で制御することができます。これは、レイヤーという名の通り、衝突判定に奥行きをもたせるものです。

以下のような設定パネルで、レイヤーとマスクを設定します。

レイヤーは、どこにあるか、マスクは、どのレイヤーにぶつかりたいか、ということで理解するのがわかりやすいかと思います。

例えば、Maskが1と2のAttackCollisionは、レイヤーが3しかないHitCollisionに命中することはできません。これを使って、自分自身の攻撃判定にあたる、といった自体を回避することができます。

ダメージの処理

攻撃が命中すると、ダメージの処理が自動で行われます、共にBaseSettingで設定できる、攻撃側オブジェクトの攻撃力分のダメージを、防御側オブジェクトのHPから差し引きます。

その後、同じくBaseSettingsで設定できる、「無敵」を設定することで、一定時間ダメージを受けない状態にすることができます。

「弾」オブジェクトを作ろう

基礎的な攻撃処理の説明が終わったところで、実際に弾をつくっていきましょう。

「弾」用のオブジェクトもゲームオブジェクトになりますので基本的な作り方はプレイヤーと同じです。画像を設定して、移動速度などを調整して、ヴィジュアルスクリプトで処理を作ります。

一点異なるのは、コントローラーで操作するオブジェクトではないということです。そのため、移動の処理が必要になりますが、発射される「弾」の場合は「弾を発射」アクションで移動を付与することができるので、「弾」側で移動処理を作る必要はありません。

では、オブジェクトを作って設定していきましょう。

「弾」用ゲームオブジェクトの作成

1. 新規シーンタブを開き、ルートノードを生成で「ゲームオブジェクト」を選択します。

2. 「新しいオブジェクトを作成」ウィンドウでオブジェクト名:bullet、テンプレートを使用:弾、タイプ(型)bullet_baseと設定しましょう。

3. 弾用オブジェクトテンプレートが読み込まれるので、[未保存(*)]を右クリックして保存しておきましょう。名前はそのまま、bullet.tscnとして保存します。

「弾」の画像設定とアニメーション設定

「弾」に画像をつけましょう、「アニメーション」を設定してよりカッコイイ弾を作ることもできますが、今回はシンプルにアニメーションはしない弾として作りましょう。なので、画像をSprite2Dのテクスチャとして設定するだけで大丈夫です。

1. 弾の画像は以下の画像を右クリックでダウンロードしてください。

bullet

2. ダウンロードしたbullet.pngをPCからファイルシステムにドラッグ&ドロップで読み込みます。

3. シーンウィンドウでSprite2Dを選択してテクスチャの<空>にbullet.pngをドラッグ&ドロップしましょう。

「弾」のMoveAndJumpSettingsを調整しよう。

移動速度をプレイヤーより早くしたいので変更しましょう、プレイヤーの速度は300なので、600にしましょう。

1. シーンウィンドウでMoveAndJumpSettingsノードを選択します。

2. インスペクターのプロパティで左右の移動量、上下の移動量を共に600にしましょう。

「弾」の攻撃判定を調整しよう。

「AttackArea2D」でコリジョンレイヤーとマスクを設定しよう。

初期状態では、このオブジェクトのレイヤーは1で、マスクは1,2です。つまり、レイヤー1,2のオブジェクトに命中してしまいますが・・・実はプレイヤーもレイヤーが1でマスクが1,2になっています。このままでは弾を発射した瞬間プレイヤーにぶつかってしまうので、当たらないようにレイヤー3,マスク3にしましょう。

1. シーンウィンドウで「AttackArea2D」を選択します。

2. インスペクターウィンドウのプロパティで、「コリジョン」をクリックして展開しましょう。

3. コリジョンレイヤー/マスクを選択するパネルが出現するので、レイヤーを1から3へ、マスクを1,2から3のみへ変更しましょう。これでプレイヤーに攻撃が命中しなくなります。

「AttackCollision」の大きさを調整しよう。

現在、攻撃判定が弾のサイズよりとても大きい状態なので小さくしましょう。

1. シーンウィンドウでAttackCollisionを選択します。

2. エディター画面でAttackCollisionの四方の点をドラッグして弾より一回り大きいくらいに調整しましょう。

「弾」のスクリプトを設定しよう。

壁判定(CollisionShape2D)はちょうどよいサイズなので変更する必要はなさそうです。基本の設定が終わったのでスクリプトを作りましょう。

「移動」中に「敵にあたる」「タイルにあたる」「カメラの外にでる」と消滅するということが実現できればよさそうです。つまり、必要なステートは「移動」と「消滅」の2つだけです。早速つくっていきましょう。

スクリプトのアタッチ

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

2. シーンウィンドウ右上の:scroll:+(スクリプトをアタッチ)ボタンをクリックします。

3. 特に変更はなく作成を押し、bullet.vsを作成します。

ステートの設定「移動」

デフォルトのステート001を再利用して「移動」ステートを作ります。先述の通り、移動の処理は「弾を発射する側」で行うためアクションの設定は特にいりません。

1. ステート001を選択します。

2. インスペクターウィンドウでタイトルを「移動」に変更します。

「消滅」ステートを作る。

1. 移動の右側で右クリックを行い「ステートを追加」します。

2. 新たにできた「ステート001」を選択しインスペクターでタイトルを「消滅」にします。

3. 引き続きインスペクターで「+実行アクションを追加」をクリックします。

4. 実行アクション「自身を消滅させる」を選択し、「追加」します。

5. これでこのステートになるとこの弾が消滅するようになりました。

「移動」から「消滅」のリンクをつくる

「移動」中に敵にあたるか、タイルにあたるか、カメラの外にでると「消滅」するようにしましょう。この場合、条件は「3つ」もあることになりますが、「AND(かつ)」と「OR(または)」で3つをつなぐことで1つのリンクで複数の条件を扱うことができます。

この場合は、「敵にあたる」「OR(または)」「タイルにあたる」「OR(または)」「カメラの外にでる」とつなぐことで3つの条件を扱うことができます。

1. 「移動」ステートを右クリックしてリンクを追加します。

2. 「消滅」ステートをクリックしてリンクをつなぎます。

3. 作成されたリンクを選択し、インスペクターで「+その他条件の追加」します。

4. 「オブジェクトのあたり判定と接触」を選択します。

5. すべての方向をチェックし、「追加」ボタンを押しましょう。

6. 再度、「+その他条件の追加」をクリックします。

7. 次は「タイルと接触」条件を選択します。

8. 再び、すべての方向をチェックし、前の条件との論理条件を「OR」として「追加」ボタンを押します。

9. 3つ目の条件を「+その他条件の追加」で追加します。

10. 条件をスクロールして、その他にある「カメラの範囲外になった」を選択します。

11. データタイプ(判定対象オブジェクト)を「自分自身」前の条件との論理条件を「OR」にして追加します。

12. その他の条件が以下のようになっているか確認してください。AND/ORが違っている場合は、AND/ORのアイコンをクリックすることで変更することができます。

補足:オブジェクトのあたり判定との接触は「AND」で良いのか?

AND/ORは**「前の」**条件との論理条件との名前の通り、一段上の条件に対して判定されます。「オブジェクトのあたり判定との接触」は一番上にあり、前の条件がないためANDでもORでもどちらでも大丈夫です。ただし、順番を入れ替え2段目以降にしてしまうとANDで動作してしまうため、ORにしておくと安心ではあります。

これで弾の設定は完了です。「シーンを保存」しておきましょう。

「プレイヤー」オブジェクトを改修して弾を打てるようにしよう

弾を打てるようにするためには、4つの手順が必要になります。

A. 弾を発射するアニメーションを作る

B. 弾設定「BulletsSettings」ノードを追加して設定する。

C. 弾の発射地点となる接続点「Connector」ノードを追加して設定する。

D. ヴィジュアルスクリプトで「弾を発射」するステートを作る。

では、早速発射アニメの追加からはじめましょう。

A. 弾を発射するアニメーションを作る

まず、弾を発射したいシチュエーションを考えましょう。ロックマン風ということで、「立ち止まっての発射」「歩きながらの発射」「ジャンプ中の発射」の3種類のステートが必要になりそうです。それぞれのアニメーションが必要になります・・・が、実は既に作成済みの「移動」アニメーションはそのまま射撃ができるように、手をかざしながら走るアニメーションになっておりそのまま使うことがでます。

なので、「地上発射」「空中発射」の2つのアニメーションを作りましょう。

作り方は前パートと全く同じです。読み込み済みのスプライトシートに発射動作に適したものがあるのでそちらを使いましょう。

アニメーションの作り方は「アニメを追加」「キーフレームを挿入」「アニメーションセットに読み込み」の手順です。

「地上発射」「空中発射」アニメーションの作成

  1. シーンタブをplayer、エディター画面を2Dに変更します。
  2. AnimationPlayerノードを選択します。
  3. 下部アニメーションウィンドウの「アニメーション」をクリックして新規アニメーションを作ります。
  4. アニメーション名は「地上発射」としましょう。
  5. Sprite2Dを選択し、インスペクターの「アニメーション」プロパティを展開します。
  6. フレームを1(左手を前方にかざしている画像)にして、「:key:+」(キーフレームを追加)ボタンを押しましょう。
  7. RESETトラックを作成のチェックを外して作成します。
  8. 2.~3.の手順を繰り返し、「空中発射」アニメを作ります。
  9. Sprite2Dのインスペクターで、フレームを2(空中で前方に手をかざしているアニメーション)にして「:key:+」(キーフレームを追加)ボタンを押してキーを挿入します。

アニメーションセットへの登録

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

2. インスペクターの「アニメーション一括読み込み」ボタンをクリックして読み込みましょう。

3. 地上発射、空中発射が追加されます。

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

1. シーンウィンドウ左上の「+」(子ノードを追加)ボタンをクリックします。

2. BulletsSettingsノードを選択し、「作成」します。

3. インスペクターウィンドウの弾の一覧の右側、Array[BulletData]をクリックして展開します。

4. 「+弾を追加」ボタンをクリックします。

5. <空>をクリックして新規BulletDataを選択します。

6. 作成されたBulletDataをクリックして展開します。

7. 基本設定を展開し、「弾オブジェクトを指定」の右側にある:page_with_curl:アイコンをクリックし、先程のbullet.tscnを選択します。

8. 基本設定の制限無しを「オン」にします。これは、シーン内に表示できる弾の数を無制限にするオプションです。

9. 「弾の飛び方(初期動作)」を展開します。

10. 「弾の飛び方(初期動作)」を「発射元オブジェクトの表示方向に飛ぶ」と設定します。

11. これで、「bullet.tscn」を「画面内に何個でも」「発射元オブジェクトの表示方向に飛ばす」ことができるようになりました。

C: 接続点「Connector」ノードの追加と設定

接続点とは、弾の発射元やオブジェクトの生成場所など、ヴィジュアルスクリプトで「場所」を指示するときに使うノードです。この接続点は発射地点なので、発射アニメでかざした手の先に接続点を設定します。

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

2. 左上の「+」(子ノードを追加)ボタンで「Nodeを新規作成」画面を開きます。

3. Connectorノードを選択して「作成」します

4. AnimationPlayerノードを選択し、アニメーションを「地上発射」に切り替えましょう。

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

6. エディターのツールを「移動モード」に切り替えます。

7. 接続点の✛を手のひらの先に動かしましょう。これで接続点の設定は完了です。

D. 弾を発射するステートを追加しよう。

続いて弾を発射するステートを追加します。「地上発射」「移動発射」と「空中発射」の2つのステートが必要なのはもちろんですが、「空中発射」には工夫が必要そうです。

「地上発射」や「移動発射」からはそれぞれ「待機」、「移動」に遷移でもどれば良いのですが、「空中発射」を「ジャンプ」に遷移で戻してしまうと、再びジャンプしてしまうため、発射する度にジャンプで登ってしまいます。

そのため、ジャンプ以外の空中ステートが必要になります。今回は「ジャンプ」ステートを、「ジャンプ」と「空中」の2つに分けるようにしましょう。「ジャンプ」からは即座に「空中」に遷移し、「空中」中に「タイルに触れたら」「待機」に遷移するようにすればよさそうです。

そして、「空中発射」からは「空中」に戻るようにすれば問題が起きないでしょう。

では早速作っていきます。

「地上発射」「移動発射」ステートを作ろう

1. 「待機」の左方あたりに新しいステートをつくりましょう。

2. 作成した「ステート001」を「地上発射」にリネームします。

3. アニメーションカテゴリ名で「地上発射」アニメーションセットを指定します。

4. 「+実行アクションの追加」をクリックします。

5. 実行アクションとして、「弾を発射」を選択します。

6. 弾データで先程作成した「弾」を指定します。

7. 接続点の「割り当て」ボタンをクリックします。

8. 「ノードを選択」ウィンドウが出るので、先程作成したConnectorを指定します。

9. 弾データ「弾」接続点「Connector」が正しく指定されていることを確認したら「追加」しましょう。

10. 続いては「移動発射」ですが、「移動発射」はアニメーション以外「地上発射」と全く同じステートです、コピーして再利用しましょう。「地上発射」ステートを右クリックして「コピー」します。

11. 「移動」ステートの右側あたりを右クリックして、「ステートをペースト」を選択します。

12. 「地上発射(1)」というステートができるのでインスペクターで「移動発射」にリネームします。

13. 「遷移前のアニメーションを維持」のチェックボックスを有効にしましょう。「移動射撃」のアニメーションは、遷移元である「移動」と全く同一のものなので変更をする必要がありません、こういったケースではこのオプションが利用できます。

「待機」と「地上発射」、「移動」と「移動発射」ステートをつなごう

「待機」「移動」から「攻撃」ボタンが押されたら「地上発射」「移動発射」に遷移し、「待機」「移動」に戻るようにすれば動作しそうです。連射しすぎてしまうのも問題なので、「0.3秒」経過すれば戻る、とすれば程よく動作できるでしょう。

1. 「待機」ステートを右クリックしてリンクを作成し、「地上発射」ステートにつなぎます。

2. プロパティで「以下の入力がされた」のチェックをオンにしましょう。

3. 入力操作リストの右欄「Array[InputCondition…]をクリックして展開します。

4. 「+入力を追加」をクリックして入力欄を追加します。

5. <空>をクリックして「新規 入力に関する条件」を追加しましょう。

6. 「入力に関する条件」をクリックして展開します。

7. 「入力キー」を「攻撃」に変更しましょう。

8. 作成したリンクを右クリックで「コピー」します。

9. 「移動」ステートを右クリックして「リンクをペースト」しましょう。

10. 「移動発射」ステートにリンクをつなぎます。これで、「待機」、「移動」からのリンクができました、次は戻るリンクです。

11. 「地上発射」ステートを右クリックして「リンクを追加」し、「待機」ステートにつなぎます。

12. インスペクターで「+その他条件の追加」ボタンをクリックします。

13. その他欄にある、「一定時間が経過」条件を選択します。

14. 「数値」項目の秒数を1秒から0.3秒に変更しましょう。

15. 追加が完了したら、リンクを右クリックして「コピー」します。

16. 「移動発射」ステートを右クリックして「リンクをペースト」して「移動」につなぎます。以下のようになっていれば地上での発射ステートは完成です。

正しく弾が地上で発射できるか試してみよう

ここまで「弾」オブジェクトの作成、「BulletSettings」の設定、「地上発射」「移動発射」スクリプトの作成と3段階の設定を行いましたが、ここでようやく弾の発射がテストできるようになりました、一度テストプレイで試してみましょう。

1. エディター右上の「プロジェクトを実行(F5)」ボタンをクリックします。

2. うまく設定できていれば、「待機」「移動」の状態でXキーを押せば弾が発射されるはずですが、設定項目が多かったので設定もれがあるかもしれません。以下のリストで再チェックしてみましょう。

うまくいかないときのチェックリスト

アニメーションが再生されない:各発射ステートの設定を見直してみましょう。問題がない場合はAnimationPlayerのアニメーションも見直してみましょう。

アニメーションが再生されるが、弾がでない:「弾を発射」アクションの設定を見直してみましょう。

弾が出るが動かない、変な方向にいく:「BulletsSettings」を見直してみましょう。

問題がないことを確認できたら閉じるボタンでテストプレイを閉じましょう。

「ジャンプ」ステートを「ジャンプ」と「空中」ステートに分割。

それでは、「ジャンプ」ステートを分割しましょう。

1. 「ジャンプ」の左のあたりに「ステートを追加」します。

2. ステート001から「空中」にリネームしましょう。

3. アニメーションカテゴリ名を「ジャンプ」にして「空中」ステートは完成です。

4. 続けてリンクをつなぎます、「ジャンプ」ステートを右クリックして「リンクを追加」し、「空中」につなぎましょう。

5. インスペクターで「ステートを切り替える条件」を「無条件」にします。「無条件」は、条件なく即座にステートを切り替える条件です。「ジャンプ」の動作は即座に行われますし、「ジャンプ」のアニメもフレームを切り替えるだけなのでこちらの条件で動作します。

6. 続いて、「ジャンプ」から「待機」に戻るリンクを「空中」から「待機」に戻るリンクに付け替えましょう、リンクを選択します。

7. 右クリックして「切り取り」を選択します。

8. 「空中」ステートを右クリックして「リンクをペースト」しましょう。

9. 待機に繋げば完成です。

10. 念の為テストプレイをしてジャンプから着地までの流れが正しく動作するかチェックしておきましょう。

「空中発射」ステートを作って「空中」とつなごう

「空中発射」ステート、およびリンクの条件は先程作った地上発射のものでアニメーションが異なるだけなので再利用しましょう。

1. 「地上発射」ステートを右クリックして「コピー」します。

2. 「空中」の左にペーストします。

3. インスペクターで「地上発射(1)」を「空中発射」にリネームします。

4. 「アニメーションカテゴリ」を「空中発射」に変更します。

5. 「待機」→「地上発射」のリンクをコピーします。

6. 「空中」を右クリックして「リンクをペースト」し、「空中発射」につなぎます。

7. 「地上発射」→「待機」のリンクをコピーします。

8. 「空中発射」を右クリックして「リンクをペースト」し、「空中」につなぎます。

9. これで完成です、再度テストプレイをして動作をチェックしましょう。Zキーを押してジャンプ中にXを押して弾が正常に発射されれば成功です。

「敵」オブジェクトをつくろう

続いて敵のオブジェクトを作りましょう。最もシンプルなタイプの敵、左右に移動するだけのものを作ることにします。作り方はキャラクターと同じ、シーンを作り、画像・アニメを作り、各ノードの設定を行い、スクリプトを作成します。

「enemy」用ゲームオブジェクトの作成

1. エディター画面を「Script」から「2D」に戻します。

2. 新しいシーンタブを作り、ルートノードを生成で「ゲームオブジェクト」を選択します。

3. オブジェクト名: enemy、テンプレートを使用:キャラクター、タイプ(型): 2DSprite Character Base、オブジェクトグループ: Enemy として作成します。

4. [未保存](*)を右クリックしてenemy.tscnとして保存しましょう。

「enemy」の画像設定とアニメーション設定

画像はこちらで用意した以下画像を使いましょう。弾と同じく画像1枚だけのシンプルなキャラクターです。正円で反転する必要のなかった弾と違い、この敵は左右非対称で移動方向に応じて反転する必要があります。自動反転機能はアニメーションセットの機能を使っているので、プレイヤーと同じくSprite2Dでテクスチャを設定し、AnimationPlayerでアニメーションを作り、enemyノード(GameObject)でアニメーションセットを作りましょう。

Sprite2Dの設定

enemy

1. 上記画像を右クリックしてPCに保存してください。

2. ファイルシステムにドラッグ&ドロップで読み込みます。

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

4. インスペクターのテクスチャプロパティにenemy.pngをドラッグ&ドロップで設定しましょう。この画像はフレームを分割する必要はないので画像設定はこれで完了です。

CollisionShape2Dで壁判定のサイズを調整しよう

現状の壁判定のサイズは設定したスプライトよりかなり小さいようなので拡大しましょう。

1. シーンウィンドウでCollisionShape2Dを選択します。

2. 壁判定の四隅のオレンジ丸をドラッグして良いサイズに調整しましょう。

AnimationPlayerの設定とアニメーションセットの作成

アニメーションセットを設定するためにアニメーションを作りますが、プレイヤーと違いフレームを切り替える必要はないためアニメーションを作成するだけで大丈夫です。

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

2. 中央下部ウィンドウの「アニメーション」をクリックして「新規」を選択します。

3. 新しいアニメーション名として「移動」を入力して作成します。トラックには何も入力をする必要がないためアニメーションはこれで完成です。続いてアニメーションセットを作ります。

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

5. インスペクターの「AnimationPlayerを指定」をクリックします。

6. AnimationPlayerが正しく指定されていることを確認し、OKボタンをおします。

7. インスペクターの「アニメーション一括読み込み」ボタンを押します。

8. アニメーションセットを展開し、「移動」が正しく設定されていることを確認しましょう。

「enemy」の「BaseSettings」を調整しよう

敵はきちんと攻撃で倒されるようにしないといけませんので、体力や無敵時間を設定しましょう。

「体力」の設定

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

2. インスペクターの「体力」「最大体力」を1から3に変更しましょう。これで3のダメージを受けるとHPが0になるようになります。

「無敵」の設定

「無敵」とは、ダメージを受けたときに一定時間HPが減らないようにする設定です。これを設定しない場合、攻撃があたった瞬間、連続でダメージを受けてしまう危険があります。

プレイヤーの弾の発射間隔は0.3秒に設定していますので、0.2秒ほどの無敵時間であれば問題ないでしょう。無敵時間を0.4秒にすると2連射した弾の2発目があたらなくなってしまいますし、0.3秒ぴったりだと敵が移動して近づいているシーンなどで2発目があたらない可能性があります。

また、無敵機能には、無敵中にオブジェクトを点滅させて無敵時間を教える機能があります。無敵時間が0.2秒なので、0.1秒間隔で点滅するようにすれば点滅が見えるでしょう。

1. インスペクターで「無敵時間(秒)」プロパティを1秒から0.2秒に変更しましょう。

2. そのすぐ下にある「点滅間隔(秒)」プロパティを1秒から0.1秒に変更しましょう。

「enemy」の「あたり判定」を調整しよう。

続いて、「enemy」の「あたり判定」を設定しましょう。「弾」オブジェクトのコリジョンレイヤーを「3」に変更しているため、レイヤー「3」にあたるようにする必要があります。

「HitArea2D」でコリジョンレイヤーとマスクを設定しよう。

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

2. インスペクターの「コリジョン」欄を展開します。

3. レイヤーを3、マスクを3に変更しましょう。これで、「弾」の「攻撃判定」と相互に接触できるようになります。

「HitCollision」の大きさを調整しよう。

現状のHitCollisionは大きすぎるようなので少し小さくしましょう。

1. シーンウィンドウでHitCollisionを選択します。

2. 壁判定の四隅のオレンジ丸をドラッグして壁判定より一回り大きなサイズに調整しましょう。

「enemy」の「攻撃判定」を調整しよう。

続いて「攻撃判定」ですが、攻撃判定はプレイヤーにあたるようになっていれば大丈夫です。弾と異なりプレイヤーのコリジョンレイヤーはデフォルトのままなのでこちらも変更の必要はありません。Collisionのサイズだけ調整しておきましょう。

1. シーンウィンドウでAttackCollisionを選択します。

2. 壁判定の四隅のオレンジ丸をドラッグして当たり判定と同等のサイズに調整しましょう。

「enemy」のスクリプトを設定しよう。

「enemy」は左右に動くだけなので、左右に動くことと、HPが0になったときにやられることができれば大丈夫です。単純に考えれば「左に移動」「右に移動」「消滅」の3つのステートがあればよいのですが、今回は単純な移動を自動で設定できる「テンプレート移動」というアクションが使えます。

なので、「テンプレート移動」「消滅」の2つのステートを作り、HPが0になったら消滅する、というリンクを設定しましょう。

ヴィジュアルスクリプトのアタッチ

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

2. スクリプトをアタッチボタンでスクリプトをアタッチします。

3. 名称はそのままenemy.vsで作成を押しましょう。

「テンプレート移動」「消滅」のステート制作

1. ステート001を「テンプレート移動」にリネームします。

2. インスペクターでアニメーションカテゴリを「移動」に設定します。

3. 「+実行アクションを追加」ボタンをクリックします。

4. 「テンプレート移動の設定」を選択します。

5. 「移動時間」を3、「段差から落ちない」をオンに設定します。これで3秒移動するか、落下するような段差があった場合に折り返すようになります。

6. 「追加」を押します。

7. 続いて、「テンプレート移動」ステートの右側の空間を右クリックし、「ステートを追加」します。

8. ステート001を「消滅」にリネームします。

9. 「+実行アクションを追加」ボタンをクリックします。

10. 「自身を消滅させる」を選択して追加しましょう。

11. 以下のようになっていればステートの設定が完了です。

「テンプレート移動」から「消滅」のリンクをつくろう

1. 「テンプレート移動」ステートを右クリックして「リンクを追加」し、「消滅」ステートにつなぎます。

2. インスペクターの「+その他条件の設定」ボタンをクリックします。

3. 「HPが0になった」を選択します。

4. 設定項目はそのまま(データタイプ:自分自身)で良いので追加します。

5. 以下のようになっていれば設定完了です。

「enemy」を「stage1」シーンに配置しよう。

それでは、enemyの設定ができたので、stage1に配置してテストプレイしましょう。Playerと同じレイヤーに配置します。

1. エディター画面をScriptから2Dに変更します。

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

3. シーンウィンドウでPlayerノードを選択します。

4. 選択したまま、ファイルシステムから「enemy.tscn」をプレイヤーの右側にドラッグ&ドロップします。

5. 配置できたらテストプレイをしてみましょう。

敵が3秒毎に左右に動き、弾を3回あてると消滅することが確認できれば成功です。

動かないときのチェックリスト

敵が左右に動かない時:「テンプレート移動」ステートを確認しましょう。

敵が折り返しても反転しない時:enemyノードのアニメーションセットと、「テンプレート移動」ステートのアニメーション指定を見直してみましょう。

敵が弾1発で消えてしまう時:enemyのbasesettingsの「体力」「最大体力」と「無敵」の設定を見直してみましょう。

弾があたらない時:enemyの「HitArea」のCollisionLayer/Mask、bulletの「AttackArea」のCollisionLayer/Maskを確認しましょう。

弾が消えない時:「bullet」の移動から消滅ステートへのリンクと、消滅ステートのアクションを確認してみましょう。

「プレイヤー」に被ダメージの処理を入れよう。

さて、これでこのパートの目的「プレイヤーがショットで敵を倒す」を達成することができましたが、敵の攻撃判定はあるのにプレイヤーは何のリアクションもしない状態です。

さらに、プレイヤーに攻撃判定があるので体当たりで敵を倒してしまいます。

プレイヤーの設定を調整し、ダメージを受けたらリアクションをするように設定してみましょう。「被ダメージ」のアニメーションを追加し、「無敵時間」「あたり判定」「攻撃判定」を調整、最後にヴィジュアルスクリプトを追加します。

「被ダメージ」アニメーションとアニメーションセットの追加

1. エディター画面を2Dに戻し、シーンタブをplayerに変更します。

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

3. 下部ウィンドウのアニメーションボタンより「新規」を選択します。

4. 「被ダメージ」と入力してOKを押しましょう。

5. 「Sprite2D」ノードを選択します。

6. 「被ダメージ」のフレームは上段の一番右端、つまりフレーム4に用意してあります。インスペクターのアニメーションプロパティのフレームを4にします。

7. フレームの横の:key:+(キーフレームを追加)ボタンをクリックします。

8. RESETトラックを作成のチェックを外して作成しましょう。

9. これでアニメーションはできたのでセットに追加します。Player(GameObject)ノードを選択します。

10. インスペクターの「アニメーション一括読み込み」ボタンを押します。

11. アニメーションが追加されていない・・・ように見えますが、2ページ目に追加されているはずです。アニメーション一括読み込みボタンの上にある<1/2>の>をクリックして2ページ目に切り替えましょう。

12. 「被ダメージ」があればOKです。

「BaseSettings」で無敵時間を調整しよう。

続いて無敵時間を設定しておきましょう。無敵時間はプレイヤーなので長めのほうがよいでしょう。無敵時間1秒、点滅間隔0.2秒としましょう。

また、無敵中に攻撃があたってリアクションをしてしまわないように、無敵中はあたり判定が消える設定を行いましょう。無敵中にHPは減りませんが、攻撃にあたった、という判定自体はされてしまうためです。

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

2. インスペクターの「点滅間隔(秒)」を1.0から0.2に変更します。

3. 点滅間隔(秒)の下にある「無効化するHit Collisionリスト」の「Array…」を展開して「+要素を追加」しましょう。

4. <空>をクリックして「新規DisableCollisonData」を設定します。

5. <空>が変化してDisableCollisionDataとなるのでクリックして展開します。

6. 「割り当て」ボタンを押します。

7. ノードを選択ウィンドウが立ち上がるので、HitCollisionを選択してOKをおしましょう。これでダメージを受けると1秒間当たり判定も無効になります。