UnityのLive Captureを使ってアバターに表情をつけて仮想カメラで出力する

# ラーメンセット カタ

![DSC_0069.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/a8d99134-96e6-4a48-0b9c-26afa2583472.jpeg)

# はじめに

オンラインでのビデオ通話するときに、アバターで登場することも増えてきてますね？

そういったときに、以前はAnimazeを使っていました。

https://store.steampowered.com/app/1364390/Animaze_by_FaceRig/?l=japanese

Webカメラだけで完結できるのでとてもお手軽です。

こんな感じになります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/gDU3NAuwDNQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

これでも十分すごいですが、例えばカメラアングルの自由度とか、トラッキングデバイスのサポートとかはどうしても限られてしまいます。（それでもLeap Motionに対応してたりとかすごい）

それに対して、例えばUniyを使えば、VR用トラッカーとか使って手を動かしたり、複数のカメラを一定時間ごとに切り替えたり、好きなアニメーションを付けたりとか、いろいろ自由にできるようになるなと思いました。

いろいろ調べた結果、なんとか実現できたので、その方法を紹介します。

完成動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/4m4qByr0PRM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 必要なもの

- iPhone
- Unity
- HANA Tool (有料)

あと他にいくつかツールがありますが無料です。

ARKitまわりに詳しくないので、どのiPhoneならちゃんと動かせるのかはちょっと定かではないですが、FaceIDが使えるiPhoneだと使えるのではないかという感じです。

OSはWindowsで作業しています。Macの場合、最後に出てくる仮想カメラのソフトウェアが対応していない可能性があります。

# iPhoneの作業

Unity Face Captureをインストール

https://apps.apple.com/jp/app/unity-face-capture/id1544159771

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/4df5678b-165b-59e9-2650-620090f6fc8e.png)

※Wi-Fiを使いPCと同じネットワークに接続する必要があります（推測

# アバターを作る

VRoid Studioを使います。

https://vroid.com/studio

私はSteam版を使っています。

一通り好きなパーツを選んでアバターを作成したら、VRMエクスポートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/2014640a-8d19-31ce-f5ee-d68158a915c6.png)

エクスポートの設定で、透明メッシュを削除するのチェックを外します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/639f229e-6462-560d-1df4-639959be3592.png)

エクスポートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/f9b8db3b-b241-2149-4024-df30283aaeb7.png)


# UniVRMでVRMをUnityにインポート

先ほど作ったVRMをUnityにインポートしていきます。

VRM形式はそのままでは扱えないので、UniVRMを使います。

https://github.com/vrm-c/UniVRM

インストール方法
https://vrm.dev/univrm/install/univrm_upm.html

インストール後、VRMファイルをUnityにドラッグアンドドロップすると、処理が走った後にたくさんファイルが出現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/8c13af78-831a-70e3-d55e-ce109763bba5.png)

プレファブをそのままシーンかヒエラルキーにドラッグすると、表示されるのがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/dc0921f4-0a04-5d35-6c67-b239ef6c1a00.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/ea7d4fe5-e66b-ef9d-f432-ea0dbab66c11.png)

# HANA Toolでブレンドシェイプの追加

インポートしたアバターは、表情のブレンドシェイプがまだ足りてないので、HANA Toolを使って追加していきます。

HANA Tool
https://booth.pm/ja/items/2437978

## インストール

購入すると.unitypackageがダウンロードするので、Unityにインポートしておきます。

プロジェクトウィンドウにドラッグアンドドロップするとか、Assets > Import Package > Custom Package...など

## ブレンドシェイプの追加

インストールすると、メニューバーにHANA_Toolという項目ができますので、Readerを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/d8a7f407-f775-c9c8-d1d3-eea1d13f4df6.png)

SkinnedMeshRendererのところに顔のところのコンポーネントを設定し、PerfectSync_VRoid_v1_0_0_Female.txt（もしくはMale）のラジオボタンを選択してRead BlendShapesを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/ddcd7238-483d-e72c-9a6d-fec3a552d566.png)

うまくいくと、「変換完了」というダイアログが出て、ブレンドシェイプが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/0d39ef73-c722-4399-c5cc-8bc1683d5ff0.png)

ここで、透明メッシュの設定を確認してください等のメッセージが表示された場合、VRoid Studioでのエクスポートの時に、透明メッシュを削除するというチェックボックスがオンになっている可能性があります。

裏では、新しいメッシュが作られて、それが紐づけられるみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/dcda7d73-3eff-b970-07e7-d0301910b0d0.png)

## Prefabの保存

この後の作業の兼ね合いで、いったんPrefabかPrefab Variantとして保存しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/854be3d5-fd6b-c835-c0ec-876f3c721478.png)


# Live Captureでアバターの制御と表情トラッキング

次に、アバターのブレンドシェイプを制御するためのパッケージをインストールします。

ここのインストールの仕方はUnityのバージョンによって表示が異なることが多いです。

Window -> Package Manager

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/40b3df9b-21d6-6eab-bfd6-262c1f50e75a.png)

Packages: Unity Registryとなっていることを確認して、Live Captureを探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/8b1d28f7-f6ab-a2ba-5cfc-3cc00bfd0538.png)

Installボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/86fd7f33-1dba-a69b-a45d-337892871d89.png)

参考マニュアル

https://docs.unity3d.com/ja/2021.2/Manual/com.unity.live-capture.html

## アバターのセットアップ

HANA_Toolでブレンドシェイプを追加したプレファブを開き、プレファブモードに入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/cefb4250-47a7-0722-dc4a-2b9a83ce0583.png)


### ARKit Face Actorコンポーネント

ARKit Face Actorコンポーネントをアタッチします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/40935fdb-8b9d-d720-b3e8-9f947d595d29.png)

### FaceMapperアセットの作成

FaceMapperアセットを作ります。プロジェクトウィンドウで右クリックして、Create > Live Capture > ARKit Face Capture > Mapper

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/b4557b40-9592-97fd-22cf-f113a8e1474b.png)

作成されたFaceMapperを選択してインスペクターを見ると、何か選択するところがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/3e3a8234-dadd-e1f3-0d14-ccdde47ca5ed.png)

ここにいま編集中のプレファブを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/ae375ce2-f6fc-b93f-773f-06bddeed6148.png)

こんな感じで項目が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/0ae8dfda-edd3-9aef-9ca0-0d8fc84b511c.png)


### FaceMapperの設定

EyesとHeadの設定。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/e40833c6-d3a1-49d1-dd4e-d6ce53890d7f.png)



次にAdd Rendererを押すと、Faceという項目が出るのでこれを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/02dc9ba5-5066-3e5f-7414-a10279d99077.png)

（プレファブ内のSkinned Mesh Rendererの中からBlendShapesがあるものがリスト表示されると予想）

自動的に検知してくれて、いい感じにいろんなブレンドシェイプがマッピングされていきます。手動でいろいろカスタムすることもできそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/1f85ef0a-6040-385d-50df-59d2c13961bc.png)

#### 作成したマッパーをセット

最後に、ARKit Face ActorコンポーネントのMapperの欄に、作ったFaceMapperアセットをセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/e73b8b77-7765-5f6c-cdd6-d31d7765737b.png)

#### ヒエラルキーに配置

プレファブモードを解除します。

アバターのプレファブをヒエラルキーに配置します。既にしてるかも。

## iPhoneからのフェイスキャプチャの情報を受信するためのセットアップ

### Take RecorderコンポーネントとARKit Face Deviceコンポーネント

まずは任意のゲームオブジェクトにTake Recorderコンポーネントを付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/014d4e84-23ba-d2f2-1d67-d65bc2b4a4da.png)

Playable Directorも一緒にくっついてきます。（今回は使いません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/a1dd8ba3-b5f3-d8e3-e0ee-e62463558b95.png)

Take Recorderの子オブジェクトに、ARKit Face Deviceコンポーネントを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/4716c308-2b4e-ab71-4838-0d8e696b571b.png)

Actorのところには、ヒエラルキー上に配置したアバターをセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/a79b589a-2a1c-20d7-f666-bbcc6a599aa8.png)

先ほど作った２つのコンポーネントはこのような親子関係になってると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/4cd7e924-9155-da2f-84b9-d470d73a617d.png)

Take Recorderの方を見ると、Capture Device欄で子要素を自動的に検知しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/4f0a0730-c232-1cf7-0569-4b140b6d2b3c.png)

なので、親子関係はTake Recorder > ARKit Face Deviceの順になってなければなりません。

### iPhoneから接続するサーバーの立ち上げ

メニュー > Window > Live Capture > Connections

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/3fe9f5e0-a8e9-0c65-32b8-a1e3809dbb15.png)

Connectionsウィンドウが表示されますので、まずはConfigure Firewallをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/b5e3dc85-0256-5bbc-16d2-78af9611101d.png)


後でWindows Defenderファイアウォールの詳細設定をのぞくいたら、それらしき設定ができていました。

次に、Create Serverをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/9a879b05-7bde-45b1-1a16-938acd61fabf.png)

# 動作確認（飛ばしてもいい）

この状態で、フェイスキャプチャの動作確認をすることができるようになりました。

iPhoneでUnity Face Captureアプリを立ち上げ、Unityでプレイを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/f1e9d864-a218-aad8-1cb2-bc1b2879295f.png)

iPhone側でConnectボタンが青くなって押せるようになるので、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/302eb599-ed8d-6b12-8af0-4f5e26c0b816.png)

Connectを押すとUnityと接続されます。

iPhoneの方にはインカメラの映像が表示されます。
（Client not Assignedって出ますが、Unityの方では反応していて使えてるのでこのまま使ってます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/906b542d-5cde-79e9-1444-a05ee57074d4.png)


Unityを見ると、アバターが動いていることと思います。
（この手順そのままだとTポーズとかになってるかも）
（もしかしたら首だけ飛んでいって大変なことになってるかも）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/932f3db2-f18a-3e50-7142-51f801cb5bb2.png)

首が飛んで行った場合は、ARKit Face ActorでHead Positionのボタンをオフにすると解消するかも

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/8e82f16a-9c37-9236-2040-a6cf4a6da1f1.png)


# 仮想Webカメラの設定

フェイストラッキングができたので、あとはUnityの映像をライブ配信などのソフトに送る必要があります。

手短なのはUnityのゲームウィンドウを最大化して、デスクトップキャプチャなどをすることです。

しかしそれではデスクトップで他のアプリの表示などができなくなりますので、ここは仮想Webカメラに出力できるようにしようと思います。

## 仮想カメラをインストール

Spoutをインストールします。

https://spout.zeal.co/

Spoutのサイトに行って、Downloadをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/d204fdc6-010e-9cde-1fd0-e595d33a0245.png)

ここからちょっと記憶があいまいですが、確かSpoutCamだけインストールすればよかったような。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/d95fca0d-ab5f-9a42-f550-a04b3f589ac3.png)

Zipの中はこんな感じになっているのですが、わかりやすいインストーラーなどはありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/644609ea-f19a-ce8c-fff9-c9373fbc3373.png)

ここも記憶があいまいなので詳しくはreadme.txtを読んでほしいのですが、SpoutCam32またはSpoutCam64のなかにある_register_run_as_admin.batを実行（管理者として実行が必要かも）するとインストールされます。

## Unityから映像送信

そして、インストールした仮想カメラにUnityから映像を送らなければなりません。

以下のライブラリを使います。

https://github.com/keijiro/KlakSpout

### インストール

README.mdにあるHow to installに従って、`Packages/manifest.json`を編集していきます。

### レンダーテクスチャ作成

プロジェクトウィンドウで右クリックCreate > Render Texture。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/cce8e204-fd2f-6ed1-86b2-2025da5d33be.png)

インスペクターで解像度などを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/1f5ce8fc-ab94-a8b1-511f-1d023a6f4777.png)

### カメラ

ヒエラルキーにカメラを追加して、Target Textureに先ほど作成したレンダーテクスチャを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/3d27bbeb-7ccb-77ac-5c6b-a64730b7266e.png)

### Spout Senderコンポーネント

ヒエラルキー上の任意のゲームオブジェクトに、Spout Senderコンポーネントを付け、Source Textureに先ほど作成したレンダーテクスチャを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/e3815dd9-7168-566a-8ec2-aa713b8d8941.png)

※書いてて見つけたんですが、Capture MethodをGame ViewもしくはCameraに設定したほうが、レンダーテクスチャも要らず、かつお手軽かもしれない。


## OBSなどでウェブカメラを選択して表示する

SpoutCamをインストールすると、Webカメラとして選択できるようになりますので、OBSなどの配信ソフトで表示するもよし、DiscordのWebカメラとして使うもよし。

OBS Studio

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/22311449-bde5-c823-72d8-8a3b79802ead.png)

Discord

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/16848320-811f-0639-4bea-d29239e69fd1.png)

あとは如何様にも。OBSで録画するもよし、Discordで通話するもよし。

# おわりに

以上で手順は終わりです。

（再掲）完成動画

https://youtu.be/4m4qByr0PRM

だいぶ手順が長くなってしまいました。

こちらのビデオとかも参考にするといいかもしれません。

https://learning.unity3d.jp/8266/

また、パーフェクトシンク対応のアバターなんかは、最初から必要となるブレンドシェイプが入ってたりするので、それを使うこともできます。

Boothにて検索すると、けっこうヒットします。

https://booth.pm/ja/browse/3D%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC?q=%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88%E3%82%B7%E3%83%B3%E3%82%AF

ちなみに、背景には以下のアセットを使いました。

https://assetstore.unity.com/packages/3d/environments/japanese-hotel-room-193482

あとはFinal IKなんかを使ってアニメーションとブレンドしたりしているのですが、それはまたいつかの機会に。

それでは