Unityのラグドールを使って敵が制御を失って倒れる様子を作成する

今回はUnityのラグドールを使って敵が倒れる時の制御を失ってバタッと倒れる状態を作成していきたいと思います。

文章だけでは分かり辛いと思いますが、ダークソウルで敵を倒した後に制御を失って吹っ飛び、主人公に引きずられるようになる状態です。

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

上のような感じで敵のHPが0以下になった時に敵がフニャフニャになって飛ばされます。

倒れるアニメーションを作成しているわけではなくラグドールで設定したRigidbody、Joint、コライダによって動きが作られています。

上のサンプルは遠距離武器ですが、近接武器の実行例は記事の最後に紹介したいと思います。

スポンサーリンク

今回の機能を作る流れ

今回の機能作成の流れとしては、

  • ヒエラルキー上に設置した敵のモデルにラグドールを設定しプレハブにし、ヒエラルキー上の敵を削除する。
  • 新たに敵のモデルをヒエラルキー上に配置し、通常の敵のスクリプト等を取り付ける。
  • メインカメラに攻撃スクリプトを取り付け、敵のHPが0以下になったら通常の敵を削除しラグドールを設定した敵のプレハブをインスタンス化する。
  • となります。

    敵にラグドールを設定しプレハブを作成する

    まずは敵にラグドールを設定していきます。

    アセットストアで検索窓にZombiと入力し、PricingでFree Assetsにチェックを入れ、PXLTIGERさんが作ったゾンビのモデルをインポートします。

    Assets→Zombie→ModelFBX→Zombieを選択し、インスペクタのRigでAnimation TypeをHumanoidにします。

    Zombieをヒエラルキー上にドラッグ&ドロップして配置します。

    ヒエラルキー上で右クリック→3D Object→Ragdoll…を選択します(敵のモデルは選択しなくて大丈夫です)。

    ラグドールの作成

    Create Ragdollウインドウが開きます。

    ラグドールのウインドウ

    Create Ragdollウインドウの設定に、ヒエラルキー上のZombieのボーンをドラッグ&ドロップして設定します。

    Zombiのボーンをラグドールウインドウで設定

    その他のTotal Mass(全体の質量)、Strength(強さ)、Flip Forward(向きの反転)等は適宜変更してください。

    今回は変更しません。

    Createボタンを押すと敵の設定したボーンにRigidbodyやJoint、コライダが設定されるのがわかります。

    敵モデルにラグドールが設定された

    ZombieゲームオブジェクトのインスペクタのAdd ComponentからCharacterControllerを取り付けコライダのサイズを調整します。

    Animatorコンポーネントの歯車をクリックしRemove Componentを選択しAnimatorコンポーネントを削除します(Animatorが作用しているとラグドールが作用しない為)。

    また名前をZombieからZombiePrefabと変更しておきます。

    これでラグドールを設定した敵が出来たのでAssetsフォルダ内にドラッグ&ドロップしてプレハブにし、ヒエラルキー上の敵は削除します。

    通常の敵キャラクターの作成

    次は通常の歩いたり攻撃をしてきたりする敵キャラクターの作成をします。

    今回はただ攻撃を受ける敵キャラクターにし、移動や攻撃の機能は取り付けません。

    Assets→Zombie→ModelFBX→Zombieをヒエラルキー上にドラッグ&ドロップをします。

    ZombieのインスペクタのLayerにEnemyを設定します(Enemyレイヤーがない場合は作成してください)。

    Enemyレイヤーに変更する時にウインドウが出るので、No, this object onlyボタンを押し子要素のレイヤーは変更しないようにします。

    インスペクタのAdd ComponentからCharacterControllerを取り付け、コライダのサイズをゾンビのモデルの大きさと合うように調整します。

    新しくEnemyスクリプトを作成し取り付けます。

    enemyPrefabにはインスペクタで先ほど作ったラグドールを設定した敵のプレハブを設定します。

    damageDirectionはダメージを受けた時の方向を入れます。

    powerToMoveは敵のラグドールを飛ばす方向に加える力を指定します。

    timeToDeleteEnemyはラグドールの敵をインスタンス化してから削除するまでの時間を設定します。

    TakeDamageメソッドでは受けたダメージと方向を引数として受け取ります。

    自身が保持するhpを減らしてhpが0以下になったらダメージを受けた方向を保持し、自身のゲームオブジェクトを削除します。

    インスタンス化したラグドールの敵のCharacterControllerのMoveメソッドを使って攻撃を受けた方向に力を加えて動かします。

    その後一定時間が経過したらラグドールの敵も削除します。

    TakeDamageメソッドはメインカメラに取り付けるスクリプトから呼び出すことにします。

    メインカメラに敵攻撃スクリプトを取り付ける

    Main Cameraに新しくAttackスクリプトを取り付けます。

    rayDistanceはレイの距離を指定します。

    Input.GetMouseButtonDown(0)でマウスの左ボタンが押されたかどうかを判定します。

    Camera.main.ScreenPointToRay(Input.mousePosition)でメインカメラからマウスの位置にレイを飛ばしその情報をrayに保持します。

    Physics.Raycastでrayの情報を元にEnemyレイヤーが設定されたゲームオブジェクトと接触したかどうかを調べ、接触した情報をhitに保持します。

    接触した相手のEnemyスクリプトを取得し、GetHpメソッドでhpが0よりあるかどうかを調べて、hpがある場合はEnemyスクリプトのTakeDamageメソッドを呼び出し敵にダメージを与えます。

    ダメージ量に1を渡し、ダメージ方向にray.directionでカメラから敵に飛ばしたレイの方向の正規化された値を渡しています。

    渡す引数の前にdamage:やdirection:という記述がありますが、これはEnemyスクリプトのTakeDamageの引数で割り当てられている名前を指定して、TakeDamageメソッドを呼び出す時にどんな引数を渡しているのかを分かりやすくしているだけです。

    行っていることは以下と同じです。

    これで機能が完成しました!

    近接武器に対応する

    ここまでで機能は出来ましたが、レイを使っての銃器を想定した遠距離武器での対応でした。

    しかし近接武器でも同じような感じで対応出来ます。

    以前作成した剣を持たせて敵を攻撃する記事で剣に敵との接触判定をするスクリプトを作りました。

    Unityで主人公キャラが剣を振って敵キャラを攻撃出来るようにする機能を作成します

    そこで剣に取り付けたスクリプトでEnemyレイヤーが設定されている敵と剣が接触した時に敵のEnemyスクリプトのTakeDamageメソッドを呼び出します。

    ダメージの方向はtransform.root.forwardで主人公の一番階層が上のZombieのゲームオブジェクトの前方を渡していますが、剣が接触した時の剣先の方向を与えるとそちらの方に敵を飛ばす事も出来ます。

    近接攻撃を試すと

    上のようになりました。

    敵のPowerToMoveの値を0.01に設定して試しました。

    終わりに

    ラグドールを使用するとリアルな敵が倒れる様子を作成する事が出来ますね。

    手動でRigidbody、Joint、コライダをキャラクターのボーンに取り付ける事でも同じような機能を作成できますが、ラグドールを使用すると該当する場所にボーンを設定するだけで勝手にそれらを作成してくれるので便利ですね。

    今回は移動や攻撃をする敵キャラクターとラグドールを設定したキャラクターを別に作りましたが、移動や攻撃をする敵キャラクターにラグドールを設定しておき敵が倒れる時だけAnimatorコンポーネントを無効化する事でも同じような機能が作れます。

    ただこの場合は敵を飛ばす方向にうまく飛ばせなかったのでやめました。

    敵が倒れる時にラグドールの機能を使って倒し、その後再び起き上がってくる機能も移動キャラとラグドールを一緒にしておけば実現が可能かもしれません。

    ラグドール用のRigidbody、Joint、コライダ等は無効化したり有効化したりといった事が必要になるかもしれませんが・・・・(´Д`)

    スポンサーリンク

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

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