SEED Stage および LEAP Stage での展示において効率化を図るために以下のような展示用ユーティリティを作成し、活用した。
このユーティリティでは複数のQuestに対して以下の操作を行える。
これらの操作をQuestを装着することなく行えることで、展示にあたっての手間を大幅に削減することができた。
なお、ユーティリティのコードは mirroring-tool
のブランチで管理しているのでコード全文はそちらから。
本ツールではいくつかのソフトやツールを利用している。
またミラーリングや近接センサを扱う部分については、リーダーが個人的につくっているミラーリングツールを基にしている。
PCに接続した Android デバイスに対して様々な操作を行える開発者用ツール。いろいろできる。
例えば Android 端末にアプリをインストールしたいときは、コマンドプロンプト (Macならターミナル) を開いて adb install [apkファイルのパス]
と実行すれば、Android 端末を一切触らずにアプリのインストールができる。
(ちなみにコマンドプロンプト/ターミナルにapkファイルをD&Dすれば勝手にパスを入れてくれるので楽)
基本的に adb
で書き始めればいいが、複数のデバイスが接続されているときはその端末のシリアル番号を指定して実行しないと怒られる。 adb -s[シリアル番号]
のように始めよう。
adbコマンドでできることをたくさんまとめてくれているサイトがある。
Android デバイスの画面をPC上にミラーリングしたり、PC上で操作したりできるソフト。内部的には一部 adb の仕組みをつかっているらしい。
展示用ユーティリティでは Quest の画面をミラーリングする部分に用いた。
ところで、Quest 3 のスクリーンは以下のように左右が傾いて配置されているため、そのままミラーリング&クロップすると斜めの映像になってしまう。そこでこれを回転させて表示させたいのだが、制作時点 (2024年9月) の scrcpy では、画面を傾ける機能は提供されていない。(90度単位での回転は可能)
そこで、有志が開発中の機能を開発者の rom1v 氏に紹介してもらい、こちらを用いることで Quest 3 や Pro に合わせた傾き補正を行うことができた。
Python のGUIライブラリのひとつ。
Flutter という Google が開発したオープンソースのUIソフトウェア開発キットを基にしており、クロスプラットフォームのアプリケーションを作成できる。
今回は Windows 上でコマンドを実行するためのGUIを作成する目的で利用している。
本ツールの動作は大きく以下のように説明できる。
adb devices -l
でPCに接続された Android端末 (Quest を含む) を取得し、「名前 (シリアル番号)」の形でリスト管理各種コマンドの中身については次のとおりだ。
scrcpy -s [シリアル番号]
というコマンドだけで画面全体のミラーリングを行うことはできる。ここに、GUIで設定したオプションを追加したコマンドを実行する。
具体的には以下のようなオプションが追加される。
--no-audio
や --no-video
を追加--crop=Xサイズ:Yサイズ:X開始位置:Y開始位置
--crop=1450:1450:140:140
--crop=2000:2000:2000:0
--crop=2000:2000:1800:0
--rotation-offset=角度
-20
--scale=拡大率%
132
、Pro では 125
--position-x-offset=X補正サイズ
(yも同様) (以下 (x,y)
で記載)
(-170, -125)
、Proでは (-120, -160)
-b ビットレート
で指定する
-b 20M
と記載すれば 20Mbps になる、これくらいがおすすめ。大きくしすぎると映像はキレイになるがラグがひどくなる。-m サイズ
で指定する
--window-title=タイトル
で指定する。複数ミラーリングするときにゴチャつかないように「端末名 (シリアル番号)」をつけておくと便利。このようなオプションが追加され、最終的なコマンドは例えば以下のようになる。
scrcpy -s XXX12345 -m 1024 --window-title="Quest 3 (XXX12345)" --no-audio --crop=2000:2000:2000:0 --rotation-offset=-20 --scale=132 --position-x-offset=-170 --position-y-offset=-125
長い。こういうのを手打ちとかコピペの必要なくGUIでポチポチしておくだけでいいので楽ですね。
ゲームの操作は、実はこちら側の実装というよりは Unity 側の実装を基にしている。
開発時にPCでデバッグするために Unity 側で用意していたキーボード入力操作を Android でエミュレートしているに過ぎない。
ということでキー入力を送信するだけなので、adb -s [シリアル番号] shell input keyevent [キーコード]
のコマンドを実行する。
例えばキーボードの “A” の入力を送信したいときは adb shell input keyevent KEYCODE_A
を実行すれば、Android で動いているゲームアプリ内で “A” が押されたことになる。
キーコードの一覧はAndroid の開発者ページにまとまっている。
なお本ツールでは、これを簡単に実行するための関数として send_key_event(key_code)
を定義しておき、引数としてキーコードを渡すだけでコマンドを組み立てて実行してくれるようにしている。
adbは通信はUSBによる有線接続のほかに TCP/IP による無線通信もサポートしている。USBケーブルを挿すのが面倒なときにおすすめ。
まず、無線接続したい Android 端末をTCPモードに切り替える必要がある。ポート番号として慣例的に 5555 を使うらしい。
adb -s [シリアル番号] tcpip 5555
次に、TCPモードが有効になった端末に対してIPアドレスとポート番号を指定して接続する (これがUSBケーブルを挿すことと同義になる)
adb connect 192.168.XXX.YYY:5555
なお、端末のIPアドレスを確認するのが面倒なので、コマンドで引っ張り出している。
adb -s [シリアル番号] shell ip route
を実行すると、
192.168.0.0/24 dev wlan1 proto kernel scope link src 192.168.XXX.YYY
のように返ってくるので、これの標準出力から正規表現を用いてIPアドレスの部分だけを吐き出すようにしている。実装は以下のとおり。
result = subprocess.run([adb, "-s", serial_number, "shell", "ip", "route"], capture_output=True, text=True)
output = result.stdout
ip_match = re.search(r'src (\d+\.\d+\.\d+\.\d+)', output)
if ip_match:
return ip_match.group(1)
Quest には装着状態を判定する近接センサ (Proximity Sensor) が内蔵されている。
(レンズの中間上部にあるところを指で塞ぐと画面が点くのがわかるとおもう)
これを無効にすることで、装着していないときも画面を点灯させることができ、ミラーリング画面が黒くならない。もちろんバッテリー消費も激しくなるので扱いには注意。
近接センサを無効にする (装着していないときも点灯させる) ときは adb -s [シリアル番号] shell am broadcast -a com.oculus.vrpowermanager.prox_close
有効にするときは adb -s [シリアル番号] shell am broadcast -a com.oculus.vrpowermanager.automation_disable
センサは Quest 側で任意に切り替えられないので、ミラーリング終了時などにソフト側で適切にセンサが有効に戻るようにしている。一応 Quest を再起動すれば戻るらしい。
アプリのパッケージ名とクラス名をつかってアプリの起動や終了ができる。
adb shell pm list package
でインストールされているアプリを一覧で出力してくれる。
あるいは Unity で任意に設定もできる。方法は Edit > Project Settings > Player
から Company Name と Product Name に設定した文字列がそのままパッケージ名になる。例えば Company Name を hogehoge
、Product Name を MyProject
とした場合は com.hogehoge.MyProject
がパッケージ名になる。
よくわからん。AndroidManifest.xml ファイルに activity android:name="hogehoge"
として載ってるらしい?
Unity 製のアプリならたぶん標準で com.unity3d.player.UnityPlayerActivity
になるとおもうのでこれを使ってる。
これらのパッケージ名/クラス名を用いて、アプリを起動する際は adb -s [シリアル番号] shell am start -n パッケージ名/クラス名
、終了する際は adb -s [シリアル番号] shell am force-stop パッケージ名/クラス名
のコマンドを実行する。