メインコンテンツまでスキップ
バージョン: 1.0.4

MiRZAで見えている映像をスマホに投影

WARNING

本ページに記載の環境は本記事執筆時点(2024/12/5)のものです。
アップデートによって変更が生じている可能性がある点ご留意ください。

0. はじめに

MiRZAとは、NTTコノキューデバイスから2024年10月16日に発売された6DoF対応のXRグラスのことです。(MiRZAの詳細についてはこちら

MiRZAで見えているものはMiRZAを装着していない人からは何も見えないため、外から何が見えているか確認したいケースが多々あります。

そこで、MiRZAがスマホとセットで動作するデバイスであるというのを活用し、MiRZAで見えている映像をスマホに投影する機能の実装方法についてご紹介します。

1. 開発環境

  • Windows 11
  • Unity 2022.3.27f1
  • Snapdragon Spaces SDK 0.23.2

2. 実装手順

2-1. Snapdragon Spaces SDKのセットアップ

こちらを参考にSnapdragon Spaces SDKをUnityに導入します。

これにより、MiRZAで動くアプリを作成することができます。

2-2. Dual Render Fusionのセットアップ

こちらを参考にDual Render Fusion(以降、DRFと呼称)をセットアップします。

これにより、Unityからスマホ画面のUIの実装が可能になります。

2-3. Camera Frame Access機能の有効化

こちらを参考にCamera Frame Accessの機能を有効化します。

これにより、MiRZAのカメラにアクセスすることができるようになります。

2-4. Unityシーンの作成

以下のシーンファイルをコピーして、任意の名前にリネームします。

本シーンはDRF向けにコンポーネントが整備されており、こちらを流用すると簡単にDRFを使用したアプリが作成可能です。

Assets/Samples/Snapdragon Spaces/0.23.2/Fusion Samples/Scenes/ControllerPrefabSampleScene.unity

2-5. AR Camera Managerコンポーネントの追加

AR Camera ManagerコンポーネントをMainCamera(AR Setup > AR Session Origin > AR Camera)にアタッチします。

これにより、カメラアクセスのサブシステムが有効になり、デバイスから有効なセンサー情報を取得します。

2-6. スマホ画面投影用のカメラ設定

スマホ画面投影に使用するカメラであるHost ViewのGameObjectをAR Setup > AR Session Origin > AR Camra配下に配置し、Environment Setup > Render Cameraは不要なので削除します。

※Host ViewのCameraコンポーネントのTarget EyeがNoneになっていることを確認します。ここがNoneになってないと、アプリが正しく動かないため注意が必要です。

2-7. スマホ画面のUI作成

シーン直下のFusion Interactionを非表示にし、UI > CanvasをPhoneCanvasという名前で新規作成します。

Canvas Scalerコンポーネントの以下のように設定します。

作成したCanvas配下にUI > Raw Imageを作成し、Rect Transformを以下のように設定します。

シーン直下のFusion Scene ManagerのFusion Screen Setupコンポーネントを以下のように設定します。

これにより、スマホ画面を横向きで使用する設定ができます。

2-8. カメラフレームデータの取得処理

シーン直下に空のGameObjectをCameraFrameAccessControllerという名前で作成します。CameraFrameAccessController.csという名前でスクリプトを新規作成し、そのGameObjectにアタッチします。

CameraFrameAccessController.csは以下のように記述します。このスクリプトで、カメラフレームを取得し、リアルタイムで画面に表示する処理を行っています。

using System;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

namespace NTTQONOQ.CameraFrameAccess
{
public class CameraFrameAccessController : MonoBehaviour
{
[SerializeField] private ARCameraManager m_CameraManager;
[SerializeField] private RawImage m_CameraRawImage;

private Texture2D _cameraTexture;
private XRCpuImage _lastCpuImage;

private void Start()
{
if (Permission.HasUserAuthorizedPermission(Permission.Camera))
{
Debug.Log("カメラ権限は既に許可されています。");
}
else
{
Permission.RequestUserPermission(Permission.Camera);
}

if (m_CameraManager != null)
{
m_CameraManager.frameReceived += OnFrameReceived;
}
}

private void OnFrameReceived(ARCameraFrameEventArgs args)
{
if (m_CameraManager.TryAcquireLatestCpuImage(out _lastCpuImage))
{
UpdateCameraTexture(_lastCpuImage);
}
}

private unsafe void UpdateCameraTexture(XRCpuImage image)
{
var format = TextureFormat.RGBA32;
var conversionParams = new XRCpuImage.ConversionParams(image, format);

if (_cameraTexture == null || _cameraTexture.width != image.width || _cameraTexture.height != image.height)
{
_cameraTexture = new Texture2D(image.width, image.height, format, false);
}

var rawTextureData = _cameraTexture.GetRawTextureData<byte>();
try
{
image.Convert(conversionParams, new IntPtr(rawTextureData.GetUnsafePtr()), rawTextureData.Length);
}
finally
{
image.Dispose();
}

_cameraTexture.Apply();
m_CameraRawImage.texture = _cameraTexture;
}

private void OnDestroy()
{
if (m_CameraManager != null)
{
m_CameraManager.frameReceived -= OnFrameReceived;
}
}
}
}

CameraFrameAccessControllerコンポーネントに、以下のように参照をつけます。

  • Camera Manager : AR Setup > AR Session Origin > AR Camera
  • Camera Raw Image : PhoneCanvas > RawImage

2-9. 完成

8の手順までで、MiRZAで見えている映像をスマホに投影する実装が完了したので、APKをビルドして、MiRZAで確認してみた結果が以下になります。

キャプチャの都合上、スマホ画面が白飛びしてるので分かりづらいと思いますが、MiRZAで見えている映像をスマホ画面にも投影できています。

3. まとめ

Spaces SDKの機能を駆使することで、MiRZAで見えている映像をスマホに投影できるようになりました。

この機能を活用することで、色々なシーンでMiRZAが活躍しそうですね。