2020/8/10追記
追記ここまでAutoScreenhttps://t.co/1Udni4dqKa
— su10@ハイパーカジュアルゲーム開発 (@su10_dev) August 10, 2020
Unity2019.3以降でエラーが出続ける問題があったので修正してv1.0.1になりました。 https://t.co/eFXaZ4maJG
AutoScreen(GitHub)
はじめに
Unityにおけるセーフエリアの対応に関してはScreen.safeArea
というAPIがあるのですが、ビルドして実機で呼ばないと端末ごとの値が取れない=エディタ上ではレイアウトの確認ができないという辛さがあります。
最近だとUnite Tokyo 2019でも紹介されたDevice Simulatorが記憶に新しいところですが、このパッケージはUnity2019.3からでないと使用できず、まだプレビュー版となっています。
- 新機能「Device Simulator」でモバイル開発のイテレーションを加速させよう(Unity公式ブログ)
- 【Unity】Device Simulatorでノッチとセーフエリアの対策(テラシュールブログ)
個人的な感覚ではUnityはたとえLTS版であってもある程度時間が経つまでは本番で使用するのが怖いので、自分が実際にDevice Simulatorを使えるようになるのは2020年の後半になる気がしています。
そんなに待ってられないよ!ということでUniSafeAreaAdjusterをありがたく使わせてもらってたのですが
- 解像度に合わせて端末を選択するのが面倒
- 特に複数の
GameObject
にSafeAreaAdjuster
コンポーネントをつけてるとき
- 特に複数の
- デバイスのフレーム表示機能がほしい
- 手軽に対応端末を追加・拡張できるようにしたい
という気持ちがピークに達して自分でアセットを作ってしまったのでご紹介します。
便宜上「アセット」と書いてますがアセットストアに公開するのはけっこう面倒なのでGitHubでだけ公開しています。
↓↓↓↓↓↓↓
AutoScreen(GitHub)
READMEがまだないのですが、そのうち本記事を元に英語で書くと思います。
機能
- モバイル実機上でセーフエリアに応じて
RectTransform
のアンカーを自動調整するコンポーネント-
SafeArea
:セーフエリア用(適用したい方向を上下左右自由に組み合わせ可) -
UnsafeArea
:非セーフエリア用(上下左右どれか選択) -
RuntimeSafeAreaUpdater
:画面の回転を自動検知してSafeArea
,UnsafeArea
を更新
-
- エディタ上でセーフエリアをリアルタイムプレビュー
- 既存のGameウィンドウでセーフエリアあり端末の解像度を選択するだけ(追加作業なし)
- 再生/非再生の状態に関係なく即時反映
- on/off可能なオプション
- デバイスのフレームを表示
- セーフエリアの境界線表示
対応状況
- Unity2018.3以降対応(Device Simulatorは未対応)
- iOS:実機・エディタともに対応
- iPhone X/XS/11 Pro
- iPhone XS Max/11 Pro Max
- iPhone XR
- iPad Pro (第3世代, 11インチ)
- iPad Pro (第3世代, 12.9インチ)
- Android:実機のみ対応
Android端末のエディタプレビューは以下の理由でオミットしています。
- 個人的にAndroid端末にビルドする必要性がない
- フレーム画像と解像度・セーフエリアデータの収集に手間がかかる
- 対応が必要な端末数が多そう
端末のマスターデータの追加自体は簡単なので、必要に応じて後述の手順を参考に自分で足してください。
インストール方法
リポジトリ内に*.unitypackage
ファイルがあるのでこちらを使用してください。
使い方
とりあえず動作を確認してみたい場合はDemo
シーンを用意してあるのでいじってみたりビルドしてみてください。
セーフエリアの自動調整機能
Canvas
直下のGameObject
にSafeArea
/UnsafeArea
コンポーネントをAddComponent
するとRectTransform
のAnchor
が自動で調整されます。直下じゃなくてもCanvas
に至るまでの親GameObject
のRectTransform
がすべて縦横に完全にストレッチするようにしてあれば正常に動作します。
デバイスのフレーム表示/セーフエリアの範囲表示
セーフエリアありの端末解像度を選択するとGameウィンドウの左上に歯車アイコンが表示されるので、そこから表示・非表示を切り替え可能です。
こだわった点
基本的には以下の3点を追求しました。
- uGUIのオートレイアウトのような簡単で自然な使い心地
- 使ってて細かい挙動を含めイライラしない
- シンプルかつ高い拡張性
リアルタイムプレビュー
- エディタ上で
- 既存のGameウィンドウの解像度選択を変更するだけで
- リアルタイムに
- 再生/非再生の状態を問わず
- セーフエリアあり端末での見た目が自動で調整
されるので、ビルドしなくてもセーフエリアありの場合のレイアウトを手軽に確認できます。
設定変更がGameウィンドウから可能
通常アセットやエディタの拡張の設定は[MenuItem]
を使用してグローバルメニュー(+ショートカットキー)から行えるようにするのですが、Gameウィンドウ上に設定のUIを配置することでon/off切り替えの煩雑さを軽減しました。
ちなみにUIの配置にはUIElementsを使用しています。
高い拡張性
端末解像度とセーフエリアの情報はScriptableObject
を継承したアセットとして保持しているので、追加・拡張が簡単にできます。
SafeArea
,UnsafeArea
コンポーネントで満たせない複雑な要件の場合も、SafeAreaBase
クラスを継承することでエディタ上でのリアルタイムプレビューの機能が簡単に実装できます。
Gitフレンドリー
セーフエリアの対応はRectTransform
のアンカーを自動調整することで実現していますが、シーンやプレハブの保存前に必ずアンカーをリセットしています。
これにより「Gameウィンドウで異なる解像度を選択して保存 → Gitでdiffが出る」ということが起きません。
実装の詳細
Gameウィンドウの情報を利用するにあたり、Gameウィンドウの実態であるGameView
クラスが公開されていないため、リフレクションを用いてそのデータにアクセスしています。
実際にリフレクションを用いているのはGameViewProxy
クラスのみで、値の変更についてはGameViewEvent
クラスが監視・イベント化しています。
実機のフレーム表示は前もって用意したフレーム画像を描画していて、セーフエリアの大きさは事前にシミュレータビルドで収集した値をScriptableObject
を継承したGameViewScreen
アセットに保存・使用しています。
デバイスのフレーム表示とセーフエリアの境界線表示はそれぞれDeviceFrameDrawer
コンポーネントとSafeAreaDrawer
コンポーネントが行っていて、それらのコンポーネントがアタッチされたAutoScreenManager
プレハブが自動的にHierarchyに配置されるようになっています。このプレハブインスタンスはシーンやビルドには含まれず、Hierarchyにも表示されません。
対応端末追加の手順
エディタ上でのプレビューはマスターデータを追加するだけで簡単に対応機種を増やすことが可能です。
- Gameウィンドウから手作業で解像度を追加します。自動化したい場合はGameViewSizeHelperを使うと良いです。
- Projectウィンドウで右クリックし、
Create
->ScriptableObjects
->GameViewScreen
からマスターデータを保持するためのアセットを作成します。 - 2.で作成したアセットの各値をInspectorウィンドウから設定します。
- 解像度やセーフエリアの値はDemoシーンをシミュレータや実機にビルドして確認すると楽です。
-
Base Text
は1.で追加した解像度のLabel
と同じ文字列にしてください。 - 必要であればデバイスのフレーム画像を追加し、アセットの
Frame
にセットしてください。
- 解像度を適当に変更すると反映されます。Unityを再起動する必要はありません。
Tips
- 自動で追加される
RuntimeSafeAreaUpdater
コンポーネントは画面の回転を許可していないアプリの場合は不要 - 11インチのiPadはGameウィンドウから解像度を登録するとプレビュー可能
- デフォルトだとUnityに解像度が登録されてない
- ラベル名は「iPadPro 2388x1668 Landscape」「iPadPro 2388x1668 Portrait」で登録する
- 12インチのiPadの解像度を選択するとセーフエリアあり(第3世代)としてプレビュー表示される
- 第1〜2世代のセーフエリアなしレイアウトを確認したい場合は適当なラベル名で別途解像度を追加すればOK
- セーフエリア境界線の太さ・色は
AutoScreenManager
プレハブから調整可能 -
SafeAreaDrawer
コンポーネントは単体で実機でも動作可能
ライセンス
MIT
参考
- GameView.cs(UnityCsReference)
- GameViewSizes.cs(UnityCsReference)
- UniSafeAreaAdjuster(GitHub)
- NotchSolution(GitHub)
最後に
やりたいことや細かい挙動の調整を全部やろうとしたら結果的に
- 新しいプレハブAPIの使い方
- UIElements
[ExecuteAlways]
HideFlags
等々Unityのよく知らなかった様々な機能について詳しく知る良い機会になりました。個別の知見についてはアドベントカレンダーのときにでもまとめたいと思います。
コードにコメント書かないマンなのですがコード自体はシンプルで読みやすいと思うので、わからないことがあったらとりあえずコードを読んでみてください。
実は実践未投入なので、何か不具合があればPRかTwitterへ → @su10_dev