Unity 2D 如何讓遊戲物件相容各個手機尺寸
分類
說明
因為手機的解析度與螢幕比率不同,這讓我非常頭痛,即使到現在我還是覺得這篇寫的方法,沒有特別好,如果讀者有不錯的方法歡迎告訴我。
這次主軸是要開發一款 2D 手機遊戲,只打算發佈到 ios 系統,而遊戲只有直式方式顯示,所以不會考慮橫式的問題,只有一台攝影機,不會考慮多台攝影機切換的問題,遊戲美術會以小圖為主,大概為64x64那種。
接下來就來看看有什麼需要注意的地方
Game 場景
在選單 File > Build Settings… 切換 ios 設備後,可以顯示多種手機裝置的解析度,保險起見,多看幾個裝置,確認最小的寬度為何,以免做到超出場景。
你也可以自訂解析度,無論是比例或是固定解析度,當然最好的測試是拿真實手機確認,如果沒有的話就先用 Unity Game 場景提供的即可。
UI
這裡的 UI 指的是在 canvas 畫布裡面的物件
Canvas
- Render Mode: Screen Space - Overlay,比較適合做 2D 遊戲的選項、設定按鈕操作,讓畫面保持一致大小,始終在最上層。
Canvas Scaler
- UI Scale Mode 選擇 Scale With Screen Size。
- Reference Resolution 解析度依照當時的裝置而定,這個是 UI 設計的基礎畫布大小。
- 關於蘋果裝置的解析度可參考這篇: App 預覽規格
- Screen Match Mode 選擇 Expand: 水平或垂直擴展畫佈區域,使畫布不會小於參考。
- Reference Pixels Per Unit: 因為 Screen Match Mode 選擇 Expand,所以此欄位不影響遊戲
以上是參考 Unity UI 適配總結,當你按照上述設定,搭配錨點和樞紐(anchor and pivot),我想大部分的佈局都能如預期一樣,但是你可能會遇到 iPhone 瀏海的問題,這就要參考 Unity UI 適配總結 裡面的解決辦法。
攝影機
主要看 Projection 和 Size
- Projection 選 Orthographic
- 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
最後我的遊戲中有一個背景物件,我把它調整成恰好填滿整個攝影機的畫面
攝影機高度固定
Projection 選 Orthographic 的時候,我發現無論切換什麼解析度的裝置,高度都是固定的,只有寬度在改變。
參考下圖兩個不同的裝置的攝影機所拍攝的範圍:
IPhone 8
IPhone XS
用程式調整合適的 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 屬性裡
最後在 Start()
呼叫你想要的效果
_autoFit()
水平和垂直適配
_fitFullHeight()
垂直適配
_fitFullWidth()
寬度適配
參考
一杯咖啡的力量,勝過千言萬語的感謝。
支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!