漢なら iPhoneX + Unity で face tracking して vtuber 目指したいですね!
ねんがんの iPhone X + Unity での facial capture アプリの実行に成功したぞ!!!! 🎉🎉🎉🎉🎉🎉😤😤😤😤😤😤✌️✌️✌️✌️✌️✌️㊗️㊗️㊗️㊗️㊗️㊗️😎😎😎😎😎😎😎 > https://t.co/ALwQN3YiVq pic.twitter.com/JXQ9nGAM8O
— Syoyo Fujita (@syoyo) April 22, 2018
やりましょう!
準備
- iPhoneX と XCode 開発環境と https://github.com/johnjcsmith/iPhoneMoCapiOS
- Unity(2017.2 or later) と https://github.com/johnjcsmith/iPhoneMoCapUnity
- iPhoneX と Unity を動かす PC(Windows だとうまくいなかったので, mac のほうがネットワーク接続問題がなさそう)が同一ネットワーク(wifi) 環境にあること.
仕組み
iPhoneX の face tracking SDK により BlendShapes のウェイトを取得できます.
(ちなみに, face tracking 自体はふつうのカメラ画像からやっているっぽくて赤外線センサーを隠しても認識します. Apple 側で iPhoneX でのみ動作するように制限がかかっています)
iPhoneMoCapiOS では, その BlendShapes の重みを UDP で Unity に飛ばし(テキストにして送信), Unity でそのデータを受け取り BlendShapes をコントロールします.
セットアップ
iPhoneMocapiOS を XCode でビルドして iPhoneX にインストールしておきます.
Unity で iPhoneMoCapUnity のデータを読み込みます. Unity と iPhoneMoCapUnity のバージョン違が違うとロードがうまくいかないようなので, 必要に応じて, 一旦 Asset を Hierarchy に再インポートします.
Unity 側では, ネットワークが同一環境にない場合は Unity 側のネットワーク UDP アドレスを調整ください.
(たとえば 192.168.10.xxx
の IP アドレスなら, ブロードキャストアドレスとして 192.168.10.255
など)
UDPServer.cs で boardCastIP を必要に応じて自分のブロードキャストアドレスに変更します.
private static IPEndPoint broadCastIP = new IPEndPoint(IPAddress.Parse("192.168.10.255"), 49452);
また, いろいろ変えたら iPhoneX 側のアプリを再起動しましょう(以前のネットワーク設定での connection が残って, Unity 側と繋がらなくなったりする)
ユーザ作成の BlendShapes を動かす.
Maya で BlendShapes を作るものとします.
Blender でも形式を合わせればいけるかもしれません.
BlendShapes に詳しい優秀な BlendShapes アーティスト若人を探しましょう!
各シェイプの名前(e.g. eyeBlinkLeft
)は iPhoneX face tracker の名前と合わせます.
iPhoneMoCapUnity に付属の JohnSmithHead.fbx を Maya に読み込んでノード名などを確認して BlendShapes データを作るとよいでしょう.
出来上がったら FBX でエクスポートします.
Unity で読み込む
Unity 側で読んだ Asset を Hierarchy にインポートしたときに, 名称を BlendShapeTarget
に変更しておきます.
もしくは, NetworkMeshAnimator で GameObject.Find("BlendShapeTarget")のところを変えます.
public void StartAcceptingMessages() {
Debug.Log("Started accepting messages");
meshTarget = GameObject.Find ("BlendShapeTarget").GetComponent<SkinnedMeshRenderer> ();
Shape 名の対応
エクスポートの仕方が悪いのか, FBX を Unity で読むと
blendShape1.eyeBlinkLeft
などと, Maya の親?ノード名(blendShape1.
) プレフィックスがついてしまいます.
Unity のエディタ側でノード名を修正する機能はないため, とりあえずは C# スクリプトを修正することで対応します.
NetworkMeshAnimator.cs の SetBlendShapesOnMainThread で, 以下のように prefix をくっつけます.
var mappedShapeName = strArray.GetValue (0).ToString ().Replace ("_L", "Left").Replace ("_R", "Right");
// HACK
mappedShapeName = "blendShape1." + mappedShapeName;
これで自分が作った BlendShapes をアニメートすることができます!
Happy vtuber developing!
TODO
- FBX で BlendShape 名に prefix がつかないようにする方法を探す.
- 顔の傾きなどの情報も扱えるようにする
- 物理エンジン?
- Blender と連携したい
- 優秀な若人さまが, 人類史上最速で iPhoneX + Unity で BlendShapes と face tracking を極め, 1 億総 vtuber 活躍社会を実現するスキームを確立する旅に出たい.