Meta Quest 3でついにカメラアクセスができるようになりました。Meta社がすでにサンプルプロジェクトをGitHub上に公開してくれていますが、便利に利用できる分だけ肉厚になっています。実際には権限付与とWebCamTextureを利用するだけで使えるので、必要なところだけを抜き出し、他で利用したいときなど、何を使っているかわかりやすいようにしてみました。
前提
- Unity 2022.3.58f1
- Passthrough APIはUnityのバージョンがかなり重要です。初めて試すときはこのバージョンで試しておいたほうが無難です
- Meta XR All-in-One SDK 74.0.3
使い方の前に
Unityプロジェクトはこちらで公開しています。細かい点でわかなかればcloneして確認してみてください。
使い方
- パススルーが使えることが前提になっているのでこちらの手順を元にパススルーを設定します。
- AndroidManifest.xmlに
<uses-permission android:name="horizonos.permission.HEADSET_CAMERA" />
を追加します - 以下コードを追加します。3.1、3.2で簡単な説明をして、3.3に全コードがあります。
-
権限周りの設定をAwakeでしています
if (!hasPermission) { var grantedPermissionCount = 0; var callbacks = new PermissionCallbacks(); callbacks.PermissionGranted += (permissionName) => { grantedPermissionCount++; hasPermission = grantedPermissionCount >= PERMISSIONS.Length; }; Permission.RequestUserPermissions(PERMISSIONS, callbacks); }
-
この5行でカメラにアクセスして、画像をUIに設定しています
var devices = WebCamTexture.devices; var deviceName = devices[0].name; var webCamTexture = new WebCamTexture(deviceName, 1280, 960); webCamTexture.Play(); output.texture = webCamTexture;
-
全コードはこちら
using System.Collections; using System.Linq; using UnityEngine; using UnityEngine.Android; using UnityEngine.UI; public class PassthroughAPIHelper : MonoBehaviour { private static readonly string[] PERMISSIONS = { "android.permission.CAMERA", "horizonos.permission.HEADSET_CAMERA" }; [SerializeField] private RawImage output; [SerializeField] private Text debugMessage; private bool hasPermission = false; private void Awake() { debugMessage.text = "権限の確認をして、なければリクエストを出します"; hasPermission = PERMISSIONS.All(Permission.HasUserAuthorizedPermission); if (!hasPermission) { var grantedPermissionCount = 0; var callbacks = new PermissionCallbacks(); callbacks.PermissionGranted += (permissionName) => { grantedPermissionCount++; hasPermission = grantedPermissionCount >= PERMISSIONS.Length; }; Permission.RequestUserPermissions(PERMISSIONS, callbacks); } } void Start() { StartCoroutine(InitializeWebCamTexture()); } private IEnumerator InitializeWebCamTexture() { debugMessage.text = "初期化を開始します"; #if !UNITY_6000_OR_NEWER debugMessage.text = "Unity2022のバグのため、WebCamTextureの初期化を1フレーム待ち中"; yield return new WaitForEndOfFrame(); #endif while (!hasPermission) { debugMessage.text = "権限の付与を待っています"; yield return new WaitForEndOfFrame(); } debugMessage.text = "パススルーをWebCam経由で設定します"; var devices = WebCamTexture.devices; var deviceName = devices[0].name; var webCamTexture = new WebCamTexture(deviceName, 1280, 960); webCamTexture.Play(); output.texture = webCamTexture; debugMessage.text = "初期化完了です"; } }
-
- PassthroughAPIHelper.csのアウトプットとしてRawImageとTextが必要なので、適当なCanvasを作成して設定してください。この例では左手にCanvasを持たせて、カメラが画像を見やすい状態にしています。
- 後はビルド、adb installして、Questで実行するだけです。うまくいけば↑の真っ白なRawImageのところに取得したカメラ画像が表示されるはずです。
補足
- 公式ドキュメントはこちら。Unityの前提バージョンや画像解像度など、諸々の仕様が記載されているので、細かいところはこちらを参照ください。
- MetaがすでにサンプルプロジェクトをGitHub上に公開してくれています。これには権限周りの取得(
PassthroughCameraPermissions.cs
)やWebCamTextureの取得などを簡単にできるようにラップしてくれているクラス(WebCamTextureManager.cs
)が含まれています。便利なのでこちらを流用すると楽です。