とりあえず、NGUIのUIAnchorについてSafeAreas対応ができたのでメモ。
他にも、SafeAreasとして以下の対応が必要になるが、この記事ではUIAnchorの対処方法を記載します。
必要になること:
・UIRectのAnchor
・UIScrollViewの表示範囲の調整(Anchorの基準が変化するためUI調整が必要になる)
前提条件:
この記事は、以下のことを前提に話を進めます。
・Unity5.6.6を使って開発しています。
・iOSSafeAreasPluginをダウンロードしてインポートしていること
Pluginのダウンロードサイト
https://bitbucket.org/p12tic/iossafeareasplugin/src
・OSはiOSのみ考慮しています。
ソースコード
まずは、ソースコードから公開します。
セーフエリアの取得
SafeAreaScreen.cs
このソースコードは、主にセーフエリアの取得を担当しています。
UnityエディタでスクリーンサイズをiPhoneXと同じサイズ(1125×2436)に設定すると、Unity Player上でもデバッグできます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
public class SafeAreaScreen {
#if UNITY_IOS
[DllImport("__Internal")]
private extern static void GetSafeAreaImpl(out float x, out float y, out float w, out float h);
#endif
static public Rect GetSafeArea()
{
float x, y, w, h;
//初期値設定
x = 0;
y = 0;
w = Screen.width;
h = Screen.height;
#if UNITY_IOS && !UNITY_EDITOR
//iOSSafeAreasPluginを呼び出す
GetSafeAreaImpl(out x, out y, out w, out h);
#elif UNITY_ANDROID && !UNITY_EDITOR
//Androidの縦長端末対応が必要になったときのために
#else
//UnityエディタでiPhoneXのテストできるように値を設定する
if(Screen.width == 1125 && Screen.height == 2436 ){
y = 102;
h = 2202;
}
#endif
return new Rect(x, y, w, h);
}
static public int GetTopOffsetY(){
int offset = 0;
//画面の高さとセーフエリアの高さの差分
Rect screenSize = GetSafeArea();
if (Screen.height != screenSize.height) {
offset = Screen.height - (int)screenSize.height - (int)screenSize.y;
}
return offset;
}
static public int GetBottomOffsetY(){
int offset = 0;
//セーフエリアのyの位置取得
Rect screenSize = GetSafeArea();
if (Screen.height != screenSize.height) {
offset = (int)screenSize.y;
}
return offset;
}
}
NGUIのSafeArea
NguiSafeAreaPatch.cs
SafeAreaScreen.csで取得したセーフエリアを元にAnchorの位置を調整します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NguiSafeAreaPatch : MonoBehaviour {
void Awake()
{
// UIAnchorを使ってAnchorを設定している場合
UIAnchor anchor = gameObject.GetComponent();
if(anchor != null){
//offsetの値を取得する
SetUIAnchorOffset(anchor);
return;
}
// UIRectをAnchorを使っている場合
UIRect rect = gameObject.GetComponent();
if (rect != null) {
//現在,NGUIのソースコードを解析中
//完成しだい公開予定
return;
}
}
private void SetUIAnchorOffset(UIAnchor anchor){
//現在のoffsetを取得する
Vector2 nowOffset = anchor.pixelOffset;
//TOP側の補正値取得
int topCorrectionOffset = SafeAreaScreen.GetTopOffsetY ();
//Bottom側の補正値取得
int bottomCorrectionOffset = SafeAreaScreen.GetBottomOffsetY ();
switch (anchor.side) {
case UIAnchor.Side.Top:
case UIAnchor.Side.TopLeft:
case UIAnchor.Side.TopRight:
anchor.pixelOffset.Set(nowOffset.x, nowOffset.y - topCorrectionOffset);
break;
case UIAnchor.Side.Bottom:
case UIAnchor.Side.BottomLeft:
case UIAnchor.Side.BottomRight:
anchor.pixelOffset.Set(nowOffset.x, nowOffset.y + bottomCorrectionOffset);
break;
}
}
}
使い方は、このソースコードをUIAnchorがアタッチされているゲームオブジェクトにアタッチするだけ。
ソース内でやっていることは、動作環境がiPhoneXと判定したら、スクリーンとセーフエリアの高さの差分を計算して、差分の分ゲームオブジェクトを下げます。
差分の値は、UIAnchorの「Pixel Offset」に代入されます。
ソースコードを反映させた結果
NguiSafeAreaPatch.csをUIAnchorにアタッチさせた結果を記載します。
■反映前
■反映後
その結果、セーフエリアを基準にすることができました。
これにてUIAnchorについてはSafeAreaの対処ができました。
しかし、ほかにも「UIRectのAnchor」に対してもSafeAreas対応があります。対応が終わり次第、随時記事に追加していきます。