読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

Unity上でMMDモデルを独自アニメーションで走らせる

Unity 3D MMD・モデルの扱い・モデリング アセット・ファイル管理 アニメーション ゲームの作り方・チュートリアル・サンプル 回転とか移動とか拡大縮小とか Unity

MMDモデルをRoot移動の無い、独自のモーションで走らせる方法についてです。この記事は以前に書いたUnity内でMMDモデルを自由に走らせる手軽な方法 の続き的な位置づけです。

f:id:tsubaki_t1:20150726044459g:plain

目次

MMDモデルおよびモーションの登録

MMDモデルとモーションを登録します。

基本的にはMMD4Mecanimを使用してMMDモデルにUnityで踊って頂いてみた。PMX2FBXを行う を参考にモデルを登録すればOKです。その際、VMDを登録したい場合はVMDにモーションを登録して使用します。

ちなみにUIが以前と比べてだいぶスッキリしているので、かなり分かりやすくなっています。基本的には、以下の操作を行えばOKです。

  1. MMD4Mecanimをインポート
  2. MMDモデルをProjectビューに突っ込む
  3. Projectビューに(モデル名)MMD4Mecanimが自動的に作成されるので、選択
  4. Inspectorビューで利用規約とか同梱されているReadMeを読んで同意

    f:id:tsubaki_t1:20150726045751p:plain

  5. Processを押す(だいぶUIがスッキリ)

    f:id:tsubaki_t1:20150726045228p:plain

Unityの他のモーション、たとえばユニティちゃんのモーションを使用したい場合は、作成されたFBXを選択後、InspectorでRigを選択し、AnimationTypeをHumanoidに設定します。モーション時に空気椅子のポーズをとる場合、だいたいこのあたりの設定です。

f:id:tsubaki_t1:20150726050020p:plain

本当はモーション側もVMDから持ってきて紹介しようと思いましたが、探すのが面倒になったのでモーションはAssetStoreから拝借します。

RootMotionとアニメーション

RootMotionがあるアニメーションならば、ApplyRootMotionでキャラクターの位置を動かす事が出来ます。アニメーションで動かすことが出来るので、「蹴りはじめは加速」のような緩急のあるモーションをデザイナーの力で設定出来て。

f:id:tsubaki_t1:20150726025410g:plain

f:id:tsubaki_t1:20150726025200g:plain

ただ、現状ゲームで一般的なのはRootMotionのないアニメーションで、その場でバタバタするタイプです。上がRootMotionが動くアニメーション、下が動かないアニメーションです。その場でバタバタ動いているのが確認出来ます。

RootMotionの無いモーションはApplyRootMotionで動かす事が出来ないので、スクリプトで動かします。

スクリプトでキャラクターの位置を動かす

スクリプトとAnimationでキャラクターの位置を動かす場合、OnAnimatorMoveコールバック内で動かすのがAnimator的には良いです。

この処理をコンポーネントに記述すると、AnimatorのApplyRootMotionが消えHandled by scriptと表示されます。

f:id:tsubaki_t1:20150726034906p:plain

あとはOnAnimatorMove内で移動の処理を記述してやればOKです。キャラクターの移動はTransformでやると壁を貫通するので、CharacterControllerやRigidbodyを使用し障害物を貫通しないようにします。

ちなみにRootMotionを使用したい場合、animator.rootPositionanimator.rootRotationを使用すると、アニメーションの移動が取得できます。

この実装をせずApplyRootMotoinにチェックが入っている場合、ルートの移動量で移動します。これ、直線移動は良いですが回転が面倒です。

マップから落下するのを絶対に防ぎたい場合は、NavmeshAgent.Moveを使うアイディアも良い気がします。

移動量に合わせてモーションを切り替える

キャラクターの移動量に合わせてモーションを切り替えます。状態によりAnimator.CrossFadeを使用してアニメーションを切り替えるのも良いのですが、今回はBlendTreeを使用します。

まず空のAnimationClipを切り替えるアニメーション分作ります。Animatorに内蔵してしまうとアニメーションがすっきりします。

ParameterにSpeedを設定し、このパラメータが0.1以上になった時にRunning・以下の場合はIdleするようにします。BlendTreeの設定はNavmeshのAI経路探索とAnimatorのアニメーションを連動させる もどうぞ。

f:id:tsubaki_t1:20150726041523p:plain

f:id:tsubaki_t1:20150726042548g:plain

最後にAnimatorOverrideControllerを使用してAnimatorのアニメーションを上書きします。Controllerに先ほど作成したAnimationControllerを設定し、上書きしたいAnimationClipで更新します。

これはAnimationControllerで直接設定しても良いのですが、個人的にはこっちの方がAnimationControllerを使いまわしやすいので好きです。

f:id:tsubaki_t1:20150726042838p:plain

あとは移動時に移動距離に合わせてanimator.SetFloatを設定してやると、移動量に合わせてモーションが切り替わります。

f:id:tsubaki_t1:20150726054305g:plain

ステートを増やすことで、ジャンプや落下中・着地のモーション切り替えもスムーズに行えるようになりますが、これはこれで長いのでまた今度。

移動先を向く

移動先を向いてもらいます。単純にCharacterControllerから移動量を持ってきて、移動先にキャラクターを回転させるだけです。

移動先=キャラクターの向いてる方向では無い場合は違う実装も出来ます。

if (direction != Vector3.zero) {
    var velocity = characterController.velocity;
    velocity.y = 0;
    transform.rotation = Quaternion.LookRotation(velocity);
}

スクリプト

今回のコードです。このコードをシーンに配置したモデルに設定すれば、たぶんアニメーションします。モーションが切り替わらない場合はAnimationControllerの設定が間違ってる、空気椅子したらモーションの設定が間違ってる、って感じです。

gist.github.com

Resetでやってるので、【Unity】コンポーネントを設定したフィールドを非表示にする でフィールドを非表示にします。

関連

tsubakit1.hateblo.jp

unity3d-study.seesaa.net

tsubakit1.hateblo.jp

今回は東北ずん子のイラスト/3Dデータのデータをお借りしました。SDずん子ちゃん可愛い!