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

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

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

スクリプトからRigidbodyを付けてもいいんですが、うまく出来ませんでした。

Rigidbody自体がIsKinematicにチェックが入っているとスクリプト上でしか操作出来ないのでダメなのかも

今回の機能を作成すると、

↑のような感じになります。

敵の抱きつき時のアニメーションは昔適当に作ったやつなので主人公キャラのサイズとも合ってません・・・・・(^_^;)

そこら辺もちゃんと作りこむとなかなか良くなるかもしれません。

スポンサーリンク

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

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

敵キャラクターの作成

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

他の敵キャラでも同じように設定すればいいのでどんなキャラでも人型なら大丈夫です。

敵キャラを動かすスクリプトの作成

敵にはAnimatorにHugEnemyというアニメーターコントローラーを作り設定し、敵キャラの動きはNavMeshAgentで動かします。

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

NavMeshAgentに関しては、

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

を参考にしてください。

HugEnemyスクリプトは以下のように作成しました。

敵が主人公に抱きついていない時は目的地を主人公に設定し追いかけさせます。

抱きついている時は敵キャラの位置を主人公の位置に補正値を加えて移動させます。

また主人公が動いている時は敵キャラの向きを主人公の向きに向けさせるようにします。

抱きつきタイム(謎)が終了したら敵の状態をフリーズ状態とし、すぐに主人公に抱きつかないようにします。

フリーズ状態で一定時間が経過したらノーマル状態へと遷移させています。

SetStateでHugEnemyState.Hug状態の時はアニメーションパラメータのHugをtrueにして抱きつき時のアニメーションへと遷移させます。

敵キャラ用のアニメータコントローラーの作成

次に敵キャラ用のアニメーターコントローラーHugEnemyを作成します。

主人公に抱きつく敵キャラのアニメーターコントローラー

アニメーションパラメータ-にFloatでSpeed、BoolでHugを作成します。

Idle→WalkをSpeedが0.1以上
Walk→IdleをSpeedが0.1以下
Idle→HugをHugがtrue
Walk→HugをHugがtrue

を設定します。

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

Walk→IdleのSettingsでInterruption SourceをNext Stateに設定し、歩き状態でHugがtrueになった時すぐにHug状態に遷移出来るようにします。

主人公キャラに抱きつく範囲の作成

次に敵のゲームオブジェクトの子要素に空のゲームオブジェクトを作成し、名前をHugAreaとし主人公に抱きつく範囲を作成します。

敵が主人公に抱きつく範囲を作成

↑のような階層ですね。

HugAreaにはSphereColliderを取り付けIs Triggerにチェックを入れ検知範囲を作ります。

HugAreaの設定

実際の抱きつく範囲は、

敵が主人公に抱きつく範囲の実際の画像

↑のようになりました。

HugAreaにはHugAreaスクリプトを作成し取り付けます。

敵自身の状態がフリーズ、抱きつき状態でない時に敵を抱きつき状態にし、主人公を抱きつかれた状態に設定します。

主人公キャラクターの作成

次に主人公キャラクターを作成します。

主人公キャラ操作スクリプトの作成

主人公キャラの操作スクリプトはHugCharaとしました。

キャラクターを動かす処理の部分ではノーマル状態か抱きつかれている状態かで歩くスピードを変化させています。

SetStateメソッドでは受け取った状態に主人公の状態を変化させますが、その時にAnimatorに設定しているアニメーターコントローラーのOverrideLayerというレイヤーのウエイトを変化させています。

OverrideLayerレイヤーはこの後作成しますが、ウエイトが1だと完全にOverrideLayerに設定したアニメーションを再生させます。

0だとベースとなるレイヤー(デフォルトで作成されるBase Layer)のアニメーションが再生されます。

この辺りは

Unityのゲームでキャラクターが元気な状態なのか、疲れている状態なのかでAnimatorの切り替えをしたい事があります。そんな時はAnimatorでSyncのレイヤーを作成し、スクリプトから疲れている状態のレイヤーのウエイトを操作し、Animatorの状態と遷移はそのままにアニメーションを変更する事が出来ます。

で詳しくやっておりますので、そちらを参照してみてください。

IsMoveメソッドは主人公キャラクターを動かしているかどうかを返すメソッドです。

主人公キャラのアニメーターコントローラーの作成

主人公キャラに設定するアニメーターコントローラーを作成します。

AnimatorタブのLayersで+を押し新しいレイヤーを作成して名前をOverrideLayerとします。

OverrideLayerの右の歯車を押し、

主人公キャラのアニメーターをオーバーライドする

↑のように設定します。

このレイヤーはウエイトが変更されるとSource Layerに設定したレイヤーを上書きします。

Syncにチェックを入れるとSource Layerとシンクロし、Source Layerに設定されているアニメーションの遷移条件等と同じものがOverride Layerに表示されます。

Override LayerのWalk状態に抱きつかれた状態の時の歩行アニメーションを設定します。

オーバーライドしたレイヤーのモーションを変更

Override Layerのウエイトが1になると完全にOverride LayerのWalk状態のモーションが再生されます。

これで敵キャラが主人公キャラにくっつく処理が完成しました。

Unityの実行ボタンを押して確認してみましょう。

タイト7

↑は改造前の抱きつき機能なのでアニメーションは変化していません。

簡易ではありますが、敵が主人公キャラクターにくっつくようになりました。

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

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます