こんにちは、Unityエンジニアのオオバです。

以前フルFlashサイト (ブラウザ全画面Flashサイト) を制作していました。

モニタ解像度やブラウザ画面の縦横比率がどういう状態でも正常にレイアウトされる実装をしないといけない所に苦労した思い出があります。

スマホアプリ開発も同様で、スマホからタブレットまで様々な比率の解像度(主にAndroid)が存在し、フルFlashサイト開発とさして変わりません。

ナイツクロニクル
画面数多めのRPGナイツクロニクルが、
縦横どちらも対応したアプリとしてリリースされたことは記憶に新しいです。

逃げる手段も色々あるが...

比率を固定して、それ以外の比率の端末では左右に黒背景を敷いて逃げるのが最もUI開発としては簡単なのですが、今やそんなことをしているアプリは少ないですし、何よりダサくレガシー感が拭えません。

iPhone3Gが日本で発売されて早8年近く経ち、スマホユーザーのアプリに対する目は確実に肥えていますし、アプリ総数自体が当時と桁違いです。

少しでもアプリをよく見せるためには、多少大変だとしてもリキッドレイアウトを採用して行くべきだとオオバは考えます。

今回はどんな解像度でも対応できる背景画像実装を紹介します。
縦長、横長どちらでも画面にフィットさせることが出来ます。

使い方は、uGUIBgFitコンポーネントをフィットさせたいGameObjectにAddComponentするだけです。

【Unity】uGUIで画面にフィットする便利コンポーネント_0

↑↑元画像

【Unity】uGUIで画面にフィットする便利コンポーネント_1

比率 3:4 iPad縦持ち

【Unity】uGUIで画面にフィットする便利コンポーネント_2

比率 4:3 iPad横持ち

【Unity】uGUIで画面にフィットする便利コンポーネント_3

比率 9:16 iPhone5縦持ち

【Unity】uGUIで画面にフィットする便利コンポーネント_4

比率 16:9 iPhone5横持ち

すると、このように全ての解像度に画像をフィットさせることが出来ます。
まさにフルFlashサイトで実装していた内容と同じです。

今回は基本的なUGUIでの画像フィット実装だけにとどめますが、
このままだと縦長解像度ではUnityちゃんの顔が切れてしまいますので、良い感じに調整する機能を追加していく必要がありそうですね。

サンプルコードを貼っておきます。

using UnityEngine;  
using UnityEngine.UI;  

/// <summary>  
/// アタッチしたRectTransformを画面にフィットさせます  
/// </summary>  
[ExecuteInEditMode ()]  
[RequireComponent (typeof(RectTransform))]  
public class UGUIBgFit : MonoBehaviour  
{
    private float _imgRatio;  

    [SerializeField] private CanvasScaler _scaler;  

    [SerializeField] private RectTransform _rectTr;  

    private void Start ()  
    {
        if (_scaler == null) {  
            _scaler = GetComponentInParent<CanvasScaler> ();  
        }
        if (_rectTr == null) {  
            _rectTr = GetComponent<RectTransform> ();  
        }
        Fit ();  
    }

    private void Update ()  
    {
        #if UNITY_EDITOR  
        // Edit中でも反映されます  
        Fit ();  
        #endif  
    }

    private void Fit ()  
    {
        if (_rectTr == null || _scaler == null) {  
            return;  
        }
        float screenW = (float)Screen.width;  
        float screenH = (float)Screen.height;  
        var screenRatio = screenW / screenH;  
        _imgRatio = _rectTr.sizeDelta.x / _rectTr.sizeDelta.y;  
        if (_imgRatio <= screenRatio) {  
            // 画面が横長  
            _scaler.referenceResolution = new Vector2 (screenW, screenW);  
            _rectTr.sizeDelta = new Vector2 (screenW, screenW / _imgRatio);  
            _scaler.matchWidthOrHeight = 0;  
        } else {  
            // 画面が縦長  
            _scaler.referenceResolution = new Vector2 (screenH, screenH);  
            _rectTr.sizeDelta = new Vector2 (screenH * _imgRatio, screenH);  
            _scaler.matchWidthOrHeight = 1f;  
        }
    }
}

最後に

リキッドレイアウト開発は、エンジニア、デザイナー、ディレクターなど
開発に関わる人が開発初期から意識して設計しなければ後で大きな後悔を生みます。

などなど。

意思決定が行われたのであれば貫く勇気を持って頂きたいです。

オススメ記事
検証環境