【Unity/iOS】iPhoneXのSafeArea対応
iPhoneXは上部にセンサーハウジング(凹)や角丸があるため、矩形の領域(SafeArea)を考慮する必要があります。
SafeAreaについては以下を参照
Update Apps for iPhone X - iOS - Apple Developer
この記事では縦で使用する場合を想定しています。
SafeAreaの取得
Unity5.5.x - 2017.x
- Unityからパッチがあるので、Bitbucketから「iOSSafeAreasPlugin」をダウンロード
- Plugins/iOSに
SafeAreaImpl.mm
を追加
iOSの場合
float x, y, w, h; GetSafeAreaImpl(out x, out y, out w, out h); var safeArea = new Rect (x, y, w, h);
iOS以外の場合
var safeArea = new Rect(0, 0, Scree.width, Scree.height);
2017.3から
2017.3からはScreenから取れるようですが、未検証です。
var safeArea = Screen.safeArea;
SafeAreaを反映
以下のようにCanvas直下にGameObject(Content)を配置します。
Canvas/ Content/
ContentがSafeArea内になります。 もし、現在Canvas直下にUIを配置している場合は、Content内に入れるように1つ階層を下げる必要がありますが、画面全体を覆うようなエフェクト処理は今まで通りCanvas直下で問題ありません。
また、縦型の場合、以下のようにContentの上下に配置すると便利だったりします。
Canvas/ Top/ Content/ Bottom/
- iPhoneX
- iPhoneX以外
Top、BottomがContentの外側になります。iPhoneX以外ではTop, Bottomは使用しません(サイズがゼロまたはactiveSelf==false)。 TopとBottomは状況に応じてHeader/Footerの色で塗りつぶしたり、非表示にするといった対応が必要になります。
ContentにSafeAreaを反映
ダウンロードしたパッチのAssets/SetCanvasBounds.cs
のApplySafeArea
を使用します。
Canvasにスクリプトを追加し、StartのタイミングでApplySafeAreaのpanel
部分をContent
に置き換えて反映します。
Top/Content/Bottomのサイズを設定
SafeAreaは左下基準で取得するため、 bottomの高さがsafeArea.y、topの高さがScreenからsafeAreaとbottomの高さを引いたものになります。
void _ApplyLayout(){ var safeArea = SafeArea.GetSafeArea (); SafeArea.ApplySafeArea (_content, safeArea); var scale = 1 / _content.lossyScale.y; var bottomSize = _bottom.sizeDelta; bottomSize.y = _bottom.gameObject.activeSelf ? safeArea.y * scale : 0; _bottom.sizeDelta = bottomSize; var topSize = _top.sizeDelta; topSize.y = _top.gameObject.activeSelf ? (Screen.height - safeArea.height - safeArea.y) * scale : 0; _top.sizeDelta = topSize; }
ただ、このままでは実機でなければ確認ができず、大変不便です。
Editor上で確認
開発しやすくするために、Editor上でも確認できるようにしておくと便利です。 SafeAreaのrectに対し、以下のように変更します。 (要Window > Gameのwidth=1125, height=2436に設定)
#if UNITY_EDITOR if(Screen.width == 1125 && Screen.height == 2436){ rect.y = 102; rect.height = 2202; } #endif