今回は少しニッチ&難しい話なのですが、「Final IK」というアセットを使ってUnityで一人称視点の腕(=FPS用の腕モデル)に武器を持たせる方法についてのメモです。
FPSなど一人称視点のゲームを作ってみたい方には参考になると思います。
前置き:わざわざIKを使って腕に武器を持たせたい理由
でははじめに、目的を書いただけだとなんでそんなことをしたいのか?という理由がわかりづらいのでその部分を説明しておきます。今回、FPSの腕にIK(=逆運動学)で武器を持たせようと思った経緯は次の通りです。
- FPSを作るにあたって、画面に銃などの武器を持った腕を表示させたかった。
- しかしアセットストアには武器を持った腕のアセットが少なく、あってもレビューを見ると「別の武器を持たせることができない」「腕の見た目を変えられない」などのレビューがあって使いづらそうな気がした。
- 一方で武器だけ・腕だけのバラ売りアセットは多いので、それらを組み合わせれば自由度の高い「FPSの腕」を作れそうだなと思った。
- ただ、そうするには腕に武器を持たせる必要がある。そこでIKを使って腕の座標を武器の取っ手に合わせることで、あたかも武器を持っているように見せる方法を試してみることにした。
…とまあこんな感じです。なんとなく理解していただけたでしょうか?
Final IKの「Arm IK」を活用して、腕に武器を持たせる
Final IKについて
さて、UnityでIKを扱うには「Final IK」というアセットが便利です。
ここでは詳しい説明は省きますが、非常に高性能なIKソルバーを手軽に導入・使用することができる便利アセットです。使い方さえわかれば実に様々な用途に使うことができ、3DゲームはもちろんVTuberにも使われていたりします。
Arm IKの使い方
それで今回はこのFinal IKの中に含まれる「Arm IK」という、その名の通り腕を動かすためのコンポーネントを使ってFPS用の腕を動かすことにしました。
使い方は簡単で、次の4つの作業を行うだけです。
- Chest~Handの欄に、腕モデルの対応するボーンを登録する
- Targetに腕が目指すターゲットを登録する
- もし左手ならIsLeftにチェックを入れる
- 実際にテストプレイして動作を確認する。Arm IKはターゲットのTransformの座標だけでなく回転も考慮するので、良い感じになるようにターゲットの座標・回転を調整する。
たったこれだけで使えるので非常に便利です。
実際に銃を持たせてみる
では実際に
- 腕モデル
- 銃モデル
を用意して腕に銃を持たせてみましょう。手順は次の通り。
- 銃のモデルを腕モデルの子にして、座標を適当に調整する。
- 銃モデルのグリップ部分に空のゲームオブジェクトを作り、右手のArm IKのターゲットとする。
- 銃のモデルの銃身部分に空のゲームオブジェクトを作り、左手のArm IKのターゲットとする。
- 腕モデルにArm IKコンポーネントを2つアタッチして、それぞれ右手・左手用の設定を行う。
- 実際にテストプレイしてターゲットの座標・回転を調整する。
作業結果(ゲーム実行中の様子)は次のようになりました。良い感じですね。
※もちろん、ゲームを実行していないときは腕は銃から離れています。
応用編:銃のリロードモーションを作る
次に、応用編として次のような銃のリロードモーションを作ってみましょう。
一見するとアニメーションが絡むので複雑そうに思えますが、IKを使えば大したことはありません。
リロードモーションを簡単に作るための考え方
まず、リロードモーションを作るためには左手をマガジンに持っていく必要があります。これをクソ真面目にアニメーションで処理しようとすると大変面倒ですが、今回はIKを使っているのでターゲットを変えればよいのです。
つまりやり方としては
- 銃やマガジンの動きはアニメーションクリップを作ってアニメーターで動かす。このとき、マガジンに左手のIK用のターゲットを仕込んでおく。
- リロードモーションが始まったら、左手IKのターゲットをマガジンのものに切り替える。終わったらターゲットをまた元のものに切り替える。
というような感じです。
C#スクリプトを書いて、アニメーションイベントからメソッドを呼び出す
となると、やるべき作業は次の3つになりますね。
- 銃とマガジンのアニメーションを作る
- IKのターゲットを切り替える簡単なC#スクリプトを書く
- アニメーターと同じゲームオブジェクトに2.のスクリプトをアタッチし、アニメーションイベントからスクリプトのメソッドを呼び出せるようにする。
手順1.と3.はここでは省略させていただきますが、2.のスクリプトだけ載せておきます。
using UnityEngine; using RootMotion.FinalIK; public class FpsLeftHandController : MonoBehaviour { [SerializeField] ArmIK armIK = null; [SerializeField] Transform normalLeftHandTarget = null; [SerializeField] Transform reloadLeftHandTarget = null; public void OnReloadStart() { armIK.solver.arm.target = reloadLeftHandTarget; } public void OnReloadEnd() { armIK.solver.arm.target = normalLeftHandTarget; } }
これで先ほどのようなリロードモーションを実現することができます。
おわりに
以上、かなりニッチな話になってしまいましたが「一人称視点の腕(=FPS用の腕モデル)に武器を持たせる方法」をご紹介しました。Final IKのおかげで今後自作ゲームに「FPSの腕」を導入できるようになって感無量です。これでFPS制作が捗りますね!
まあ果たして他の方の参考になるかどうかは分かりませんが、何か少しでも得るものがあれば幸いです。