- 概要
- 開発環境の整備
- コントローラを使う
- GvrEventSystemを使う
- ハマったこと
- ポイントした先にワープするとポインタが正常に動かなくなる
- AndroidアプリのDaydreamコントローラエミュレータで実機アプリを動かす
- フレームレートが出ない
- HDRが有効にならない
- プロファイリング
- ファイル保存
- 有用リンク
概要
Daydream開発を始めてみたので、色々とメモしていきます。
基本的に気づきベースなので、随時更新していきます。
開発環境の整備
開発環境が整わないと色々と大変なので、Tips的な部分をメモ。
adbをWi-Fi経由で実行する
Daydream開発をしていると、実機インストール→Daydreamデバイスで見る、を繰り返すため、USB接続でやっているととてもめんどくさいです。
しかし、adb
にはWi-Fi経由でコマンドを実行する方法が用意されています。
まず、USBで一度Android端末とPCを接続します。
コマンドプロンプトから以下のコマンドを実行することで、以後はWi-Fi経由でコマンドを実行し、ケーブルレスでapkのインストールなども可能になります。
$ adb tcpip 5555 $ adb connect xxx.xxx.xxx.xxx
xxx.xxx.xxx.xxx
はAndroid端末のIPアドレスです。
接続を解除するには以下のようにします。
$ adb disconnect
コントローラを使う
Daydream Viewには標準でコントローラが付属しています。
そしてDaydreamアプリはコントローラを認識しないと起動しないので、必然的にコントローラが必須となります。
アプリ内でコントローラを利用するにはGvrController
クラスが提供するプロパティを利用します。
ドキュメントはこちら(Controller API Basics)
コントローラの状態を知る
ドキュメントから引用すると、以下の状態を知ることができます。
Buttons
The controller reports the following button properties:
- ClickButton: True if the Click button (a touchpad click) is currently being pressed.
- ClickButtonDown: True for 1 frame after user starts pressing the Click button.
- ClickButtonUp: True for 1 frame after user stops pressing the Click button.
- AppButton: True if the App button is currently being pressed.
- AppButtonDown: True for 1 frame after user starts pressing the App button.
- AppButtonUp: True for 1 frame after user stops pressing the App button.
GvrEventSystemを使う
Google VR SDKから、イベントシステムを利用した、各種イベントの制御の方法が提供されています。
といっても、独自のものはIGvrPointerHoverHandler
のみで、それ以外は通常のuGUIで提供されているインターフェースを実装することでイベントをトラッキングすることができるようになっています。
(例: IPointerClickHandler
など)
ハマったこと
いくつかハマったことをメモとして残しておきます。
Single Passレンダリングを利用すると色味がおかしくなる
色々な最適化方法を参考に設定を行っていたところ、Single Passレンダリングを有効化して実機確認したところ、色が反転するような現象が現れました。
結論から言うと、Use 32bit Display Buffer
をオフにしていると起こるようです。
Daydreamコントローラの感度が悪い
開発をしていて、しばらくしたらどうも「Daydreamコントローラの感度が悪いな・・」と思うことが何度かありました。
いろいろ調べてみると以下の投稿を発見。どうやら、充電がなくなると精度が悪くなるようです。
なので、充電に気をつけて、できるだけフル充電状態で開発ができるようにしておくとよさそうです。
Playerにコライダを設定したらイベントが動作しない
GvrEventSystem
に則ってイベントを処理していて、とあるタイミングでPlayerにコライダを設定したところ、コントローラのRayが自身にヒットしてしまって一向にオブジェクトに反応しない、ということがありました。
冷静に考えればRayCastなので当たり前ですが、仕組みがそもそもどうやっているのかを把握していなかったので若干ハマりました。
GvrPointerPhysicsRaycaster
クラスに、eventMask
というプロパティがあるので、それにマスクを設定しておけば大丈夫です。
例:
GvrPointerPhysicsRaycaster raycaster = GetComponentInChildren<GvrPointerPhysicsRaycaster>(); int playerLayer = (1 << 8); raycaster.eventMask = ~playerLayer;
ポイントした先にワープするとポインタが正常に動かなくなる
これも理由は上記と同じなのですが、ワープポイントみたいなオブジェクトを作り、それにコントローラで選択させて、決定時にその場所までワープする、みたいなことは比較的やる処理かなと思います。
ただ気をつけないとならないのは、ワープポイントの場所に移動させると、(実装の仕方によっては)コライダの中に入ってしまい、結果そのオブジェクトにコントローラのポインタが取られ続けてしまう、という問題があります。
自分の実装では、プレイヤーがワープポイントにいる間はRaycast向こうなレイヤーに変更し、別の場所に移動したら戻す、ということで対処しました。
AndroidアプリのDaydreamコントローラエミュレータで実機アプリを動かす
Daydreamは、専用コントローラを関連付けないと起動ができません。
(コントローラを認識してね画面から先に進まない)
とはいえ、現状は日本での発売がなく、せっかくDaydream対応端末を買ってもDaydreamコンテンツを楽しむことができません。
そこで、Android上で実行できる、コントローラのエミュレータを使います。
エミュレータはこちらからダウンロードすることができます。
基本的にはPC(開発機)に接続して開発用途として使うものになります。
が、やはり実機での確認は必須。
ということで、これを実機でも利用できるように設定します。
手順としては、
- Daydreamアプリを実行するAndroid(実機)と、コントローラ用AndroidをBluetoothでペアリングしておく(これはDaydream関係なく普通に設定から行う)
- Daydreamアプリ側で、GoogleVR設定画面から「ビルド」を複数回タップして開発者メニューを表示する
- 開発者メニューから、コントローラのエミュレータを有効化する
- (3)のタイミングで、どのAndroid端末のエミュレータを利用するかリストが表示されるので、(1)で同期した端末を選択する
という流れで行います。
無事に接続が完了すると、エミュレータ画面で「Connected」表示になるので、あとは普通にDaydreamアプリを操作することが可能になります。
フレームレートが出ない
開発をしていて、Physicsを利用してすばやく動かしたオブジェクトがやたらブレて見える現象がありました。 野生の漢さんの記事で書かれている、FixedUpdate周りかなと思って色々やってみたものの変化なし。
そして色々調べていたところ、以下の記事を発見。
https://forum.unity3d.com/threads/best-practice-project-settings-for-daydream.438598/
ここで書かれている以下の項目にしたところだいぶ軽くなりました。
- Enable 2x Anti Aliasing. (Unity will issue a warning about performance when you build, but it performs fine and looks bad without it.)
- Disable real time shadows. (They look bad and kill performance.)
- Disable "Use 32-bit Display Buffer"
- Stick with Forward or Vertex rendering
- Enable Multithreaded Rendering
- Enable Static and Dynamic batching
HDRが有効にならない
Post Processing Stackを使っていて、Bloomが有効にならないなーと思ったら、そもそもHDRが有効になってなかったというオチ。
Graphics Settingsを見てみると、Androidの場合はuse HDR
がデフォルトではオフになっているのが原因。それをオンにしたら普通に動きました。
このへんで言及されてるやつ。
プロファイリング
プロファイリングするにはいくつかのツールがあります。
一番シンプルなのは、ビルトインの内部プロファイラを利用することだと思います。(が、なぜかAndroidでこれが出力できなかった( ;´Д`))
ただ、色々試したのでメモしておきます。
adb logcatでログを出力
AndroidをPCに接続して、以下のようにコマンドプロンプトから実行すると、ログがだーっと出力されます。
$ adb logcat
ただ、これだとAnroid上で実行されているすべてのアプリやシステムのログがすべて出力されてしまうので、Unityだけに絞ります。
具体的には、
$ adb logcat Unity:V *:S
Unity
部分がタグで、V
がVerbose
の略、*:S
は、Unityとタグが付いたもの以外のログをすべてSilent
にする、という指定です。
これで無事、Unityタグがついたログだけがフィルタリングして出力されるようになります。
ファイル保存
セーブデータなど、ファイルを保存するには保存先パスを指定する必要があります。
保存先パスとしてはApplication
クラスから取得できる以下のパスを利用します。
Application.dataPath
アプリケーションが保存されているパス。
環境 | 取得パス |
---|---|
Android(本体) | /data/app/<アプリのID>.apk |
Android(SDカード) | /mnt/asec/<アプリのID>/pkg.apk |
iOS /var/mobile/Applications/****/myappname.app/Data |
Application.persistentDataPath
永続的なデータを保存するパス。 ユーザーデータなど、アプリが再生成できないファイルを配置する。
環境 | 取得パス |
---|---|
Android(本体) | /data/data/<アプリのID>/files/ |
Android(SDカード) | /mnt/sdcard/Android/data/<アプリのID>/files/ |
iOS | /var/mobile/Applications/****/Documents |
apkに含まれているManifestの内容を確認する
Daydream向けアプリでは、いくつかの機能の有効化などをManifestに記載する必要があります。
その際、実際にビルドしたapkに該当の項目がしっかり含まれているか、というのを確認したいケースがあります。
それを行うには、aapt
というツールがあるので、それを利用します。
(aapt
は、apktools
に含まれています)
コマンドは以下のように実行します。
$ aapt l -a hoge.apk
すると、ダーっと色々な情報が出力され、その中にマニフェストの内容も含まれているので、それで内容を確認することが出来ます。
詳細はこちら
参考
logcat コマンドライン ツール | Android Developers