こんにちは!最近はリモートで仕事をすることが多くなったエンジニアの松下です。
リモートワークでZoomを使う際にVtuberみたいに相手に表示するアバターを変える機能を自分で好きに作りたいなと思ったのですが、Webカメラの表示をする際にUnityが落ちてしまうという問題に遭遇しました。
もしかしたら同じような人がいるかもしれないので備忘録的な意味も込めて共有します。
問題の箇所について
問題はmacOSのUnityで以下のようなコードでWebカメラにアクセスしたときにUnityごとクラッシュするというものです。OpenCVを使ってFaceTrackingしたかったのですが、思わぬところで躓いてしまいました。
using UnityEngine;
using System.Collections;
public class WebCamTest : MonoBehaviour
{
    void Start()
    {
        WebCamTexture webcamTexture = new WebCamTexture();
        Renderer renderer = GetComponent<Renderer>();
        renderer.material.mainTexture = webcamTexture;
        webcamTexture.Play();
    }
}
ちなみに発生時は以下のような構成で動作させてました。
・macOS Mojave 10.14.6
・Unity 2019.2.17f1
原因
調べたところ、いつからかmacOSのカメラやマイクにアクセスするためにシステム側で許可がいるようになったようです。
以下の箇所にカメラへのアクセスに関する表示があるかと思ったのですが、見当たらずUnityを再インストールしたりしてもアクセス権を追加するダイアログなどは出てきませんでした。
システム環境設定 → セキュリティとプライバシー → プライバシー 
解決方法
GUIからは操作できないようだったので、 ~/Library/Application\ Support/com.apple.TCC/TCC.db に直接Cameraへのアクセス許可情報を追加します。
ただし、これを操作するにはmacのシステム整合性保護 (System Integrity Protection: SIP) を一時的に無効化させる必要があります。macOSをリカバリーモードで起動させる必要があり、操作については自己責任でお願いします。
- 
macOSの再起動時に 「 cmd + R 」キーを長押ししたまま待ちます。 
- 
リカバリーモードでターミナルを開きます。   
- 
以下のコマンドでSIPを無効化させた後、macを再起動します。 csrutil disable
- 
ターミナルを開いてTCC.dbにアクセスします。 sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db
- 
Unityにカメラへのアクセス権を追加します。 INSERT INTO access VALUES('kTCCServiceCamera','com.unity3d.unityhub',0,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);もしマイクも必要であればついでに追加します。 INSERT INTO access VALUES('kTCCServiceMicrophone','com.unity3d.unityhub',0,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1541440109);service client client_type allowed prompt_count csreq policy_id indirect_object_identifier_type indirect_object_identifier indirect_object_code_identity flags last_modified TEXT TEXT INTEGER INTEGER INTEGER BLOB INTEGER INTEGER TEXT BLOB INTEGER INTEGER 追加する accessテーブルの構造は上記のようになっているようです。
 ただし手元にはmacOS HighSIerraの端末もあったので構造を見てみたのですが、policy_idより先のカラムが無く、OSによって構造が少し異なるかもしれません。
- 
システム環境設定 → セキュリティとプライバシー → プライバシーを確認します。
 カメラの項目にUnity Hubが追加されていることが確認できました。  
- 
再度macOSの再起動時に 「 cmd + R 」キーを長押ししてリカバリーモードで起動します。 
 ターミナルで以下のコマンドを入力してSIPを有効化して再起動します。csrutil enable
以上で手順完了です。
上手くいけばUnityからWebカメラにアクセスしても落ちることは無くなったと思います。
最後に
本当は以下のような構成でZoomにVtuberを登場させるところを記事の内容にしたかったのですが、思わぬところで躓きました…。
もし興味がある方はUnityのカメラ映像をSyphon(Windowsの場合はSpout)とCamTwistを使ってZoomに持っていけるので、チャレンジしてみてはどうでしょうか。1

参考
- 
CamTwistをカメラ入力の選択肢に追加すると、また別の原因でWebカメラ起動に失敗することもあるようです。その場合は一旦CamTwistを再インストールすると症状は無くなります。 ↩ 
