Unityで敵キャラが主人公に近づいた時に攻撃をしてくる機能

前回までで主人公が敵キャラの検知エリアに入った時に追いかけてくるところまで作りました。

Unityで主人公キャラが近づいてきたら追いかける敵キャラを作る
Unityで主人公キャラクターが敵キャラクターに近づいたら敵が主人公に近づいてくるようにしたいと思います。

今回はさらに主人公との距離が縮まったら敵キャラが主人公を攻撃してくる機能を作ってみます。

まずは前回まで列挙型をMoveEnemyに設定していましたが、シーンを管理するオブジェクトScriptに新しいスクリプトManagementを作成し、
そこに宣言を移動させました(移動させなくても大丈夫です)。

それではAsset Storeでアニメーション用のデータをインポートしましょう。

3Dモデル→キャラクター→トゥーン→Cartoon Zombie

をインポートしました。キャラクターに付いているattackというアニメーションを使います。

スポンサーリンク

アニメーションクリップの設定をする

ゾンビのキャラクターを選択したらインスペクタ上でRigがHumanoidになるようにし、次にAnimationsをクリックします。

Attack用のアニメーションRigをHumanoidにする


atack01を選択したら赤く印をつけた場所にチェックを入れます。

アニメーションの動きによってオブジェクトに回転や移動を加えないようにし、スクリプトで制御する為です。

アニメーションのPoseにチェックを入れる

アニメーションイベントを作成する

次はアニメーションの再生位置でイベントを発生させるようにしてみます。

アニメーションイベントを追加する

上のようにEventの所をクリックし、下のマークをクリックします。

アニメーションイベントの設定をする

新しいウインドウが出てくるのでAttackStartとAttackEnd、StateEndというイベントを作り、赤でマークをした位置に移動させます。

これは攻撃判定開始時と判定終了時、攻撃状態の終了を設定する為にこの位置にしています。(微調整してください)
FloatやIntはそのイベント発生時に渡せる引数の値です。特に渡さない場合は変更しなくて大丈夫です。

これでこのアニメーションが再生され、イベントの個所にくるとAnimatorが設定されているオブジェクトにAttackStart、AttackEnd、StateEndというイベントが送られます。
このイベントを受け取るスクリプトはあとで作成します。
これでアニメーションの途中でイベントを投げる事が出来るようになりました。

敵キャラが攻撃をする為のスクリプトを作成

次は敵キャラが攻撃に遷移するスクリプト部分を作ります。

Managementスクリプトの状態にattackを追加しておきます。
状態がchaseの時に主人公と1.3mの距離内に入ったら攻撃するようにします。
距離の計算はVector3.Distanceで計算出来ます。

状態をattackにしアニメーターのパラメータAttackの値をOnにします。

アニメーターで攻撃の状態と遷移を作成

次にアニメーターの設定をしていきます。

まずはアニメーターのパラメータAttackをBooleanとして作成します。

アニメーションパラメータを作成する

新しいアニメーションのatack01をアニメーターウインドウ上にドラッグ&ドロップし、Walk、Idleを選択し右クリックしてatack01にMake Transitionします。

アニメーション遷移条件を設定する

ConditionsにAttackを追加し、WalkとIdleからatack01への遷移条件に『Attackがtrue』の時を入れます。

遷移のインスペクタでHas Exit Timeのチェックを外しておきます。
このチェックが入っていると条件がOnになっても元のアニメーションの再生が終わらないと次のアニメーションに行きません。

atack01からIdleへMake Transitionを繋げます。インスペクタ上のHas Exit Timeのチェックを外し、条件にAttackがfalseになった時を入れておきます。
攻撃が終了したら何もしていない状態に遷移させる為です。

敵キャラの攻撃の当たり判定部分(コライダ)を作る

アニメーターの設定が終わったので、次は敵キャラの攻撃の当たり判定部分を作成していきます。

プレハブを修正するので、一旦、敵キャラのプレハブをヒエラルキー上にドラッグ&ドロップし、修正します。

アニメーションイベントの受け取りスクリプトを取りつける

敵キャラ本体にProcessAttackスクリプトを新規で追加し、

右手に攻撃用のコライダを設定

↑のように敵キャラの右手の部分にSphereColliderを追加します。

SphereColliderはスクリプトでOn・Offするので最初はチェックを外しておきます。

敵キャラの攻撃スクリプトを追加する

AttackZombiという名前で新しいスクリプトをSphereColliderの設定してある右手の手の部分に設定します。

攻撃当たり判定コライダの大きさ

SphereColliderを上のような感じで設定し当たり部分を大きめに取ります。
この部分が主人公のCharacterControllerのコライダに当たったら攻撃が当たったという処理をします。

修正が終わったら敵キャラのインスペクタ上にあるPrefabのApplyボタンをクリックしプレハブに反映させておきます。

反映させたらヒエラルキー上の敵キャラはいらないのでチェックをはずすか削除しておきます。

アニメーションイベントを受け取り、当たり判定のオン・オフをするスクリプト

ProcessAttackスクリプトはアニメーションのイベントを受けとるスクリプトになります。

Start関数内でEnemyMoveスクリプトとSphereColliderを取得しています。

GetComponentInChildrenはこのスクリプトが設定されているオブジェクトの子要素のコンポーネントを取得する時に使います。
コンポーネントの取得に関しては

Unityのスクリプトでゲームオブジェクト、コンポーネントを取得する方法
Unityのスクリプトでゲームオブジェクト、コンポーネントを取得し変数に保存する方法

こちらで詳しく解説しています。

AttackStartとAttackEndはさきほど設定したアニメーションから送られてくるイベントを受け取りますので、AttackStartを受け取ったらコライダをOnにし、当たり判定を有効にします。

AttackEndを受け取ったら、コライダをOffにし、当たり判定を無効にします。
攻撃後(StateEnd)は待ち状態に設定します。

攻撃の当たり判定をするスクリプト

次はAttackZombiスクリプトです。

Playerタグを持つインスタンスに当たったらキャラクター操作スクリプトMoveのNockBack関数(ダメージ処理関数)を実行させます。

引数としてこのスクリプトが設定されているオブジェクトの親(敵キャラ)のTransform情報(位置情報)を渡しています。
つまり主人公キャラのMoveスクリプトのNockBack関数に敵キャラのTransform情報を渡すという事になります。

これで敵キャラの攻撃の処理が出来ました。
ただ、攻撃された主人公キャラ側の処理をまだ作っていないので、攻撃されても主人公は棒立ち状態のままです。

主人公側の攻撃を受けた時の処理スクリプト

それでは攻撃を受けた主人公の処理を追加します。
さきほど攻撃を受けた時にNockBack関数を実行する処理を記述したので、主人公側で攻撃を受けた時の処理を実行します。

主人公側でも今何をしている状態か?を記憶しておく変数stateを作ります。

NockBack関数が呼ばれたら、状態stateをダメージを受けている状態damageに変更し、主人公キャラのアニメーターのパラメータDamageトリガーをOnにします。

また攻撃を受けた際に敵の向いている方向に少しだけ主人公キャラを後退させます。

EndDamage関数はアニメーションでイベントを作るので、それを受け取る関数です。
主人公の場合はダメージを受けた直後はwalkに設定します。

キャラクター操作スクリプトを修正する

次にUpdate関数内を修正します。
ダメージを受けている時に方向キー等を押した場合、ダメージを受けながら移動してしまいますので、そうならない為の条件を加えます。

キャラクターの状態がダメージを受けている状態State.damageの時は移動処理を行わないように条件ではじいています。

アニメーターコントローラにダメージ状態と遷移を作成する

ダメージ状態と遷移を作成する

主人公キャラクターのアニメーターを作成します。

敵キャラのアニメーターとほぼ同じで、アニメーションパラメータにTrigger型のDamageのパラメータを作成し、
Damageアニメーションを作り、DamageトリガーがOnになったらDamageに遷移するように作ります。

DamageからIdleにMake TransitionしDamageのアニメーションが終了したらIdleに遷移するようにします。

最後にダメージアニメーションでイベントを発生させておきます。

DamageEndアニメーションイベントを追加する

アニメーションが終了した時にDamageEndイベントを発生させています。
ダメージアニメーションは

Asset Store→3D モデル→キャラクター→人型→ファンタジー→Mummy Warriors

をインポートし、そのキャラクターに設定されているアニメーションを使用します。
ダメージアニメーションはGetDamage_1_SwordShieldを使用しました。

終わりに

これで敵の攻撃と主人公が攻撃を受けた時の処理が出来ました。

当たり判定の大きさと主人公キャラとの距離の調整をすればそれなりに見えるんではないかと・・・・・。

今回の作業はいろいろな個所の設定が必要なので、慣れてない人はどれがどれだか解らないという状態になるかもしれません。

説明下手なもので、飛び飛びの解説になってしまいました・・・・。(;_;)

次回は攻撃されてばかりではストレスがたまるので主人公も攻撃を出来るようにしてみます。