MikuMikuSoine開発を振り返ってみる。

OculusRiftAdventCalender 17日目担当のねぎぽよし(@CST_negi)です。よろしくお願いします。

Unityで本格的に何か実装するってことは今回が初めてだったのですが、そこでMikuMikuSoineするにあたって実装してる時の思い出(?)を3つくらい振り返りたいと思います。
自分は何か開発するときによく紙にいろいろ書きまくるのですが、今回の記事はそれを見て思い出しながら書いています。

ちなみに
OS:Windows7 64bit Professional
Unity Version:4.2.2f1 Pro
MMD4Mecanim Version:MMD4Mecanim_Alpha_20131104_4
でやってます。

1.OVRCameraControllerアセットのNearClipの値変更
OVRCameraControllerのNearClip Plane値をいじってもなぜかNearClip Plane値が適用されなかったことがありました。
(しかし、Inspector部分にOVRCameraControllerが表示されたままにして再生ボタンを押してデバッグを開始すると、変更されたNearClip Plane値が適用されるという挙動をしていまして、これに関してはぐぐっても解決しませんでした。)
ちなみにOVRCameraController.csのソースコードを書き換えてデフォルト値(0.15f)を0.01fに変えてもデフォルト値から値が変更されませんでした。

とりあえずこれをどう解決したかということなんですが、
[OVRCameraController]直下の[CameraLeft],[CameraRight]それぞれのClipping Plane(Near)値を変更しました。
これによって、OVRCameraControllerアセットのNearClip値を適用することができました。(右図参照)
全体を直すのではなく、片目ずつ直していきましょう。










2.MMD4Mecanimの話
MMD4MecanimというのはPMX(PMD)+VMDをFBXに変換するツールであり、Unity(Mecanim)で一通り動作させるためのスクリプトです。
(Nora(@Stereoarts)さん作。ちなみにNoraさんに「M4Mのここはこうしてほしい」と要望を言うと怖いくらいの早さでフィックスされます。凄い!)

旧MikuMikuSoineではUnity4MMDを使っていたのですが新しく作り変えるにあたってUnity4Mecanimのほうに移行しました。
で、ここでかなりいろんな問題にハマりました。
例えば、PMXモデルに重力を適用すると初期化時に髪の毛や服が暴れたり、モーションファイルの最終フレームに対して線形補間が働かなかったりとか。
ですが、これ直してください!とNoraさんに言ったら3日でこれらの問題を解決した新しいバージョンのMMD4Mecanimができました。凄い!

なので今回は他にハマったこととしてキャラクター(PMX)のAnimation Typeの話をしたいと思います。

AnimationTypeはPMXをimportした後にできるPrefabのInspectorで選択することができます。(右図)
ちなみにNone Legacy Generic Humanoidがあるのですが、GenericかHumanoidを使うのが一般的だと思います。
簡単に説明すると
GenericはVMDの再現性を重視したタイプです。再現性は高いのですが、視線移動(LookAt)とか人体IKとかHumanoid特有の機能は使うことができません。
HumanoidはVMDの再現性が下がる代わりに視線移動や人体IKなどの機能、そして一番のメリットである(と僕が勝手に思っている)Mecanimモーションを再生できるというメリットがあります。

MikuMikuSoineではキャラクターに自分を見てもらうということをしたかったので、視線移動(LookAt)機能を使いたく、Humanoidを使って色々やろうと思っていました。
最初の方はHumanoidで試行錯誤してて、その後いろいろやっててだんだんわかってきたのが、VMDとHumanoidは想像以上に相性が悪いなぁということです。
HumanoidのキャラクターモデルでVMDを再生しようとすると、突然キャラクターが浮いたり(しかも、キャラクターによって浮いたり浮かなかったりする。自分のメモには"艦娘は浮く"と書いてありました。謎だ。)
Y軸方向に90°回転してVMDを再生したりと、不可解な現象が沢山発生してしまいました。

というわけで結局どうしたのかということなんですが、結局Genericでやりました。
VMDの再生を優先したかったのと、キャラクターの頭部分にLookAt関数を書いたスクリプトを適用することで普通にLookAt機能と同等のことができたためです。
VMDを使う時はGeneric、VMDを使わずHumanoid特有の機能を使いたいときはHumanoid、でおそらく安牌なのかなぁと思います。
というかこれに関してはMMD4MecanimをDLした際に同梱されている説明書にちゃーーーーんと書いてあるので、よーーーく読みましょう!(よく読まずに始めた人間なのでいろいろハマりました。)



3.キャラクターの頭を見てモーションを再生するという実装
これはハマったことではなく、単純に自分のメモというか。
MikuMikuSoineはキャラクターと視線を合わせることによって、(ユーザが)見ているキャラクターのモーションを再生させるということをしてるんですが、それの実装の話。

・視線を合わせるということ
これは凄い安易な発想というか、OVRCameraController→CameraRightのアセットの下に直方体のアセットを作り(これによって頭の方向と直方体の方向を合わせることが可能です。)、
キャラクターの頭との衝突判定をとって、一定時間以上衝突している時間が経過した時にそのキャラクターのモーションを再生させるということをしています。

・アニメーションの遷移
下図のような感じでアニメーションのステートモデルを組みました。
左下のLookTime、NoLookTimeはその衝突時間を表しています。アニメーションのステートが遷移すると0に初期化するようにしています。
アニメーションの遷移は、A→B→Cという遷移をしたいのに、A→Cみたいな遷移をしちゃうとモーションとして凄く不自然です。スクリプトから直接呼ぶとそういったことが起きる危険があるし、それに気をつけて構築するとなると
モーションが増えた時に禿げるので、ステートモデルを使うことでココらへんを簡単にしています。

アニメーションステートモデルを使うことでこのようにミスが減ったのももちろんよかったことなんですが、MikuMikuSoineはC#のコードを「全部で」100行程度しか書いてないことも付け加えておきたいと思います。(Unityは凄く、そして怖い)


というわけで、簡単になりましたが僕からの記事は以上になります。ありがとうございました。
次回は18日ということで@warapuri先生にバトンタッチになります。

あと、Unityからユニティちゃんというキャラクター(下図)が今日公開(http://unity-chan.com/)されていたのですが、本当に可愛いと思うし、MS台湾の藍澤光ちゃんみたいな衝撃がありますね。
どんどんPixivの投稿が増えたり、本が薄くなっていってほしい… あと、Unityのいろんなところを触るとユニティちゃんのいろんなところを触れるんだよな…みたいな妄想ができるし本当に良いっすね^〜


(ユニティちゃんかわいい!)