見出し画像

Vtuberのやり方研究メモ① XR Mecanim IK PlusをベースにしたHTC Vive+トラッカー環境でのバーチャルキャラクターIK制御(途中)

※詳しくない人のメモ書きです。

某よく拝見しているニコ生主さんが最近流行りのバーチャルキャラクター技術について研究しているということで、一緒になってVtuberのやり方を試してみてます。シロさん推しです。

ソフトウェア環境はUnity 2017.3。その他アセットとしてSteamVR Plugin、XR Mecanim IK Plus、ユニティちゃん3Dモデルデータを使用。使用ハードウェアはHTC Vive、Viveトラッカー。

目標としては、ひとまず某生主さんに合わせて、「頭部にトラッカーを着用し、ヘッドセットをかぶらずに半身~全身のモーションキャプチャーを行う。ゲームをしている様子を配信できるような環境」とします。その後の展開としては、Vtuber的な動画を投稿できたら楽しいね、という感じ。まあひとまず技術テストということで。

今回の進捗は、ひとまず「XR Mecanim IK Plusを改造してViveトラッカーの位置・姿勢情報からIK制御できそう!」というところまでです。具体的には、これからIK及びメカニムの勉強をする必要が出てきました。という段階です。

結論から言うと、「これは90ドル出してFinal IKを買う価値あるな」という感想が得られました。一方で、高度な制御が必要ないのであれば、メカニムでも頑張れそう?


■各用語のメモ

・Vtuber、バーチャルキャラクター
バーチャルYouTuberとも。キャラクター3Dモデルになりきって、実在する人物であるかのように体の動きを表現できる人たち。程度は場合による(表情だけでもいい)。

XR Mecanim IK Plus
Unityのメカニムというアニメーション制御システムを、VR機器で制御するための神アセット。シンプルで構造が分かりやすいけど、シンプルすぎてSteamVR Pluginと連携していないのがたまにキズ。

・IK
キャラクター3Dモデルを制御する方法の一つ。階層構造の末端(手首や足、頭など)から親階層を動かしていくのでinverse kinematics(逆運動)と呼ぶらしいです。
例えばモデルの中で一番の親となる階層(体とかかな?)を動かした場合、キャラクターモデル全体が動きますよね。また、左太ももを動かすと、その子階層である左すね、左足などが追従して動きます。これが普通の制御。
これに対して、IKでは左足を引っ張って、それに引っ張られて左すねや左太ももが変形を伴いながら動く、といった動作を実現できます。
ただし、あくまでも制御は「親の動きに子が追従する」という形で行われるため、IK制御点を追加することで、擬似的に逆運動を実現しているようです。
今後の課題①。

参考:手首などのIKについてざっくり(STONEのブロマガ)

メカニム
Unityで3Dモデルを制御するときの、アニメーション回りの統合システムだそうです。主に人型向けっぽい。アニメーターのことは考えたくないので、できれば触れたくない。そこに触れずに済むシステムがメカニムだったりしたら嬉しい。とりあえずXR Mecanim IK Plusをサンプルに研究してみます。
今後の課題②。

参考:UnityのMecanimでキャラクターを動かす(yandoさん、Qiita)


■XR Mecanim IK Plusの中身

XR Mecanim IK Plusを用いれば「ViveヘッドセットとViveコントローラーを用いた上半身のトラッキング」は可能なのですが、今回はViveトラッカーでの利用や全身トラッキングも視野にいれるため、同アセットを改造する必要があります。

そもそもXR Mecanim IK Plusはどういった制御を行っているのか? まず、データの流れとしてはこう。

体験者の身体動作

①トラッキングデバイス(HMD、コントローラー、トラッカー)の位置・姿勢が変化

②「IKターゲット」の位置・姿勢が変化

③メカニムのIKを制御

順番に見ていきます。

①トラッキングデバイス(コントローラーやトラッカー)の位置・姿勢は、UnityネイティブのXR機能やSteamVR Pluginを利用することで取得できます。XR Mecanim IK Plusでは前者が用いられていますが、今回はトラッカーの取得のため後者のSteamVR Pluginに置き換えました。後述。

②IKターゲットは、③で行われているメカニムのIK制御が「目標点」とする座標です。たとえば左手のIKターゲットがキャラクターの前方遠くにある場合、左手ごと左腕が前に突き出されます。メカニムあたりが勝手にちぎれないように可動範囲を制限してくれているので安心です(詳しくは知らない)。
XR Mecanim IK Plusでは、以下のように各IKターゲットが定義・制御されています。

IK_Target_LookAt……顔が見つめる先。VR HMDにあたるオブジェクトCamera (Eye)の前方2メートルに置かれているので、HMDが回転するとその視線の先に常に存在しています。よってスクリプト制御はなし。
IK_Target_Body……体の位置。位置は左右の足の中心を基準として決定されているようです。また角度Y軸は、左右の足の角度と両手の位置が基準とのこと。制御スクリプトはIK_Body_Linkage_CSが該当。
IK_Target_Hand(L/R)……両手の位置。左右のコントローラーの位置・姿勢と常に同期されています。制御スクリプトはXR_Hand_Tracking_CSが該当。
IK_Target_Foot(L/R)……両足の位置。XR Mecanim IK Plusではコントローラーのグリップを握ることで、コントローラーを動かして足を動かすことができます。この時に動かされるのがこのオブジェクト。制御スクリプトはIK_Foot_Linkage_CSが該当。
IK_Pivot……Bodyの仲間です。体の軸を決めています。メカニムのIK制御では用いられず、IK_Target_Bodyの決定に用いられています。制御スクリプトはIK_Target_BodyにアタッチされたIK_Body_Linkage_CSが該当。

以上が、XR Mecanim IK Plusに含まれるIKターゲットになります。簡単に言えば、「視線の先」「胴体」「両手」「両足」です。これを追加していけば(肘とか)、より多くの点でキャラクターモデルをIK制御できるようになりそうです。

③メカニムのIK制御は、IKターゲットに従って実際にIKの制御を行っている部分です。スクリプトではIK_CSが該当します。
見た感じ、メカニムにはUnity標準のIK制御機能として、いくつかのクラスがあらかじめ用意されているのだと思います。
例えば、Animator.SetLookAtPositionを用いると、パラメーターとして渡したLookAtオブジェクトの座標に向かって注視動作が行われる、とか。今回の場合、IK_Target_LookAtをAnimator.SetLookAtPosition(及びRotation)に渡すことで、あとは勝手にメカニムがIK制御して頭の向きを動かしてくれるよ、ということでしょう。まだ全部見れていないのでちょっと曖昧ですが。
そういう意味では、メカニムを使う場合は、用意されていないIK制御はできないのかな? とも思えてきます。XR Mecanim IK Plusでも「MecanimのIKでは首をかしげる動作が出来ない(ため独自に実装した)」という記述があるので、自分でIK制御を拡張するのは大変な作業なのかもしれない。
とはいえ基本的な身体動作はできると思うので、Vtuberならメカニムベースでもいけるんじゃないかなと思います。メカニムのスペックはよく調べておきます。

その他のスクリプトとしては、上述のメカニムにはできない首をかしげる動作を追加実装するIK_Head_Linkage_CS、キャリブレーションなどを行うXR_Basic_Function_CSがあります。それぞれ行数も少ないので、シンプルな実装で分かりやすいですね。ありがたい。

うーん、IKの概念もさることながら、メカニムの全容も把握しきれていないので、頭が沸騰しそう。適当なこと言ってたらすみません!
IKとメカニム(及びその他のIK制御手段)については今後の勉強課題とするとして、ここらへん見てるとFinal IK買うのはアリだなあ、と思えてきます。某生主さんの方はFinal IKを買われていたので、それを参考に検討したい。


■Viveトラッカーの位置・姿勢取得

さて、Viveトラッカーはあらゆる物体をトラッキング可能にするすごい部品ですが、あくまで部品なので消費者には浸透してません。それもあってか、開発事例が非常に少ない。

Unityでは2017.2あたりからネイティブのXR機能が増えてるそうで、例えば「XRNode」クラス(クラスで合ってる?)を用いると、トラッキングデバイス(コントローラーとか)の位置・姿勢情報とかが取れるみたいです。例として、XRNode.LeftHandで左手のモーションコントローラーの位置・姿勢が取得できたり。それで、XRNodeにはHardwareTrackerというViveトラッカーに該当しそうなプロパティもあるのですが、これを入れてもトラッカーの位置・姿勢は読み取れませんでした。残念。

XR Mecanim IK PlusではXRNode.Left(及びRight)Handを用いてコントローラーの位置・姿勢を取得しているのですが、上記の理由からXRNodeではトラッカーが読み取れなかったため、今回はSteamVR Pluginを利用しました。

SteamVR Pluginは、UnityでHTC Vive開発するときには大体お世話になるであろう公式アセットです。基本的には[CameraRig]を導入することでルームスケール環境やトラッキングデバイスを利用すると思うのですが、今回はトラッキングデバイスの位置・姿勢さえ取得できれば良いので、一部のスクリプトのみを用いました。該当するのは、SteamVR_ControllerManager、SteamVR_TrackedObjectです。

まずはデータの流れを示します。

トラッキングデバイス(コントローラー、トラッカー)が実空間で移動

①トラッキングデバイスと位置・姿勢が同期する空のオブジェクトを用意

②空のオブジェクトのtransformを元にIKターゲットを決定

以上の実装で、任意のトラッキングデバイスからメカニムのIK制御を行うことができます。手足なんかは空のオブジェクト=IKターゲットでもいい。

①では、上述した二つのスクリプトを用いて、トラッキングデバイスの位置・姿勢を空のオブジェクトに反映します。
具体的には、以下の実装を行います。

・空のオブジェクトをトラッキングデバイスの数だけ用意し、それぞれにSteamVR_TrackedObjectをアタッチ
・カメラオブジェクトにSteamVR_ControllerManagerをアタッチ
・SteamVR_ControllerManagerにて、Leftに左コントローラー、Rightに右コントローラー、Objectsにトラッカーにあたる空のオブジェクトを代入。Objectの個数はsizeを増やすことで増やせる

以上の操作で、空のオブジェクトそれぞれのtransformが、ControllerManagerで設定したトラッキングデバイスに追従するようになります。[CameraRig]の中身とやってることは同じです。

②では、それぞれ任意の方法で、トラッキングデバイスの位置・姿勢を元にIKターゲットを決定してやれば良いです。ここが一番難しいところ。要するに、どのようなトラッキング情報があればどこのIKターゲットが確定する、ということを考えて配置します。
とはいえ、全身トラッキングであれば両手両足はトラッキングデバイスとIKターゲットの位置を同期させればいいかと思います。
また例えばLookAtであれば、頭部に装着したトラッカーから2メートル離れた位置に空のオブジェクトを子として置き、それをIKターゲットとすればよいということになります。ただし、トラッカーの回転方向とLookAtとの位置関係を合わせる必要があるので、リファレンスなどを参考に調整が必要です。

ひとまずSteamVR Pluginを利用することでトラッカーの位置・姿勢取得は実装できたので、あとはメカニムのIK制御について調べて、必要なIKターゲットとトラッカーの固定位置を考えることになります。現状ここまでの進捗です。


■まとめ

今回の目的は、半身・全身のトラッキングを、Viveトラッカーメインで行うことです。

そのためには、トラッカーで取得した体の一部の座標から、制御するIKのターゲット座標を推定する必要があります。

現状IK及びメカニムについての知識が足りないため、こちらは要勉強。

メカニムの代わりに有料アセットのFinal IKを用いることもできそうですが、現状そこまで高度な制御を必要としていないため、メカニムのIK制御で何ができるかを調べてみたいと思います。

IK、というかキャラクターモデル制御回りは、アニメーター含めほんと謎まみれなので、少しずつ理解していきたいところ。

ということで、次回につづく(といいですね)。


■SteamVR Pluginがうまく動かないバグ(?)

余談ですが、SteamVR Pluginが正常に動かないバグが発生したので、備忘録的に書いておきます。

結論から言うと、SteamライブラリからSteamVRをアップデートしたら正常に動作しました。

[CameraRig]をシーンに入れて再生した時、コントローラーやトラッカーのオブジェクトがグレーアウトし、描画・トラッキングされなくなるという不具合が発生しました。また最終的には、HMDへの描画も変になる始末(画面がヘッドセットについてくるような描画)。

ちゃんとアップデートしようね!

この記事が気に入ったらサポートをしてみませんか?