Unityで敵が主人公に抱きつく機能を作る

今回は主人公キャラクターが敵に攻撃を受けた時に、敵に抱きつかれる機能を作りたいと思います。

Rigidbodyを使ってキャラクターを動かしている場合はJointの機能を使うと敵が主人公にくっつく機能が作れそうです。
ですがCharacterControllerを使っている場合、Rigidbodyを使っていないので、Joint機能が使えません。

スクリプトからRigidbodyを付けてもいいんですが、うまく出来ませんでした。
Rigidbody自体がIsKinematicにチェックが入っているとスクリプト上でしか操作出来ないのでダメなのかも

スポンサーリンク

自前のくっつき機能を作成

ということでJoint機能でくっつける機能を作るのをやめて、自前のくっつき機能を作ります。

まずは敵キャラを準備します。

タイト1


敵キャラのグールを用意します。他の敵キャラでも同じように設定すればいいのでどんなキャラでも人型なら大丈夫です。

タイト4

グールにはAnimatorにghoulAnimatorというアニメーターを作り設定、敵キャラの動きはNavMeshAgentで動かします。

敵キャラを動かすスクリプトJointMoveEnemy、敵キャラのアニメーションイベントの受け取りスクリプトJointProcessAttackを作り設定します。中身は後で作成していきます。

NavMeshAgentに関しては、

敵キャラをUnityのナビゲーション機能を使って移動させる
Unityのナビゲーション機能を使って敵キャラクターを移動させます。ナビゲーション機能はあらかじめBakeされたフィールドを移動出来る機能です。

を参考にしてください。

タイト2

右手の部分R_WristにJointAttackという名前のスクリプトを作り設定します。
この部分のコライダが主人公キャラクターと接触した時はくっつく処理をします。

右手の部分にSphere Collider等のColliderを設定し、この部分が主人公キャラクターと接触した時に主人公にくっつきます。
Is Triggerにチェックを入れスクリプト上で当たり判定としてだけ使います。

Sphere Colliderのチェックを外し、グールが攻撃中だけスクリプト上からOnにし、当たり判定を行います。

ここら辺の処理は

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

を参考にしてください。

タイト3

グールは上のような感じで、当たり判定部分が薄緑色の範囲になります。

次にghoulAnimatorを作成します。

タイト5

アニメーターパラメータにFloatでSpeed、BoolでAttack、BoolでJointを作成します。

Idle→WalkをSpeedが0.1以上
Walk→IdleをSpeedが0.1以下
Idle→Attack、Walk→AttackをAttackがtrueの時
Attack→IdleをAttackがfalseの時
Attack→JointAttackをJointがtrueの時
JointAttack→IdleをJointがfalseの時

に遷移するようにします。それぞれの遷移ではHas Exit Timeのチェックを外しておきます。

アニメーションクリップはidleが止まっているクリップ、Walkが歩いているクリップ、Attackが攻撃中のクリップ、Jointが主人公キャラにくっついている状態の時のクリップを設定します。
Jointに設定するクリップはLoop Timeにチェックを入れておいてください。Jointにいる間は繰り返し動作をさせる為です。

Attackの状態に設定しているアニメーションクリップにアニメーションイベントを設定します。
攻撃開始時はAttack、攻撃終了時にEndAttackというイベントを発生させます。
アニメーションイベントに関しては先ほど紹介したUnity:敵キャラをナビゲーションを使って移動させるを参考にしてください。

タイト6

アニメーションイベントは上のような位置に設定しました。(設定するアニメーションクリップによって位置は変わります)
左側がAttack、右側がEndAttackになります。

次に敵キャラを動かすスクリプトJointMoveEnemyを作成します。

敵キャラクターはNavMeshAgentを使って移動させるので、SetDestinationで主人公キャラクターの位置を設定し、そこに移動します。

今回の例で言えば、永遠に主人公キャラを追いかけていきます。

敵キャラが主人公キャラとくっついていない時は、敵キャラが主人公キャラと0.8m以内に近づいて、しかも前回攻撃してから1秒経っていたら攻撃します。
それ以外は主人公キャラクターのいる位置まで移動をします。

敵キャラが主人公キャラとくっついている時はくっついている時間制限がくるまで主人公キャラの位置の辺りに敵キャラを設定します。

くっついている時間を超えたら、jointをfalseにして、また主人公を追いかけます。

攻撃の間隔時間を設定したのは、くっつきから離れた瞬間に主人公が近くにいる為、また攻撃してくっつくという事が起きてしまう為です。主人公にとってみたらうざい事この上ないですね・・・・(+_+)

次に右手部分R_wristに設定したJointProcessAttackスクリプトを記述します。

JointProcessAttackはアニメーションイベントから送られるイベントを受け取るスクリプトです。
Attackを受け取ったらSphereColliderをOnにし、EndAttackを受け取ったらSphereColliderをOff、アニメーションパラメータのAttackをfalseにします。

最後にR_wristに設定したJointAttackを記述します。

JointAttackでは接触したコライダに設定されているタグがPlayer(主人公キャラに設定したタグ)だった時に主人公キャラクターに設定しているJointMoveEnemyを取得し、くっつき状態にさせます。

その後アニメーションパラメータのJointをtrueにした後、Attackをfalseにします。
逆にするとIdleに遷移してしまうので、順番を逆にしないでください。
最後に主人公キャラクターに攻撃が当たった時の処理をするNockBack関数を呼んでいます。

これで敵キャラが主人公キャラにくっつく処理が完成しました。
Unityの実行ボタンを押して確認してみましょう。

タイト7

簡易ではありますが、敵が主人公キャラクターにくっつくようになりました。
くっついている状態の時は主人公キャラが動けないようにしたり、敵キャラの手や足の位置をIKで調整して
主人公キャラクターにめり込まないようにする必要もありますねぇ・・・・。