U
20 / 22 · 11 分
FAQ

あらゆる画面に合う UI(ノッチ込み)

短い答え

UI をあらゆる画面サイズに合わせるには?

Canvas Scaler を Scale With Screen Size にして基準解像度を指定し、各要素を角や辺にアンカーします。ノッチ機では全画面の親を Screen.safeArea に収め、重要なものが切り欠きに入らないようにします。

Game ビューで一つの解像度でのみ作り、別の解像度では一度も確認していない UI は、ほとんどのスマホで崩れています。直す鍵は三つ、互いに独立しています——Canvas がどう拡大縮小するか、各要素がどこにアンカーされているか、ノッチに何が隠れているか。

アニメーション図

同じ三つの要素を三つの画面形で並べたところです。どれもアンカーした角にしっかりついたまま、三台目の端末ではノッチがセーフエリアを少し噛んでいます。

1 — Canvas Scaler がすべてのサイズを決める

既定で Canvas は Constant Pixel Size になっており、40 ピクセルのボタンはどのデバイスでも 40 ピクセルのままです。つまりノートパソコンでは余裕で押せるのに、1440p のスマホでは米粒ほど。このドロップダウンを一つ変えるだけで直ります。

  1. 1

    Canvas を選択し、Canvas Scaler コンポーネントを見つけて、UI Scale Mode を Scale With Screen Size に設定します。

  2. 2

    Reference Resolution を、今デザインしているサイズに設定します。縦置きのスマホゲームなら 1080 × 1920、横置きなら 1920 × 1080 です。

  3. 3

    Screen Match Mode を Match Width Or Height にし、スライダーは縦向きゲームなら 0、横向きなら 1 にドラッグします。

2 — アンカーが、どこに留まるかを決める

アンカーは、要素が親のどの部位にしがみついているを表します。中央にアンカーして右へ 400 ピクセルのボタンは、どんな画面でも中央から右に 400 ピクセル——狭い画面では外にはみ出ます。代わりに右側へアンカーすれば、右端がどこにあっても、右端からの距離は一定のままです。

  • 見た目上どこに属しているかで、角や端にアンカーします:ヘルスバーは左上、ジャンプボタンは右下、タイトルは上部中央。

  • アンカーのプリセットをクリックするとき Alt を押しておくと、アンカーだけ変わって要素はその場に留まるのではなく、要素ごとあの位置へ移動します。

  • 横幅いっぱいに広げたいもの——トップバーやダイアログボックス——は、アンカーのハンドルを左右に引き離して、固定幅ではなく伸縮するようにします。

3 — ノッチがあるスマホのセーフエリア

Screen.safeArea は、システムがノッチ・パンチホール・角丸・ジェスチャーバーに隠れないと保証してくれる長方形の領域です。Unity に既定の切り替えはないので、RectTransform をこの領域に合わせて拡大縮小し、その中に UI を入れます。

SafeAreaFitter.cs — attach to a full-screen child of the Canvas
using UnityEngine;

[RequireComponent(typeof(RectTransform))]
public class SafeAreaFitter : MonoBehaviour
{
    RectTransform rt;
    Rect last;

    void Awake()
    {
        rt = GetComponent<RectTransform>();
        Apply();
    }

    // The safe area changes when the phone rotates, so do not do this once.
    void Update()
    {
        if (Screen.safeArea != last) Apply();
    }

    void Apply()
    {
        last = Screen.safeArea;

        // Anchors are 0–1 fractions of the screen, so divide by the screen size.
        Vector2 min = last.position;
        Vector2 max = last.position + last.size;
        min.x /= Screen.width;  min.y /= Screen.height;
        max.x /= Screen.width;  max.y /= Screen.height;

        rt.anchorMin = min;
        rt.anchorMax = max;
        rt.offsetMin = rt.offsetMax = Vector2.zero;
    }
}
  • 画面いっぱいの Canvas の子オブジェクトに付け、HUD をその子の下に入れます。Canvas 自身には絶対に付けないでください——あの RectTransform の主導権は Canvas Scaler が握っています。

  • 背景はあえて外に残します。セーフエリアに寄せた背景はノッチの横にみすぼらしい帯を作ってしまうので、必ず見たい・押したいものだけを内側に入れます。

  • エディタでは Screen.safeArea が画面全体を指すため、このコードはビルドするまで何もしていないように見えます。スマホなしで確かめる唯一の方法は Device Simulator ウィンドウです。

リリース前に確かめる

  1. 1

    Window▸General▸Device Simulator を開き、何台かのスマホを順に切り替えて見て回ります。ノッチ付きと、とても縦に長い機種を必ず入れてください。

  2. 2

    Game ビューに、両端の解像度をカスタムで追加します:4:3 と 21:9。その両方で UI が崩れなければ、間のどの比率でも大丈夫です。

  3. 3

    見た目だけでなく、タップできる領域を確認します。指で押さえるものには約 9 mm——デバイスに依存しないピクセルで約 48——が必要で、手元のモニターで小さく見えてもこれは変わりません。

これを作るレッスン

タッチ操作とジョイスティック

この記事はそれだけで完結するレシピです。コースでは同じものを、5 つのタブを貫くひとつのプロジェクトの一部として作ります — カメラと入力 のレッスン 05。