はじめに
UnityからビルドしたiOSアプリでARKitを使って、フェイストラッキングをしました
参考記事で実装しているものを参考にさせていただいております!
今回はLive2Dを使用して自分の顔とアバターの表情を同期します!
一部省略しておりますのでご了承ください
※完成動画
まばたき | 口パク | 顔の向き |
---|---|---|
アバターのインポート
Live2D Cubism公式から使用するアバターをインポートします
ARKitインポート
Package ManagerのUnity RegistryからAR Foundation、ARKit XR Plugin、ARKit Face Trackingの3つをインポートします
Project SettingのXR Plug-in ManagementでARKitにチェックマークをいれます
同じくProject SettingのXR Plug-in ManagementのARKitでFace Trackingにもチェックマークをいれます
表情の同期
Sceneを作成して、XRからAR Session OriginとAR Sessionのオブジェクトを生成します
AR Session OriginにARFaceManagerのコンポーネントをアタッチします
子のAR CameraのAR Camera ManagerのFacing Direcctionを自分を写すようにUserにしておきましょう
今回自分の表情は画面に表示したくないので、Canvasを生成してAR Cameraをセットします
Canvasの子にImageオブジェクトを生成しましょう
また、表示したアバターを写すために別のCameraを生成します
下の画像の通り分かりやすいように少し位置をずらしています
アバターに表情を同期します
今回一部のみ同期するようにしています
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];
表情が変わったら反映する処理を呼びます
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/