unity は uGui 以降、比較的簡単に「どんな画面サイズでも動くゲーム」が作れます。
ただ、ちょっと気をつける要素もあります。それも含め、「これでゲームであればどんな画面サイズもOK」になるようにしてみましょう。
uGui を使う
2D 表示はとにかく uGui で済ませるようにします。
こうすることで、2D 要素については何も考えずに上手く配置されるようになります。
Canvas Scaler は Scale With Screen Size
Canvas の Canvas Scaler 設定で9割がたどんな画面サイズでも動くようになります。
(これだけで解決! としている記事も結構あるほどです)
UI Scale Mode を Scale With Screen Size、Screen Match Mode は Expand にします。
X、Y は自分が基準とする画面サイズを設定しましょう。
私は横長であれば X:1920、Y:1080、縦長なら X:1080、Y:2160 くらいに設定しています。
大きすぎると描画コストが跳ね上がるので、程ほどにしておきます。
(unity で 4K とかはあまり考えない方がいいかなーと)
画面サイズをはみ出した部分にマスクをかける
先ほど9割がた、と書きましたが残る1割がこれ。
オレンジ部分がゲーム画面ですが、はみ出している部分にも絵が出ています(赤丸の部分)。
出来れば見えなくしたいので、この部分にマスクをかぶせることにします。
最上段に表示されるキャンバスに Image を 2 枚置けば、下に何が表示されようと隠せます(赤い部分の上下マスク)。
DisplayMask はコードを入れるための GameObject です。
(Canvas に直接置いても OK)
コード
このコードを DisplayMask(GameObject) にアタッチし、Inspector で Image0、Image1 を登録してください。
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 と向き合う方法についてはこちらの記事で触れています。