Unity 2D 如何讓遊戲物件相容各個手機尺寸


建立時間: 2022年8月23日 16:37
更新時間: 2023年10月19日 21:00

說明

因為手機的解析度與螢幕比率不同,這讓我非常頭痛,即使到現在我還是覺得這篇寫的方法,沒有特別好,如果讀者有不錯的方法歡迎告訴我。

這次主軸是要開發一款 2D 手機遊戲,只打算發佈到 ios 系統,而遊戲只有直式方式顯示,所以不會考慮橫式的問題,只有一台攝影機,不會考慮多台攝影機切換的問題,遊戲美術會以小圖為主,大概為64x64那種。

接下來就來看看有什麼需要注意的地方

Game 場景

在選單 File > Build Settings… 切換 ios 設備後,可以顯示多種手機裝置的解析度,保險起見,多看幾個裝置,確認最小的寬度為何,以免做到超出場景。

你也可以自訂解析度,無論是比例或是固定解析度,當然最好的測試是拿真實手機確認,如果沒有的話就先用 Unity Game 場景提供的即可。

Game Aspect Ratio

UI

這裡的 UI 指的是在 canvas 畫布裡面的物件

Canvas

  • Render Mode: Screen Space - Overlay,比較適合做 2D 遊戲的選項、設定按鈕操作,讓畫面保持一致大小,始終在最上層。

Canvas Scaler

Canvas Scaler Settings

  1. UI Scale Mode 選擇 Scale With Screen Size。
  2. Reference Resolution 解析度依照當時的裝置而定,這個是 UI 設計的基礎畫布大小。
  3. Screen Match Mode 選擇 Expand: 水平或垂直擴展畫佈區域,使畫布不會小於參考。
  4. Reference Pixels Per Unit: 因為 Screen Match Mode 選擇 Expand,所以此欄位不影響遊戲

以上是參考 Unity UI 適配總結,當你按照上述設定,搭配錨點和樞紐(anchor and pivot),我想大部分的佈局都能如預期一樣,但是你可能會遇到 iPhone 瀏海的問題,這就要參考 Unity UI 適配總結 裡面的解決辦法。

攝影機

主要看 Projection 和 Size

Camera Settings

  1. Projection 選 Orthographic
  2. Size 自訂合適的尺寸

一般 2d 遊戲會選擇 Orthographic,沒有透視的效果,無法分辨遠近

Size 計算方式

Size 是攝影機的範圍,有一個公式試算出 Size 為多少
螢幕高度 / Pixels per Unit(每單位多少相素) / 2

Pixels per Unit 在 Canvas Scaler 的 Reference Pixels Per
假設在 Canvas Scaler 的 Reference Resolution Y 螢幕高度為640
Pixels per Unit 為100
Size = 640 / 100 / 2 = 3.2

但我沒有這樣設定
我把一張64x64的圖片放在上面,調整合適的 Size

最後我的遊戲中有一個背景物件,我把它調整成恰好填滿整個攝影機的畫面

background

攝影機高度固定

Projection 選 Orthographic 的時候,我發現無論切換什麼解析度的裝置,高度都是固定的,只有寬度在改變。

參考下圖兩個不同的裝置的攝影機所拍攝的範圍:

IPhone 8

截圖 2023-10-19 下午8.57.26.png

IPhone XS

截圖 2023-10-19 下午8.57.37.png

用程式調整合適的 Size

在調整解析度時,有可能螢幕高度變小,導致沒完全顯示高度
或者螢幕高度變大,導致顯示範圍超出背景高度,寬度也有相同狀況
我們用程式來調整 Size ,讓畫面能完整的顯示背景

CameraScript.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 攝影機適配器
/// </summary>
public class CameraScript : MonoBehaviour
{
    /// <summary>
    /// 使用此圖的大小來適配攝影機的 orthographicSize
    /// </summary>
    [SerializeField] SpriteRenderer _background;
    private float _halfBackgroundBoundSizeY;

    // Start is called before the first frame update
    void Start()
    {
        _halfBackgroundBoundSizeY = _background.bounds.size.y / 2;

        _fitFullHeight();
    }

    /// <summary>
    /// 水平和垂直適配
    /// </summary>
    private void _autoFit()
    {
        float ScreenRatio = (float)Screen.width / (float)Screen.height;
        float TargetRatio = _background.bounds.size.x / _background.bounds.size.y;

        if (ScreenRatio >= TargetRatio)
        {
            _fitFullHeight();
        }
        else
        {
            float DifferenceInSize = TargetRatio / ScreenRatio;

            Camera.main.orthographicSize = _halfBackgroundBoundSizeY * DifferenceInSize;
        }
    }

    /// <summary>
    /// 垂直適配,寬度可能會被切到,或多出來
    /// </summary>
    private void _fitFullHeight()
    {
        Camera.main.orthographicSize = _halfBackgroundBoundSizeY;
    }

    /// <summary>
    /// 寬度適配,高度可能會被切到,或多出來
    /// </summary>
    private void _fitFullWidth()
    {
        float OrthoSize = _background.bounds.size.x * Screen.height / Screen.width * 0.5f;

        Camera.main.orthographicSize = OrthoSize;
    }
}

攝影機物件加入 CameraScript.cs
將 background 物件圖片拉到 CameraScript background 屬性裡

setting background

最後在 Start() 呼叫你想要的效果
_autoFit() 水平和垂直適配
_fitFullHeight() 垂直適配
_fitFullWidth() 寬度適配

參考

觀看次數: 4019
mobileorthographicphoneresolutionsizeunity
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!