📑

MiRZAデバイス固有機能を利用できるMiRZA Plugin解説

2025/01/15に公開

MiRZA 固有機能を利用できるMiRZA Libraryが提供されています。

Snapdragon Spaces対応のMiRZAですが、ハードウェアとしての個別の機能をいくつか持っています。今回MiRZA固有の機能を使うためのライブラリが提供されたのでその詳細を調査しました。
なお、公式ドキュメントは以下にあります。

https://www.devices.nttqonoq.com/developer/doc/mirza-library/overview/

MiRZA Libraryは最近リリースされたものなのですが、まだバグであったり使い方がいまいちわかっていないものがありその部分は不明なままで今回は整理しています。
MiRZA Libraryはライブラリ自体がJavaのライブラリで、PluginはC#からJavaライブラリを呼ぶ形で構成されています。導入手順などは公式に書かれているのですが、Gradleの設定等はなくても動作しました。おそらくUnityプロジェクトがBuild.Gradleで設定している各種ライブラリのパスをLibs配下にしているようで、MiRZA Library個別に対応しなくても問題ないようです。

MiRZA Libraryでできること

MiRZA Libraryを使うとMiRZAデバイスのハードの情報を利用することができます。大まかな情報としては以下の通りです。

  1. バッテリー残量等ハードウェアの稼働に関する情報
  2. MiRZAデバイス右側のテンプル部分のタッチ操作に関する情報
  3. 搭載マイクの指向性変更
  4. MiRZAアプリへの遷移

この中では特にタッチセンサーが使えるようになるのが大きいと思います。UI操作の1つとしてアプリに組み込めるのは便利そうです。

MiRZA Libraryでもできないこと

一方でMiRZA Library使っても改善されない部分もあります。MiRZAのタッチ操作部分が使えるようになっているのですが、スクショ撮る機能は使えません。MiRZAはMiRZAアプリ起動中の時はスクショ撮ることができるのですが今回提供されている機能はタッチ操作の情報だけでスクショ撮る機能は提供されていません。また、以前から動画撮れないところも変わりはないです。作ったコンテンツを撮影する場合は「MiRZAの投影部分にフォーカス合わせて物理的にレンズ部分を撮影する」、「Dual Render FusionとCamera Frame Accessを使ってスマホの画面にARの合成映像を投影し、スマホの機能で撮影する」必要があります。
また、Javaライブラリをプロキシ経由でC#から呼ぶ設計上、幾つかの機能で正しい情報や処理が通らないバグっぽいものも幾つかありました。以降の記事ではその部分は注釈を入れています。

実装について

実装方法の基本的な話は公式にも公開されています。ただし、公開されている情報はJava言語のものでUnity上で使う時はこれらのプロキシクラスになっているC#のコードになります。そしてC#についてはMiRZA Libraryのサンプルコードを読み解かないとわからないのが現状です。

https://www.devices.nttqonoq.com/developer/doc/mirza-library/overview/#利用方法

基本的な実装方法は、最初にMiRZA Libraryのインスタンス化を(C#のプロキシクラス経由で)行い、その後各種情報を取得するためにモニタリングを開始します。モニタリング開始以降各種情報取得が可能になり、情報取得が不要になればモニタリングを終了します。
注意点としてはMiRZA Libraryの機能を利用はモニタリング中しかできないという事です。例えば、自分が作ったコンテンツからMiRZAアプリに遷移するために利用する機能もモニタリングを開始していなければ使えません。

基本的にMiRZA固有機能を利用したい場合はモニタリングは常に実施する必要があります

実装の最小限のイメージは以下のようになります。


public class Samlpe : MonoBehaviour {

  private MirzaPlugin mirzaPlugin;

  public void MiRZASamples() {
#if UNITY_ANDROID && !UNITY_EDITOR
    // ライブラリ初期化(Unity EDITOR上はエラーになるのでifディレクティブで対応)
    mirzaPlugin = new MirzaPlugin();
#endif

    // Logcatを出力
    mirzaPlugin?.SetLogEnable(true);

    //イベント定義(以下はバッテリ残量の監視用にイベントを登録)
    if (mirzaPlugin != null)
      mirzaPlugin.OnBatteryLevelChanged += OnBatteryLevelChangedInternalAction;

    // モニタリング開始
    mirzaPlugin?.startMonitoring(this);

    // 各種取得処理
    ....
        
    // モニタリング停止
    mirzaPlugin?.stopMonitoring(this);
  }
}

以降、この記事はその機能を使った時の挙動や取得可能は数値範囲などの情報を調査した内容を紹介します。

開発環境

今回は動作検証用にアプリを構築していたのですがその時の構成は以下の通りです。注意点としてはMiRZA Libraryを使うためにはスマホにインストールするMiRZAアプリを最新化しておく必要があるという事です。古いままだとエラーが出て処理ができません。

  • MiRZA アプリ v1.00.05~ (注:MiRZAアプリを最新化しないとこの機能は使えません)
  • Unity 2022.3.36f1
  • Snapdragon Spaces SDk v1.0.1
  • MiRZA Plugin V1.0.0

パッケージのインポート

以下のサイトからダウンロード可能です。

https://www.devices.nttqonoq.com/developer/library

Unity上で利用する場合は[Unityプロジェクトで錬会ライブラリをりようする際のサンプルコード]をダウンロードします。

このサンプルを含むパッケージをインポートするとJavaで作られたMiRZA LibraryのC#プロキシクラスとしてMiRZAPluginクラスを利用することができます。Unity上はこのクラスを介してMiRZA Libraryを利用します。

API仕様 - 概要

次にMiRZA Libraryで提供されるAPI仕様について紹介します。概要については公式にも情報はあるので参考にしてください。
ただし、内容はJavaのライブラリの仕様書なのでUnity上で使うC#プラグインについては以降を参考にしてください。

https://www.devices.nttqonoq.com/developer/doc/mirza-library/package

APIについては、情報の取得(メソッド呼出し、イベント制御)、設定、初期化/機能呼出があります。

情報の取得に関するAPI

情報取得に関しては都度情報を取るためのメソッドがGet~で同期/非同期で提供されています。

修飾子とタイプ メソッド 説明
Result<string> CheckVersionConsistency() バージョン整合性を確認する
Result<int> GetBatteryLevel() 電池残量を取得する
void GetBatteryLevelAsync(Action<Result<int>> onResult) 電池残量を取得する(非同期)
Result<ChargeStatus> GetChargeStatus() 充電状態を取得する
void GetChargeStatusAsync(Action<Result<ChargeStatus>> onResult) 充電状態を取得する(非同期)
Result<GlassStatus> GetGlassStatus() グラスデバイス状態を取得する
void GetGlassStatusAsync(Action<Result<GlassStatus>> onResult) グラスデバイス状態を取得する(非同期)
Result<SpacesModeStatus> GetSpacesModeStatus() MRモード状態を取得する
void GetSpacesModeStatusAsync(Action<Result<SpacesModeStatus>> onResult) MRモード状態を取得する(非同期)
string GetVersion() ライブラリバージョンを返す

また、値の変化に応じて発生するChangedイベントも用意されています。タッチセンサーのジェスチャーに関してはこちらの方が扱いやすいと思います。

修飾子とタイプ メソッド 説明
Action<int> OnBatteryLevelChanged 電池残量の変化に応じて発生するイベント
Action<DisplayStatus> OnDisplayStatusChanged 画面表示状態の変化に応じて発生するイベント
Action<GlassStatus> OnGlassStatusChanged グラスデバイス状態の変化に応じて発生するイベント
Action<GlassTouchGestureStatus> OnGlassTouchGestureStatusChanged グラスのタッチパネル操作情報の変化に応じて発生するイベント
Action OnPowerOffChanged グラス電源OFFの変化に応じて発生するイベント
Action<ServiceState> OnServiceStateChanged サービス状態の変化に応じて発生するイベント
Action<SpacesModeStatus> OnSpacesModeStatusChanged MRモード状態の変化に応じて発生するイベント

マイク設定に関するAPI

設定系はMiRZAのマイク関連の設定変更になります。最近のMiRZAのファームアップデートからマイク指向性を変更するための設定が追加されました。マイクの録音時にこの特性を利用してマイクから収音が可能になっています。

修飾子とタイプ メソッド 説明
Result<SwitchMicrophoneStatus> SwitchMicrophone(MicMode wearingMicMode, MicMode frontMicMode, MixMode mixMode) マイクモードの切替を実行する
void SwitchMicrophoneAsync(MicMode wearingMicMode, MicMode frontMicMode, MixMode mixMode, Action<Result<SwitchMicrophoneStatus>> onResult) マイク切替を実行する(非同期)

初期化/機能呼出

MiRZAの初期化、および機能呼出に関するAPIです。モニタリングの開始終了、ログ関連、MiRZAアプリへの遷移などがあります。

修飾子とタイプ メソッド 説明
void StartMonitoring() MiRZAアプリとの連携を開始する
void StopMonitoring() MiRZAアプリとの連携を解除する
Result<int> SpacesModeOff() MRモードを無効化する
void SpacesModeOffAsync(Action<Result<int>> onResult) MRモードを無効化する(非同期)
Result<int> SpacesModeOn() MRモードを有効化する
void SpacesModeOnAsync(Action<Result<int>> onResult) MRモードを有効化する(非同期)
Result<SpacesModeStatus> TransitionToMirzaAppInSpacesMode() MiRZAアプリへ遷移する
void SetLogEnable(bool enabled) ログ出力を変更する

各機能の詳細 - 情報の取得に関するAPI

次に各APIから取得できる情報が実際にどういうものなのかを解説します。

CheckVersionConsistency

バッテリー残量を取得 - GetBatteryLevelメソッド

バッテリ残量の取得はGetBatteryLevelメソッドを利用します。同期非同期の選択が可能です。
戻りあたりは0~100の値が返ります。
残量が変化した場合に処理を実行したい場合はOnBatteryLevelChangedイベントにメソッドを登録します。

グラスデバイス状態を取得する - GetGlassStatusメソッド

グラスとスマホの接続状態を取得にはGetGlassStatusメソッドを利用します。ChargeStatusクラスは接続状態として以下の情報を取得することが可能です。
接続状態が変化した際に処理を実行したい場合は、OnGlassStatusChangedイベントにメソッドを登録します。

  • BluetoothStatus
    MiRZAデバイスがスマホと接続できているかを確認できます。状態はConnected(0),Disconnected(1), Unknown(2)の3つの状態です。Bluetoothでの接続が確立されたあと、SpacesModeが利用可否と、Wifi接続の確認が行われます。
  • SpacesAvailable
    SpacesModeが使える状態にあるかどうかをboolで返します。
  • WifiStatus
    MiRZAデバイスがスマホとWifi接続できているかを確認できます。状態はConnected(0),Disconnected(1), Unknown(2)の3つの状態です。MiRZAはARコンテンツの映像についてはWifiを経由しているため、SpacesModeが利用可能な場合、Wifi接続が実施されます。

充電状態を取得する - GetChargeStatusメソッド

MiRZAが充電中かどうかを取得することが可能です。ChargeStatus.Onの場合、充電中の状態です。

MRモード状態を取得する - GetSpacesModeStatusメソッド

SpacesModeを取得します。SpacesModeとはMiRZAアプリが起動した状態でMiRZA上でARコンテンツを扱える状態を定義したもので、この値がOn(1)の場合、ARコンテンツとしてMiRZAに映像が表示されます。例えば、MiRZAをデバイスとして接続した状態だけでMiRZAアプリを起動していないもしくはSpacesModeOnメソッドを実行していない場合は、Offの状態になっています。この状態ではMiRZAには映像が投影されないので注意が必要です。
モードの状態変更時に処理を行いたい場合は、OnSpacesModeStatusChangedイベントにメソッドを登録します。

ライブラリバージョンを取得する - GetVersionメソッド

MiRZAライブラリのバージョンを取得します。

画面表示状態の変化に応じて発生するイベント - OnDisplayStatusChanged

MiRZAは電源ボタンを軽く押すと、ディスプレイが非表示/表示を切替えることが可能です。このディスプレイの変更を監視し何か処理を実行したい場合はOnDisplayStatusChangedイベントにメソッドを登録します。
イベントの引数にはDisplayStatus列挙体でディスプレイの状態を取得することができます。

DispayStatus列挙体

変数名 説明
ON ディスプレイON
OFF ディスプレイOFF

グラスのタッチパネル操作情報の変化に応じて発生するイベント - OnGlassTouchGestureStatusChanged

MiRZAにはテンプル部分にタッチセンサーが搭載されています。MiRZAメニュー選択等一部の操作においてこのタッチ操作を使っていますが、OnGlassTouchGestureStatusChangedイベントを利用することで、自作のコンテンツでもタッチセンサーを利用することが可能です。
おそらくこのライブラリで最もよく使う機能の1つだと思います。タッチセンサーはジェスチャーがいくつか用意されており、それらの状態をこのイベントから取得することが可能です。タッチセンサー周りの状態変化などについては後述します。
イベントの引数にはタッチセンサーの状態をGlassTouchGestureStatusクラスで取得できます。

GlassTouchGestureStatusクラス

変数名 説明
Movement タッチセンサーの操作方向
Operation タッチ操作の状態
Type タッチ操作の種類
XCoordinate タッチ位置の座標(x)
yCoordinate タッチ位置の座標(y)※常に0

グラス電源OFFの変化に応じて発生するイベント - OnPowerOffChanged

MiRZAデバイスの電源がOFFになった時に処理を実行することができます。必要な時はOnPowerOffChangedイベントにメソッドを登録します。バッテリー残量が0になりシャットダウンしたり、電源ボタンを長押しして電源をOFFにしたときにイベントが発生します。

サービス状態の変化に応じて発生するイベント - OnServiceStateChanged

MiRZA Libraryでモニタリングが正常に行えているかを検出することが出来ます。例えば、モニタリングを開始した後にMiRZA Library経由で情報取得を行いたい場合はこのイベントを利用します。
イベントの引数にはサービスの状態をServiceState列挙体で取得できます。

ServiceState列挙体

変数名 説明
Connecting 接続中
Connected 接続済み
Disconnecting 切断中
Disconnected 切断済み
ConnectionError 接続エラー
VersionInconsistent バージョン不整合

各種機能詳細 - マイク設定に関するAPI

公式サイトの記載ではMiRZAの12月のファームアップデートから利用できるようになったマイク指向性の機能に関する設定です。MiRZAに搭載されているマイクを使って4つのモードを切替えて録音することが可能です。

サイトより引用:マイクモードとは

マイクモードの切替を実行する - SwitchMicrophoneメソッド

マイクモードを変更する際に利用します。このメソッドはMiRZA Libraryをモニタリングした状態で利用する必要があります。引数に利用したいマイクモードを指定します。

MicMode

変数名 説明
OFF 指向性なし(通常)
Wearing 装着者の声のみ収音
Ambient 装着者の声を除いた周囲の音を収音
Front 装着者の声を除いたグラス前方の音を収音

MixMode

変数名 説明
On Wearing, FrontマイクのモードをMixする
Off マイクモードを単一で利用する

まだ、試験的な機能なのか以下のように利用には制約があるので注意が必要です。

各機能の詳細 - 初期化/機能呼出

MiRZAの初期化、および機能呼出に関するAPIです。モニタリングの開始終了、ログ関連、MiRZAアプリへの遷移などがあります。

MiRZAアプリとの連携を開始する - StartMonitoring

MiRZAライブラリを利用する為にモニタリングを開始します。MiRZAデバイスの情報を取得するためのこのライブラリを利用する最初に必ず呼び出す必要があります。

MiRZAアプリとの連携を解除する - StopMonitoring

MiRZAライブラリのモニタリングを終了します。

MRモードを無効化する - SpacesModeOff

MiRZAデバイスのMRモードを無効化します。MRモードはMiRZAをSnapdragon Spaces対応のスマホに接続した場合に利用できるモードです。MiRZAでARコンテンツを利用するモードになります。
無効化するとMiRZAは最小限のデバイス情報だけが表示された状態になります。

MRモードを有効化する - SpacesModeOn

MiRZAデバイスのMRモードを有効化します。このメソッドを呼び出せばMRモードを有効化できるようになります。自身で作成したARコンテンツ内の初期処理でこの処理を実行することでMiRZAアプリを経由せずにARコンテンツを表示できるようになります。

MiRZAアプリへ遷移する - TransitionToMirzaAppInSpacesMode

自身のアプリからMiRZAアプリへ遷移することができます。MiRZAアプリはランチャーとしても機能するメイン画面になるので、コンテンツ終了時にMiRZAアプリへ戻りたい場合はこのメソッドを呼び出します。

ログ出力を変更する - SetLogEnable

ログの出力設定を変更します。

タッチセンサーの制御

MiRZA Libraryでもよく使うと思われるタッチセンサーの制御について解説します。
MiRZAにはテンプル部分に以下のようなタッチセンサーが搭載されています。

MiRZA Libraryを使うとこのタッチセンサーのジェスチャー情報を取り出せるので自身のコンテンツで入力装置の1つとして利用することが可能になります。

ジェスチャーの種類

タッチセンサーは操作方法によっていくつかのジェスチャーを認識します。ライブラリではTouchType列挙体で定義されています。SwipeとMotionについては方向の情報も取得可能です。

TouchType
ToucuTypeはタッチセンサー上で行っているジェスチャーの種類を列挙体で表しています。

変数名 説明
Tap タッチセンサーを軽くたたくように操作するとタップとして認識します。
Swipe タッチセンサーに触れてから素早く前(or後)に動かしながら話すとSwipeとして認識します。
Motion タッチセンサーに触れながら前(or 後)に動かすとMotionとして認識します。

タップの種類やSwipeの方向についてはその詳細を示す列挙体が別に用意されています。

TouchOperation
TouchOperationはタッチセンサー上でどのジェスチャー操作を行なっているかを列挙体で表しています。

変数名 説明
Down タッチセンサーに触れた瞬間
Up タッチセンサーから指を離した時(例外あり)
Single 素早くタッチセンサーに触れる→離す(軽くたたくイメージ)
Double 素早く2回連続で素早くタッチセンサーに触れる→離す(軽くたたくイメージ)
Triple 素早く3回連続で素早くタッチセンサーに触れる→離す(軽くたたくイメージ)
LongPressInitial タッチセンサーを押す→離した時。タップよりも長めに触れるイメージ
LongPressRepeat タッチセンサーを押した状態をキープする(LongPressInitialから移行)
Move タッチセンサーに触れた状態で指を前後に動かしている間
Previous 素早くタッチセンサーに触れる→擦りながら前方向に動かす→離す
Next 素早くタッチセンサーに触れる→擦りながら後方向に動かす→離す

ジェスチャーのライフサイクル

実際にジェスチャー操作を行った時のOnGlassTouchGestureStatusChangedイベントから取得できるTouchTypeとTouchOperationの状態のライフサイクルは以下のようになります。

例えば、素早くタッチセンサーをたたく動作をすると一番左側のフローになります。最高で連続3回タップまで検知可能です。
タッチセンサーに触れた状態で前後に動かさない場合はLongPressとしてのフローに入ります。現状は押している時間の長さでLongPressInitial→LongPressRepeatへと遷移します。
最後にタッチセンサーをタッチしながら前後に動かすとMove状態になります。最後の移動方向に応じて最終状態としてNext,Previousで状態が終わります。

OnGlassTouchGestureStatusChangedイベント取得できる情報

タッチセンサーの状態はMiRZAライブラリのOnGlassTouchGestureStatusChangedイベントから取得します。このイベントはタッチセンサーに触れた時からセンサーの状態が変化している間は連続的に発生します。センサーの情報は引数で受け渡されるGlassTouchGestureStatusクラス経由で取得することが可能です。

GlassTouchGestureStatusクラス

変数名 説明
Movement int タッチセンサーの操作方向を表します。
Operation TouchOperation タッチ操作の状態
Type TouchType タッチ操作の種類
XCoordinate int タッチ位置の座標(x)
yCoordinate int タッチ位置の座標(y)※常に0

それぞれのプロパティで取得できる値の範囲は以下の通りです。

Movementプロパティ
タップした状態から少しでも前後に動かすとMove状態になります。この状態で前後方向に動かすとMovementは0以外の数値になります。一度Move状態になるとMove状態を解除しない限りは0以外の数値になるようです。例えば後→前の移動中に途中で止めてもMovementは1になります。また、この値は指の加速度に応じて数値が増減します。素早く前に動かすとその度合いに応じて数値が大きくなります。指の動きを止めると1に戻ります。

変数名 説明
1以上 後→前への移動。1以上の数値は指を動かす加速度
0 TypeがMove以外
-1以下 前→後への移動

Operationプロパティ,Typeプロパティ
タッチセンサーのジェスチャー操作に応じてどの操作を行っているか列挙体で取得できます。詳細は前述のジェスチャーの種類、ジェスチャーのライフサイクルを参照してください。

XCoordinateプロパティ
タッチセンサーのタッチ位置のX座標を返します。値の範囲は0-255です。相対位置ではなく絶対位置

YCoordinateプロパティ
タッチセンサーのタッチ位置のY座標を返します。このプロパティは常に0です。

Discussion