[unity]どんな画面サイズでも動くゲームにする

unity は uGui 以降、比較的簡単に「どんな画面サイズでも動くゲーム」が作れます。

横長画面のゲームを…
縦長画面で表示しても崩れない

ただ、ちょっと気をつける要素もあります。それも含め、「これでゲームであればどんな画面サイズもOK」になるようにしてみましょう。

uGui を使う

2D 表示はとにかく uGui で済ませるようにします。
こうすることで、2D 要素については何も考えずに上手く配置されるようになります。

Canvas Scaler は Scale With Screen Size

Canvas Canvas Scaler 設定で9割がたどんな画面サイズでも動くようになります。
(これだけで解決! としている記事も結構あるほどです)

UI Scale ModeScale With Screen SizeScreen Match ModeExpand にします。
X、Y は自分が基準とする画面サイズを設定しましょう。
私は横長であれば X:1920、Y:1080、縦長なら X:1080、Y:2160 くらいに設定しています。

大きすぎると描画コストが跳ね上がるので、程ほどにしておきます。
(unity で 4K とかはあまり考えない方がいいかなーと)

画面サイズをはみ出した部分にマスクをかける

先ほど9割がた、と書きましたが残る1割がこれ。

オレンジ部分がゲーム画面ですが、はみ出している部分にも絵が出ています(赤丸の部分)。
出来れば見えなくしたいので、この部分にマスクをかぶせることにします。

最上段に表示されるキャンバスに Image を 2 枚置けば、下に何が表示されようと隠せます(赤い部分の上下マスク)。

DisplayMask はコードを入れるための GameObject です。
(Canvas に直接置いても OK)

コード

このコードを DisplayMask(GameObject) にアタッチし、Inspector で Image0Image1 を登録してください。

using UnityEngine;
using UnityEngine.UI;

public class DisplayMask : MonoBehaviour
{
    [SerializeField]
    Image[] RectMasks = null;

    int screenWidth;
    int screenHeight;

    /// <summary>
    /// start
    /// </summary>
    void Start()
    {
        resetResolution();
    }

    void Update()
    {
        if (Screen.width != screenWidth || Screen.height != screenHeight)
        {
            resetResolution();
        }
    }

    void resetResolution()
    {
        screenWidth  = Screen.width;
        screenHeight = Screen.height;

        float dispWidth  = 2160;
        float dispHeight = 1080;

        float scale_w = screenWidth  / dispWidth;
        float scale_h = screenHeight / dispHeight;

        if (scale_w > scale_h)
        {
            // 横方向にマスク
            float width = ((screenWidth / scale_h) - dispWidth) / 2;
            float x = dispWidth / 2 + width / 2;
            RectMasks[0].SetXY( x, 0);
            RectMasks[0].SetSize(width, dispHeight);
            RectMasks[1].SetXY(-x, 0);
            RectMasks[1].SetSize(width, dispHeight);
        }
        else
        {
            // 縦方向にマスク
            float height = ((screenHeight / scale_w) - dispHeight) / 2;
            float y = dispHeight / 2 + height / 2;
            RectMasks[0].SetXY(0,  y);
            RectMasks[0].SetSize(dispWidth, height);
            RectMasks[1].SetXY(0, -y);
            RectMasks[1].SetSize(dispWidth, height);
        }
    }
}

/// <summary>
/// image extensions
/// </summary>
public static class ImageExtensions
{
    public static void SetXY(this Component self, float x, float y)
    {
        Vector3 trans = self.gameObject.transform.localPosition;
        trans.x = x;
        trans.y = y;
        self.gameObject.transform.localPosition = trans;
    }

    public static void SetSize(this Image self, float width, float height)
    {
        self.rectTransform.SetSize(width, height);
    }
}

33-34 行目は、Canvas Scaler の XY 値に合わせてください。

実行すると画面サイズに合わせてマスクが動的にリロケーションされます。

もう1つの画面サイズ対応

実用アプリの場合はゲームと違って、「非描画部分をマスクで誤魔化す」という設計はあまり好ましくないかもしれません。

少々面倒な RectTransform と向き合う方法についてはこちらの記事で触れています。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA