VRoidで作ったモデルをiPhoneXSでフェイストラッキングさせる(Unity ARKit)

VRoid面白いですね〜
わたしは根性がないので頭だけいじったモデルをいくつか作りました!!

hub.vroid.com

踊らせるのは諦めたんですが、ちょっとでも動かしたいじゃない〜
と思ってフェイストラッキングさせてみようと思いました。
いまだにUnityとは仲良しじゃないから、歩み寄りたいですよね。

 

こちらを参考にさせていただきました!!

qiita.com

 

必要なもの
  • Mac
  • Xcode
  • Apple developer
  • Unity
  • UniVRM
  • ARKit2
  • VRoid Studioでつくってエクスポートしたモデル

 

MacXcodeApple developerアカウント

iPhone用のアプリ作ろうとしてるので、超必須です。
実機につないでインストールするためには基本的にはdeveloperアカウント(99ドル/年)が必要なんですが、なくても実機には入れられるようです。

dev.classmethod.jp

ただ、いまのXcodeってAutomatic Signingがすごく便利になったので、この辺も便利になったのかなぁ。ちょっと不明です。わかんなかったら年99ドル払お!

Unity、UniVRM

UnityとUniVRMは以前設定したのと同様でしたので省略です。

 

ARKit2

ARKit2はアセットストアで見つけきれなかったんですよね …
なので、Bitbucketからリポジトリまるごともってきました。
わたしはSourceTreeを愛用しています。

Unity-Technologies / Unity-ARKit-Plugin / Downloads — Bitbucket

f:id:lejay4405:20190105182548p:plain

f:id:lejay4405:20190105182604p:plain


ここからダウンロードするなら、多分2.0マージしてあるからdefaultブランチでもいいんじゃないかな〜

VRoidで作ったVRMのモデル

hub.vroid.com

 

手順

  1. UnityでARKitのプロジェクトをそのまま開く
    (新規プロジェクトにARKitをインストールする手順がわからなかった!)

  2. UniVRMをインストールする
    プロジェクトを開いたまま「UniVRM-****.unitypackage」をダブルクリック
    (これ毎回やってるんですけどなんかいい方法ないんですかね)

  3. VRMのモデルをプロジェクトに追加
    VRoidで作ったモデルを「***.vrm」に出力したものをAssetsの下にドラッグ

    f:id:lejay4405:20190106204129p:plain

    しばし待つ

    f:id:lejay4405:20190106204620p:plain

    なんかいっぱいできるので、Assetsの下に「Model」とかいうフォルダをつくって入れてあげてもいいかもしれないですね!わたしはめんどくさいのでやっていません。

  4. ARKitの設定をする
    ここの2つにチェックを入れる

    f:id:lejay4405:20190106222837p:plain

  5. スクリプトを書く
    サンプル「UnityARFaceAnchorManager」をエディタ(わたしはUnityのVisualStudioをインストールしていないので外部エディタです)にコピペして書き足し、Assetsの下に「FaceTracking.cs」という名前で保存。
    using UnityEngine;
    using UnityEngine.XR.iOS;
    using VRM;
    
    public class FaceTracking : MonoBehaviour {
    
        //インスペクタの設定項目
        [Header("VRMモデルを設定")] //項目タイトル
        public Transform Head; //動かしたい頭部分
        public VRMBlendShapeProxy proxy; //モデル本体
    
        private UnityARSessionNativeInterface m_session;
    
        // Use this for initialization
        void Start () {
            //ネイティブのsessionインタフェースを取得
            m_session = UnityARSessionNativeInterface.GetARSessionNativeInterface();
    
            //必要なのかわからない
            // Application.targetFrameRate = 60; 
            
            ARKitFaceTrackingConfiguration config = new ARKitFaceTrackingConfiguration();
            config.alignment = UnityARAlignment.UnityARAlignmentGravity;
            // UnityARAlignmentenum
            // WorldAlignment - ARKitが実際のデバイスの動きに基づいてシーン座標系を構築する方法に関するオプション
            // UnityARAlignmentGravity - 座標系のy軸は重力に平行で、その原点はデバイスの初期位置 ←これ
            // UnityARAlignmentGravityAndHeading - 座標系のy軸は重力と平行で、x軸とz軸は方位をコンパスに向け、原点はデバイスの初期位置
            // UnityARAlignmentCamera - シーン座標系は、カメラの向きに合わせてロック
            config.enableLightEstimation = true;
    
            //サポートしてるときだけ動きます
            if (config.IsSupported)
            {
                //ARセッション設定
                //・ARKitWorldTrackingSessionConfiguration (6DOF) 
                //・ARKitSessionConfiguration (3DOF)
                //configには上の二つどちらかを設定ってあるんだけど、ARKitFaceTrackingConfigurationでもいいんじゃろうか
                m_session.RunWithConfig(config);
    
                //顔の検出
                UnityARSessionNativeInterface.ARFaceAnchorAddedEvent += FaceAdd;
                UnityARSessionNativeInterface.ARFaceAnchorUpdatedEvent += FaceUpdate;
                UnityARSessionNativeInterface.ARFaceAnchorRemovedEvent += FaceRemoved;
            }
            else {
                // 利用できない場合の処理
            }
        }
    
        //コールバック 顔検出
        void FaceAdd(ARFaceAnchor anchorData) {
            //頭と顔を更新
            UpdateHead(anchorData);
            UpdateFace(anchorData);
        }
    
        //コールバック 顔検出中
        void FaceUpdate(ARFaceAnchor anchorData) {
            //頭と顔を更新
            UpdateHead(anchorData);
            UpdateFace(anchorData);
        }
    
        //コールバック 顔検出外れ
        void FaceRemoved(ARFaceAnchor anchorData) {
            //なにもしない
        }
    
        //頭の位置を更新
        void UpdateHead(ARFaceAnchor anchorData) {
            //ARKitが右手軸なのをUnityの左手軸に変更と水平坑はミラーにするように変更
            float angle = 0.0f;
            Vector3 axis = Vector3.zero;
            var rot = UnityARMatrixOps.GetRotation(anchorData.transform);
            rot.ToAngleAxis(out angle, out axis);
            axis.x = -axis.x;
            axis.z = -axis.z;
            Head.localRotation = Quaternion.AngleAxis(angle, axis);
        }
    
        //表情更新
        void UpdateFace(ARFaceAnchor anchorData) {
            var blendShapes = anchorData.blendShapes;
            if (blendShapes == null || blendShapes.Count == 0)
            {
                return;
            }
    
            //口の開き(閉0.0←→1.0開)
            proxy.SetValue(BlendShapePreset.O, blendShapes[ARBlendShapeLocation.JawOpen]);
            //目の開き(閉0.0←→1.0開)
            proxy.SetValue(BlendShapePreset.Blink_L, blendShapes[ARBlendShapeLocation.EyeBlinkLeft]);
            proxy.SetValue(BlendShapePreset.Blink_R, blendShapes[ARBlendShapeLocation.EyeBlinkRight]);
        }
    }
  6. シーンを作る
    これもサンプルををコピペして使います。

    f:id:lejay4405:20190106224203p:plain

    「FaceAnchorScene 1」っていうのが出来るので、「FaceTracking」にリネーム

    f:id:lejay4405:20190106224406p:plain

    こいつをダブルクリックして開く

    f:id:lejay4405:20190106224817p:plain

    「Hierarchy」にある
    ・ARFaceAnchorManager
    はコピペ元なのでいらないです。削除。

    「Create」から「Create Empty」を選択すると「GameObject」ができるので

    f:id:lejay4405:20190106225200p:plain

    名前を「FaceTrackingManager」にします。

    f:id:lejay4405:20190106225446p:plain


    さっき作ったFaceTracking.csがAssetsの下にあるので探し出して…

    f:id:lejay4405:20190106225822p:plain

  7. モデルをシーンに追加

    f:id:lejay4405:20190106230012p:plain

    ワーイ

    f:id:lejay4405:20190106230158p:plain

    インスペクタで頭と本体を設定する。
    頭はどこだ…!!!!

    f:id:lejay4405:20190106230423p:plain

    ここです

    f:id:lejay4405:20190106230533p:plain

    頭ほんとどこにあるのかめっちゃ探しました。


  8. カメラを調整
    なんかカメラが後ろ向きだったので〜、ひっくり返しました。

    f:id:lejay4405:20190114180102p:plain

    f:id:lejay4405:20190114180221p:plain

     

  9. iOSビルド
    メニューの「File」-「Build Settings...」を選ぶとこういう画面が出てくるので、PlatFormからiOSを選んで「Switch Platform」

    f:id:lejay4405:20190114180837p:plain

    しばし待つ(けっこう時間かかる。つよつよMacなら一瞬かも。)

    「Player Settings...」でXcode側の設定もできる。いちいち書き出してからSigningの設定するのめんどくさいのでやっておくといいですよ!!
    チームIDはAppleアカウントで確認できます。

    iOS Dev登録してなくても実機確認できるようなのですが、わたしはDev登録しているため省略です。よろしくです。

    あとはIDをてきとうに設定したり、アプリ名を設定したり、必要ならアイコンやスプラッシュを登録したりしたらいいと思います。省略

    f:id:lejay4405:20190114183340p:plain

    そしたら、「Add Open Scenes」を押して、作ったシーンを選択

    f:id:lejay4405:20190114184752p:plain

    そして「Build」を押してお茶を入れます。
    できあがった「Unity-iPhone.xcodeproj」をxcodeで開いて、実機に入れて

    f:id:lejay4405:20190114193308p:plain


    アプリ起動すると

    f:id:lejay4405:20190114193344p:plain

    はいできたー!

    このままだと背後に妖怪が映り込んでしまうので(スクショからは抹消しました)、困ってしまいました。
    「壁みたいなのがあればいいのでは」「ハリボテを置こう」「天才」

    f:id:lejay4405:20190114193648p:plain

    「Hierarchy」-「3D Object」-「Plane」で平べったい板のようなものをつくって...

    f:id:lejay4405:20190114194016p:plain

    よいしょよいしょと位置をずらして...
    再ビルド

    f:id:lejay4405:20190114194900j:plain


    わーいうまくいきましたよ!
    つくったすぐは髪が揺れてたんですが、ブログを書くために手順をやりなおしたら髪が揺れなくなっちゃった!Vroid Studioでのエクスポート間違えたかな〜!!

    ちょっとUnityと仲良くなれた感じありますね!

    では!