第4回:HPのある敵をロジックで作る

第4回では、これまでただの的だった部分をちゃんとした敵に変えます! 
ボタンを押すとタコのような敵が出て、弾が当たるたびにパーティクルが出るなど反応するようにします。また、3回弾を当てると倒せるようにします。そしてこれを作るため、ロジックを本格的に説明していきます。

サンプルプロジェクト

今回の作例は「cue_04」です。ロジックも本格的に登場し、複雑なので一度で上手くいかない人も多いと思います。サンプルプロジェクトを見て、しっかりチェックしてください!

敵を作る。とりあえず基本の設定から

CUE_Assets/Prefabs/Enemysから8LegEnemyを配置しましょう。場所は床の上なら適当で構いません。このPrefabは、EmptyObjectの子に見た目部分……という構造に最初からなっていて、見た目のところにはコライダーもついています。

まず【8LegEnemy】の名前を【8LegEnemyPrefab】としてUnpack Prefab。子に【ParticlePos】というEmptyObjectを付けます。【ParticlePos】は敵の顔辺りが良いですね。

その上で、上の画像のような形を作っていくことを目指します。だいぶ難しくなりましたが、1つずつチェックしていきましょう!

敵の中身の解説(敵が出た時とロジック)

さて、どのようにしてこの敵の反応は作られているのでしょうか。

まずOn Create Item Trigger。この敵がワールドに出てきたときのトリガーですね。 
ここでは「HP」というKeyで数字の10というメッセージを送っている。こう書くと分かりづらいですが、要するにC#で言えば

int HP = 10;

ってことです。

CCKでは何かギミックなどを発動させたいときは「メッセージ」を送るんでしたね。そしてこの「メッセージ」は、受けとるギミックやロジックがなくても「保存」され、後で計算や条件チェックに使うことができるのです。

なのでC#などプログラミング言語の「変数」のように使えるわけですね!

そしてItem Logic。「Hit」というKeyで発動するようになっています。

テンプレートワールドに入っているHandGunBulletは、On Collide Item Triggerによってぶつかった相手に「Hit」というSignalを送ります。つまりこのItem Logicは、【8LegEnemyPrefab】ではなく外部から送られるメッセージで発動しているわけですね(*1)。

(*1)CCKでは今のところ別のItemに何かのメッセージを送る手段は割と限られています。トリガーでSpecifiedItemを指定するか、On Collide Item TriggerでCollidedItemOrPlayerを指定するか。あるいは今回の連載では説明できなかったGlobal経由か、というところです。ただしGlobal経由ではSignalしか送れず、数字を送るようなことはできません……

ロジックの中身

そして、ここからいよいよロジックの本番です。ロジックは「計算」か「条件チェック」をするものだと思えばいいと思います。トリガーやギミックにはできないことですね!

2つのItem Logicが、このようなイメージでつながっています。

まず1つめのロジックでは「=GreaterThan」というのが出てきています。「より大きい」ということですね(*2)。

RoomState(変数)の「HP」をConstant(定数)の0と比べています。これまではロジックが出てきてもほぼConstant(定数、固定の数字)ばかり使っていましたが、今回はRoomState(変数)が頻繁に出ます!

今回の場合、「HP」が0より大きい(生きている)ときだけ、「HitExec」というSignalを送り、もう1つのItem Logicが発動します。
(敵を倒した後もダメージエフェクトなどが出ないようにするため、HPが0より大きいかどうかをチェックしているわけです)

2つめのロジック

続けて、「HitExec」で発動する2つめのItem Logic
RoomStateは変数、Constantは定数ということを改めて注意して見ていってください。

こちらはまず「=Subtract」というものが出てきています。これは要するに引き算です。HPをダメージの数だけ減らして、またHPに保存しているんですね。ちなみに「damage」の数字は、「Hit」と同じく当たった弾から送られてきています(*3)。

このとき左のほうのIntegerを間違えてもCCK側で処理してくれるので大問題にはならないんですが、右側のIntegerは間違えないようにしましょう!

ポイント
Signalを指定すると、HPにとんでもなく大きな数字が入ることになります……

HPは10あり、緑の弾で4のダメージを受けます

その次の「=LessThanOrEqual」は、HPが0以下になっているかのチェックです。さっきの「HP」を減らす処理では結果をIntegerにして保存していましたが、条件チェックのときは基本的にSignalを指定します。「HP」が0以下ならSignalを送って何かを発動させる……という感じで使うわけです。

改めてイメージを確認して下さい。

最後に、「OnDamaged」というSignalを送っています。ロジックから無条件でSignalを送りたいときは、Constant Bool ON」を使うんでしたね。

 ここまでをC#っぽく書くなら

if(HP > 0) {
 HitExec();
}
void HitExec() {
 HP = HP-damage; //またはHP -= damage;
 if(HP <= 0) {
  OnDead();
  }
  OnDamaged();
}

 という感じです。

(*2) Logicでできる計算・条件チェックの一覧はこちらにまとまっています。また個人的に一部をまとめた記事もこちらにあります。
(*3) HandGunBulletのOn Collide Item Triggerの中身を確認しておいてください。なお弾からOn Collide Item Trigger経由で送れる数字は、2022年4月現在だと固定の数値のみです……ダメージの値を変えたければ、弾自体を別Itemにするしかないということですね。

敵の中身の解説(ダメージと死亡の処理)

次は敵がダメージを受けた時と死亡した時の演出をつくっていきます。イメージはこんな感じです。

弾が当たると敵が反応します

まずKey「OnDamaged」関係から見ていきましょう。Create Item Gimmickの1つ目を発動させます。ダメージが当たるたび、RedParticleというパーティクルを【ParticlePos】という場所に生成しているんですね。

そしてもう1つ、HPが0以下になると「OnDead」というSignalが送られます。このSignalにはItem TimerCreate Item Gimmickの2番目が対応しますね。

Create Item Gimmickは、ダメージを受けたときと違うBlueExplosionParticleというパーティクルを出します。

Item Timerは0.25秒後に「Destroy」という名のSignalを送ります。「Destroy」はそのままDestroy Item Gimmickを発動させ、この敵をシーンから消滅させます。

敵のダメージアニメ部分

【8leg_enemy】という見た目のオブジェクトには、Set Animator Value Gimmickを付けます。 AnimatorのAnimation ControllerにはCUE_Assets/AnimationsにあるEnemyBlendShapeDamageConを設定。Set Animator Value Gimmickの設定は上の画像のようにしてください。

これにより、「OnDamaged」が【8LegEnemyPrefab】に送られると、Animatorに同名の「OnDamaged」というSignalを送るようになっています。

Animatorも見てみると、Parametersに「OnDamaged」というTriggerがありますね。
AnimatorではSignalではなくTriggerと言いますが、ほぼ同じものです)

これが発動するたび、EnemyDamagedAnimが再生され、敵が黒くなってビクビク震えます。終わるとまたEnemyBlendShapeAnimに戻ってくるわけです(*4)。

(*4) Animatorの詳しい説明は他の記事に譲りますが、Animatorという名前に反して相当色々なパラメータをいじれます。C#スクリプトが使えないCCKでは、Animatorを使いこなすのが上級者への道!?

敵を出すボタン

これで敵が完成しました! 【8LegEnemyPrefab】をプロジェクト内のどこかにPrefabとして保存してください。
最後に、この敵をワールドに出すボタンを作ります!

EmptyObjectを5つくらいワールドに配置します。床の上なら場所はどこでも構いません。Animatorを付け、CUE_Assets/AnimationsからRightLeftWaveConを付けてあげてください。

そして、CUE_Assets/Prefabs/InteractivesからRoundButtonを【CCK_Items】の子として配置。Unpack PrefabしてからCreate Item Gimmickを5つ付け、Keyは全部「OnPressed」。Item Templateにはさっき保存した8LegEnemyPrefabを指定。SpawnPointには5つのEmptyObjectをそれぞれ指定します!

RoundButtonの実装。力業ですね!

このボタンを押せば、5つの場所に敵が出現するようになります!

ただ、弾が届かないとこに出ちゃうこともあります。この問題を解決するため、次回は「乗り物に乗って弾を撃つ」形にしてみましょう!

第5回:乗り物から弾を撃つ

第5回では、clusterの「乗り物機能」について解説します。
乗り物機能を使って、弾が撃てる乗り物をつくっていきます。よりゲーム性が高まるテクニックが詰まっています。
ここまでで乗り物から弾を撃って敵を倒していくゲームワールドが完成します!