LoginSignup
4
5

More than 1 year has passed since last update.

ARKitによるフェイストラッキングをやってみた

Posted at

はじめに

UnityからビルドしたiOSアプリでARKitを使って、フェイストラッキングをしました
参考記事で実装しているものを参考にさせていただいております!
今回はLive2Dを使用して自分の顔とアバターの表情を同期します!
一部省略しておりますのでご了承ください

※完成動画

まばたき 口パク 顔の向き
30254e211064d275bbc22a736fb6554b.gif 03065ee58c77fc78f4436148a832080e.gif 0b0448c3eda50e152ce9adeb9e63f8cc.gif

アバターのインポート

Live2D Cubism公式から使用するアバターをインポートします
スクリーンショット 2022-11-23 18.41.05.png

ARKitインポート

Package ManagerのUnity RegistryからAR Foundation、ARKit XR Plugin、ARKit Face Trackingの3つをインポートします
スクリーンショット 2022-11-22 18.22.55.png

Project SettingのXR Plug-in ManagementでARKitにチェックマークをいれます
スクリーンショット 2022-11-22 18.50.27.png

同じくProject SettingのXR Plug-in ManagementのARKitでFace Trackingにもチェックマークをいれます
スクリーンショット 2022-11-22 18.50.21.png

表情の同期

Sceneを作成して、XRからAR Session OriginとAR Sessionのオブジェクトを生成します
スクリーンショット 2022-11-23 18.57.00.png

AR Session OriginにARFaceManagerのコンポーネントをアタッチします
子のAR CameraのAR Camera ManagerのFacing Direcctionを自分を写すようにUserにしておきましょう

今回自分の表情は画面に表示したくないので、Canvasを生成してAR Cameraをセットします
Canvasの子にImageオブジェクトを生成しましょう

また、表示したアバターを写すために別のCameraを生成します
下の画像の通り分かりやすいように少し位置をずらしています
スクリーンショット 2022-11-23 19.06.00.png

アバターに表情を同期します
今回一部のみ同期するようにしています
Prametersオブジェクトの子から変更するオブジェクトを取得してます
上から0,1,2,3...といった感じです

var cubismModel = avatar.FindCubismModel();
faceAngleX = cubismModel.Parameters[0];
faceAngleY = cubismModel.Parameters[1];
faceAngleZ = cubismModel.Parameters[2];
leftEye = cubismModel.Parameters[3];
rightEye = cubismModel.Parameters[5];
mouthForm = cubismModel.Parameters[19];
mouthOpen = cubismModel.Parameters[20];

スクリーンショット 2022-11-23 19.18.57.png

表情が変わったら反映する処理を呼びます

private void OnEnable()
{
    faceManager.facesChanged += OnFaceChanged;
}

private void OnDisable()
{
    faceManager.facesChanged -= OnFaceChanged;
}

private void OnFaceChanged(ARFacesChangedEventArgs eventArgs)
{
    if (eventArgs.updated.Count != 0)
    {
        var arFace = eventArgs.updated[0];
        if (arFace.trackingState == TrackingState.Tracking
            && (ARSession.state > ARSessionState.Ready))
        {
            UpdateAvatarPosition(arFace);
            UpdateBlendShape(arFace);
        }
    }
}

最後に、ここでアバターの持つパラメーターと調整して値を計算して
アバターに反映します

private void UpdateBlendShape(ARFace arFace)
{
    using var blendShapesARKit = faceSubsystem.GetBlendShapeCoefficients(arFace.trackableId, Allocator.Temp);

    foreach (var featureCoefficient in blendShapesARKit)
    {
        if (featureCoefficient.blendShapeLocation == ARKitBlendShapeLocation.EyeBlinkLeft)
        {
            updateLeftEye = 1 - featureCoefficient.coefficient;
        }
        if (featureCoefficient.blendShapeLocation == ARKitBlendShapeLocation.EyeBlinkRight)
        {
            updateRightEye = 1 - featureCoefficient.coefficient;
        }
        if (featureCoefficient.blendShapeLocation == ARKitBlendShapeLocation.MouthFunnel)
        {
            updateMouthForm = 1 - featureCoefficient.coefficient * 2;
        }
        if (featureCoefficient.blendShapeLocation == ARKitBlendShapeLocation.JawOpen)
        {
            updateMouthOpen = (float)(featureCoefficient.coefficient * 1.8);
        }
    }
}

感想

参考記事の方の実装が分かりやすくスムーズに実装することができました
使用するアバターが2Dと3Dで反映する方法が多少違っているため調整が必要でした
また今回は最低限のパラメーターを取得して反映しているため、もっと細かく調整すれば
より滑らかな動きをさせることができると思います。

参考記事

https://qiita.com/amachi0/items/d830bd89a18b78745b84
https://www.live2d.com/download/sample-data/

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5