この記事でのバージョン
Unity 2018.4.19f1
Unity 2019.3.0f6
はじめに
iOS(Androidも?)端末にはiPhoneXのノッチなどを含まないセーフエリアという範囲があります。
そして、Unityではセーフエリアの位置やサイズをScreen.safeAreaで取得する事が可能ですが、
このsafeAreaの値がAwakeとStartで違う場合があるというのが今回のお話。
Screen.safeAreaの値がAwakeとStartで違う
例えば以下のような感じで、Awake時とStart時のsafeAreaの値をTextに表示するようなコードを
[SerializeField] private Text _infoText = default, _awakeText = default, _startText = null; private void Awake() { //Unityのバージョン、デバイスの種類、OSを表示 _infoText.text = $"UnityVersion : {UnityEngine.Application.unityVersion}\nDevice : {SystemInfo.deviceModel}\nOS : {SystemInfo.operatingSystem}"; //Start時のセーフエリアを確認 _awakeText.text = $"Awake\n{Screen.safeArea.ToString()}"; } private void Start() { //Start時のセーフエリアを確認 _startText.text = $"Start\n{Screen.safeArea.ToString()}"; }
実際に実機で確認すると、確かに値が異なります。
ちなみにStartの値の方が正しいので、
Screen.safeAreaの値はAwakeでは使わないという実装でとりあえず問題は回避出来ます。
仕様?バグ?
そもそもこの現象はバグらしくIssue Trackerにもあがっていて、Unity2019.3で直っています。
実際に先程のコードをUnity2019.3で実行しているみると、
確かにAwakeとStartの値が一致していました。
ちなみにIssue Trackerでは見つけられませんでしたが、
Androidの一部の端末でもこの現象は起きるようです。(Androidの方がUnity2019.3で直ってるかは未確認)
おわりに
今回のような「Awakeだと想定通りにいかない」というのは
safeArea以外でも起こりうるUnityあるあるだと思います。
経験則だと、Awakeは自クラス内で完結する(他クラスを参照しない)処理だけを書く
という感じである程度上手くいくと思うので参考にしてみてください。