Unity UGUI performance

Canvas

在 Unity UI 中,修改單一元素可能會觸發整個 Canvas 的重新整理。這種重新評估與網格生成的過程會對效能造成嚴重影響,特別是在複雜的 UI 設計中。主要原因如下:

  1. 網格生成成本高:Unity 的 UI 系統會將元素分組為繪製批次(Draw Calls),但每次小變動都需要重新生成批次,導致高資源消耗。
  2. 過度使用單一 Canvas:將大量 UI 元素集中於一個 Canvas 內,當有微小更新時,會引發顯著的效能尖峰。

解決方式:將 UI 分割到多個 Canvas 是減少效能問題的有效方法。

  • 將單一個 Canvas 分割為 巢狀 Canvas(Nested Canvases),這麼做的好處有
    • 子 Canvas 與父 Canvas 和兄弟 Canvas 互相隔離,具有獨立的幾何圖形和批次處理功能。
    • 有助於組織層次結構化的 UI。
    • 單一 Canvas 的變動不會影響其他 Canvas,縮小了網格重新生成的範圍。
  • 分割 Canvas 的最佳實踐
    • 依刷新頻率分組:
      • 靜態元素:將不常變動的 UI 元素(如背景圖片、標題)放在單獨的 Canvas 上。
      • 動態元素:將頻繁更新的 UI 元素(如血量條、分數、計時器)分配到不同的 Canvas。
    • 保持一致性:
      • 確保 Canvas 內的元素共享相同的 Z 值、材質和貼圖,以提高批次處理的效率。
    • 避免過度巢狀化:
      • 雖然巢狀 Canvas 功能強大,但過度巢狀化會增加維護難度。應針對邏輯分組策略性使用。
    • 範例結構:
      • 主 Canvas:作為 UI 的總容器。
        • HUD Canvas:顯示血量、分數和小地圖(頻繁更新)。
        • 暫停菜單 Canvas:包含按鈕和靜態菜單元素(很少更新)。
        • 背包 Canvas:用於展示背包內容(僅在打開時更新)。
      • 這樣的結構下,當玩家血量在遊戲中變動時,僅 HUD Canvas 會更新,暫停菜單 Canvas背包 Canvas 不受影響。這樣的分割方式有效避免了不必要的效能開銷。

Graphic Raycasters

Graphic Raycaster 是 Unity UI 系統的一部分,負責將玩家的觸控或點擊行為轉換為遊戲可理解的事件。它的主要作用是:

  • 事件檢測:確認玩家觸碰的屏幕區域是否對應到某個 UI 元素。
  • 信息傳遞:將觸控位置與設定為可互動的 UI 元素匹配,並將事件傳遞給正確的遊戲部分。
  • 運作方式:Graphic Raycaster 僅關注 UI 圖形元素(例如按鈕、圖片)。檢查所有設置為可響應觸控的 UI 部件,並確認玩家的觸碰是否在其範圍內。

Graphic Raycaster 產生的問題:

  • 效能消耗高:
    • 每次觸控時,Graphic Raycaster 都需要遍歷屏幕上的所有可交互 UI 元素。
    • 過多的 Graphic Raycaster 或不必要的檢測可能導致資源浪費,尤其是在大型 UI 設計中。
  • 非交互元素:
    • 並非所有 UI 元素都需要響應觸控事件,例如裝飾性的圖片或靜態文本。對這些元素進行射線檢測會降低效能。

解決方式:

  • 移除不必要的 Graphic Raycasters
    • 確保僅在需要檢測觸控事件的 UI Canvas 或元素上添加 Graphic Raycaster。
    • 非交互式 Canvas(例如背景圖像)則移除 Graphic Raycaster,避免不必要的檢測。
  • 關閉非交互元素的 Raycast Target
    • 對於不需要觸控的 UI 元素(如純裝飾性圖片),關閉其 Raycast Target 設定。
      • 在 Image 組件中,取消勾選 Raycast Target。
      • 這樣可以防止該元素被包含在射線檢測的範圍內,減少計算負擔。
  • 使用阻擋遮罩(Blocking Mask)
    • 當 Canvas 的 Render Mode 設置為 Worldspace Camera 或 Screen Space Camera 時,可以使用 Blocking Mask:
      • 該遮罩決定 Raycaster 是否使用 2D 或 3D 物理來檢測阻擋物。
      • 如果物理檢測對 UI 無直接影響,避免啟用該功能以節省資源。
  • 分割 Canvas
    • 將靜態和動態 UI 元素分離至不同的 Canvas。
    • 靜態 Canvas 不需要頻繁更新,也不需要 Graphic Raycaster。

例子:
假設遊戲的 UI 包含以下部分

  • 主菜單:大部分按鈕需要觸控響應,因此保留 Graphic Raycaster,並確保按鈕的 Raycast Target 為啟用狀態。
  • 背景圖片:純裝飾性元素,關閉 Raycast Target 並移除其 Canvas 的 Graphic Raycaster。
  • 玩家 HUD(血量條、得分顯示):分配到單獨的 Canvas,僅需要檢測少數互動(例如按鈕點擊)。

管理 UI 對象池

問題:在常見的 UI 對象池使用方式中,開發者通常先更改對象的父節點(parent),再禁用對象(disable)。然而,這樣的操作會導致:

  • 多次改變層級結構:反復更新對象的層級關係(hierarchy),使得整體性能受到影響。
  • 不必要的開銷:每次改變父節點或激活/禁用對象時,Unity 會標記整個層級結構為“髒”,從而增加開銷。

解決方案:優化對象激活與重設順序

  • 為提高效率,建議按照以下順序管理 UI 對象池:
    • 禁用對象再更改父節點:
      • 禁用對象(SetActive(false))後再將其重新分配到對象池的父節點。
      • 這樣可以確保原始層級結構僅被標記一次為“髒”,避免重複更新。
  • 從對象池提取時的順序:
    • 先更改父節點:將對象移動到新父節點中。
    • 更新對象數據:重設對象的數據(如 UI 文本或圖片)。
    • 最後激活對象:使用 SetActive(true) 啟用對象。
  • 這樣的流程可將每個對象的層級結構變化降至最少,從而減少不必要的性能開銷。

隱藏 Canvas 的方法

在開發過程中,可能需要暫時隱藏某些 UI 元素或整個 Canvas。常見的方式有

  • 使用 SetActive(false) 禁用整個 GameObject
    • 可能會導致 Canvas 層級結構中的回調函數執行(如 OnDisable 和 OnEnable),增加不必要的性能開銷。
  • 移動 Canvas 的位置,讓使用者看不見
    • 並不能停止 GPU 的繪製操作,仍會影響性能。
  • 改變透明度
    • 並不能停止 GPU 的繪製操作,仍會影響性能。

解決方案:停用 Canvas 組件,透過停用 Canvas 可以

  1. 停止繪製操作,當停用 Canvas 組件會立即停止向 GPU 發送繪製請求,使畫布變得不可見。
  2. 並保留頂點緩衝區,Canvas 的頂點資料(meshes 和 vertices)會被保留,因此在重新啟用時無需重建(rebulid),僅需恢復繪製操作。
  3. 避免不必要的回調,停用 Canvas 組件不會觸發整個層級結構的 OnDisable/OnEnable 回調,從而減少性能損耗。

UI 元素動畫

當在 UI 元素上應用 Animator 時,即使動畫的值保持不變,也會在每一幀對 UI 元素產生影響。這會導致

  • 不必要的性能消耗,特別是在多個靜態 UI 元素上。

解決方案:針對靜態或偶爾改變的 UI 動畫需求,避免使用 Animator。可以透過以下方式實現高效的 UI 動畫。使用程式碼或 Tweening 系統進行動畫處理

  • 手寫動畫程式碼:針對簡單的動畫需求,直接使用 C# 程式碼逐步更改 UI 屬性(如位置、透明度等)。
  • Tweening 系統:使用輕量級的 Tweening 庫來簡化動畫實現。
  • Tweening 系統通過插值逐步更改屬性,對於臨時或事件驅動的動畫需求非常高效。
  • 使用專業的 Tweening 資產(如 DoTween)可以快速實現高效動畫。

開發 UI 建議

  1. 為最常用的 UI 元素建立 Prefabs
    • 對於經常使用的 UI 元素(如標題文字),可以將其創建為 Prefab,並將所需的組件附加到這些 Prefab 上。這樣一來,當你需要修改某些元素時,所有使用該 Prefab 的地方都會自動更新,讓你更輕鬆地管理與修改 UI 元素。
    • 例子:假設你有多個地方需要顯示標題文字,將標題文字做成 Prefab,並在遊戲中重複使用。未來如果需要調整字體或大小,只需更改 Prefab,就能同步更新所有相關元素。
  2. 使用 Sprite Atlas
    • 在 Unity 中使用 Sprite Atlas 來將多個 Sprite 紋理打包到一個單一的紋理資源中。這對於優化遊戲效能非常有幫助,因為它減少了渲染過程中的 draw calls,從而提升遊戲性能,特別是在移動設備上。
    • Sprite Atlas 的優點:
      • Draw call 優化:使用 Sprite Atlas,可以減少 draw calls,讓 Unity 在渲染多個 Sprite 時只用一個 draw call,大大提高性能。
      • 紋理分組:Sprite Atlas 讓你能夠將多個 Sprite 或紋理打包在一起,便於管理和組織資源。
      • 自動打包:Unity 會自動進行紋理打包,將個別的 Sprite 儘可能地安排在 Atlas 中,減少空白區域的浪費,並優化紋理使用。
      • Mipmapping 支援:Sprite Atlas 支援 Mipmapping,這能夠提高在遠距離查看紋理時的渲染質量。
      • 平台適配:可以為不同的裝置平台或螢幕解析度創建不同的 Sprite Atlas 變體,保證在各種設備上的最佳效能。
      • Unity 編輯器整合:你可以直接在 Unity 編輯器中創建與管理 Sprite Atlas,方便遊戲開發者進行資源的視覺化與調整。
  3. 使用透明圖片疊加進行設計對齊
    • 將設計圖層疊加一個稍微透明的圖片,這樣可以幫助你更準確地對齊並組織 UI 視圖,使其符合最終設計。

MVVM

在 Unity 中實作 MVVM

1
2
3
4
5
6
// Model
public class GameData
{
public int level;
public int starts;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ViewModel
public class GameViewModel : MonoBehaviour
{
private GameData gameData;
public int level => gameData.level;
public int starts => gameData.starts;
private void Start()
{
gameData = new GameData();
}
public void UpdateGameData(int level, int score)
{
gameData.level = level;
gameData.starts = score;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// View
public class GameView : MonoBehaviour
{
[SerializeField] private GameViewModel gameViewModel;
private void Start()
{
gameViewModel.UpdateGameData(1, 100);
}
private void Update()
{
Debug.Log("Level: " + gameViewModel.level);
Debug.Log("Starts: " + gameViewModel.starts);
}
}

Scroll View

當建立 Scroll View 時,預設會建立多個組件(Component)。

  • Viewport :決定可視範圍
    • Content :在這個滾動視圖中的內容物件都將放置於這個 Content 中。它的尺寸多大,滾動視角就能滾多遠。
  • Scrollbar Horizontal :水平滾動條,可視需要刪除
  • Scrollbar Vertical :垂直滾動條,可視需要刪除

ScrollRect

ScrollRect 是 滾動視圖中的一個組件。

屬性 說明
Content 控制滾動視圖內容的父物件,它的尺寸多大,滾動視圖就能滾多遠。
Horizontal 是否啟用水平滾動
Vertical 是否啟用垂直滾動
Movement Type 滾動視圖元素的運動類型,主要控制拖動時的回應效果。
Unrestricted : 不受限制,隨便拖動。(一般不會使用)
Elastic :回效果,當滾出邊緣之後,會彈回邊界。(常用)。
Elasticity :回彈係數,控制回彈效果,值越大,回彈越慢。
Clamped :夾緊效果,始終限制在範圍內,沒有回彈效果。
Inertia 移動慣性,如果開啟,鬆開滑鼠後,會有一個移動慣性。
Deceleration Rate :減速率(0~1),0沒有慣性,1不會停止。
Scroll Sensitivity 滾輪(滑鼠中鍵)和觸控板(筆記型電腦)的滾動事件敏感性
Viewport 關聯滾動式圖內容的物件
Horizontal Scrollbar 關聯的水平滾動條物件。
Visibility :是否在不需要時自動隱藏滾動條。
Permanent :一直顯示滾動條。
Auto Hide :自動隱藏滾動條。
Auto Hide And Expend Viewport :自動隱藏滾動條並且自動擴展內容視角(Viewport)。
—— Spacing :滾動條和視角(Viewport)之間的間隔空間
Vertical Scrollbar 關聯的垂直滾動條物件

此外如果想對 Container 中的物件做排列的話,可以使用 Layout Group 組件

  • Grid Layout Group :網格(Grid)方式排列子物件
  • Horizontal Layout Group :水平方向(Width) 排列子物件
  • Vertical Layout Group :垂直方向(Height) 排列子物件

若想讓 Container 的大小自動符合內容物件的大小的話,可以使用 Container Size Filter 組件

RectTransform

RectTransform 組件(Component)是 2D 佈局(layout)中使用的組件,用於控制 UI 組件位置以及對齊方式,繼承自 Transform 組件。

  • Transform 表示一個點,只處理位置(Position),角度(Rotation)與縮放(Scale)
  • RectTransform 表示一個 2D 矩形,UI 元素可以放置在這個矩形內,並加入了錨點(Anchors),軸心點(Pivot),長寬等屬性。
  • 目的是控制 UI 元件大小,讓其可以自動適應解析度。
屬性 說明
Anchor 錨點,為相對於父矩形的錨點,值為 0 ~ 1。
Min:父矩形範圍內 X 和 Y 的最小值
Max:父矩形範圍內 X 和 Y 的最大值
Pivot 矩形範圍內的軸心點,值為 0 ~ 1。影響物件的旋轉,縮放,位置。在錨點計算位置中會用到
Pos (X, Y, Z) 軸心點相對於錨點的位置
Width, Height 矩形的寬高
Left/Top/Right/Bottom 矩形邊緣相的對於錨點的位置。當錨點分離時才會出現。
Ratation 圍繞軸心點的旋轉角度
Scale 縮放大小
BluePrint Mode 啟用後,編輯旋轉和縮放不會影響矩形,只會影響顯示內容
Raw Edit Mode 啟用後,改變軸心點和錨點值不會改變矩形位置,但會影響顯示內容

軸心點(Pivot)

軸心點為矩形範圍內的軸心點,它會影響物件的旋轉,縮放,位置。此外在錨點計算位置中會也用到

  • 在編輯器中,藍色空心圓就是軸心(Pivot)
  • 軸心的值為 0 ~ 1 之間
  • 預設值為 (0.5, 0.5),在矩形的中心。
  • 當值為 (0, 0) 時,會在矩形位置的左下角。
  • 當值為 (1, 1) 時,會在矩形的右上角。
  • 物件會根據軸心坐旋轉

錨點(Anchor)

錨點,為相對於父矩形的錨點。由 Min 和 Max 組成,這四個點在 Unity 編輯器中顯示為四個三角形,並組成一個矩形。

  • Min:父矩形範圍內 X 和 Y 的最小值。
  • Max:父矩形範圍內 X 和 Y 的最大值。
  • 錨點為一個點:當 Min 與 Max 相同時,錨點為一個點。
    • 預設 Min 與 Max 皆為 (0.5, 0.5)。此時,為父元素的中心。
    • Min 與 Max 皆為 (0, 0)。此時,為父元素的左下角。
    • Min 與 Max 皆為 (1.0, 1.0)。此時,為父元素的右上角。
    • 錨點為一個點的時候,編輯器左邊顯示的為 Pos XPox Y,在此情況下,將錨點看作原點座標,而錨點距離軸心的 X 距離為 Pos X ;錨點距離軸心的 Y 距離為 Pos Y
    • 這麼做的原因是為了適應不同解析度。例如,將錨點設定到右上角 Min(0,1) Max(0,1),那麼不論解析度如何改變,這個元件都可以根據錨點保持正確的距離。
    • 錨點為一個點的時候,編輯器左邊顯示的還有 WidthHeight ,這個寬高為元件的寬高,會依據軸心點而有所不同
  • 錨點為矩形:當 Min 與 Max 不同時,錨點會分離為一個矩形
    • Min 設為 (0.2, 0.1) , Max 設為 (0.8, 0.7)
    • 錨點為矩形時,編輯器左邊顯示會變為 LeftTopRightBottom。表示為錨點矩形與元件的矩形所形成的距離, Left 為左邊距離, Top 為上邊距離, Right 為右邊距離, Bottom 為下邊距離,如下圖。
    • 當錨點為矩形時,可以讓元件會根據父元件的變化而拉伸大小。常常用在背景圖。

BluePrint Mode

當勾選了 BluePrint Mode 之後,編輯旋轉和縮放不會影響矩形,只會影響顯示內容

一般不常使用。


Raw Edit Mode

啟用 Raw Edit Mode 後,當改變軸心點和錨點值不會改變矩形位置,但會影響顯示內容

  1. 開始圖
  2. 未啟用 Raw Edit Mode 去更改軸心,會發現軸心往上移動,但是圖形沒有變
  3. 啟用 Raw Edit Mode 去更改軸心,會發現軸心沒有變,但是圖形往下移動

一般不常使用。


使用 Unity 編輯器快速設定軸心與錨點

在編輯器中,會看到如下圖的按鈕,使用滑鼠左鍵點擊,它便會展開

展開後如下圖

使用滑鼠左鍵點擊,就可以快速的設定錨點位置(九宮格佈局)。

按下 Shift , 再點擊滑鼠左鍵,除了錨點位置,同時可以設定軸心點(相對自身矩形)
按下 Alt , 再點擊滑鼠左鍵,除了錨點位置,同時可以設置物件位置


在程式碼中,取得 RectTransform

因為 RectTransform 繼承自 Transform,因此當該遊戲物件擁有 RectTransform 時,只要將它的 Transform 轉型為 RectTransform 即可。

1
RectTransform rectTransform = (this.transform as RectTransform);

Reference:

Graphic Raycaster

Graphic Raycaster 是用來檢查UI輸入事件的圖形射線發射器。它主要負責透過射線檢查玩家和 UI 元素的交互,判斷是否點擊到了 UI 元素

屬性 說明
Ignore Reversed Graphics 是否忽略反轉圖形,預設為 true。(例如 當某個 UI 按鈕的 Rotation X 設為 180 ,這個按鈕就不能點擊)
Blocking Objects 射線被哪些類型的碰撞器(Collider)阻擋,在 Screen Space - Overlay 模式下無效。
Two D:UI 元件會被 2D 碰撞器擋住;
Three D:UI 元件會被 3D 碰撞器擋住;
All: UI 元件會被所有碰撞器擋住。
Blocking Mask 射線被哪些層的碰撞器阻擋,在 Screen Space - Overlay 模式下無效

Canvas Scaler

Canvas Scaler 組件(Component)是控制 UI 縮放的組件。主要負責控制在不同解析度下 UI 元件大小縮放比例,讓 UI 可以自動適應不同的螢幕,但它不負責位置,位置由 (RectTransform)[/2024/07/05/2024-07-05-ugui-recttransform] 組件負責。

Canvas Size 為 Cavas 中 RectTransform 的寬高。

  • 下圖中,
    • 左側的 Screen 為目前裝置的螢幕大小,下圖為 1012 x 515
    • Cavas 中 RectTransform 的 寬高*縮放係數 = 螢幕解析度, (width * X scale) x (height * Y scale), (1012 * 1) x (515 * 1)

Reference Resolution(參考解析度):在 Scale With Screen Size 模式中,它會參與解析度自適應的計算

主要提供三種模式

  • Constant Pixel Size(恆定像素模式):不論螢幕大小如何,UI始終保持相同像素大小。
    • 一般在遊戲中不常用。
    • 它不會讓 UI 元件自動適應解析度大小,除非使用程式碼去修改
  • Scale With Screen Size(縮放模式):根據螢幕大小進行縮放
    • 在遊戲中最常用
  • Constant Physical Size(恆定物理模式):不論螢幕大小如何,UI元素始終保持相同物理大小
  • World (世界模式):當 Canvas 的 Render Mode 選擇為 World Space 時,會將 Canvas Scaler 變為 World。
    • 一般不常更改,主要像素密度,一般值越大越清晰。因此當文字模糊時,可以考慮加大這個值。

Constant Pixel Size(恆定像素模式)

Scale Factor

Scale Factor 縮放 Canvas 中所有 UI 元素。

當 Scale Factor 為 1 且 Screen Size=1024x768 則 Canvas Size 會為 1024x768,圖片大小為原樣

當 Scale Factor 為 2 且 Screen Size=1024x768 則 Canvas Size 會為 512x384,在其中的圖片大小看起來會放大 2 倍。

Reference Pixel Per Unit

Reference Pixel Per Unit 設定多少像素對應 Unity 中的一個單位,預設一個單位為 100 像素。

在計算時,圖片設定中的 Pixels Per Unit 設定會與此參數一起計算。(圖片設定中的 Texture Type 要設為 Sprite(2D and UI)),

Pixels Per Unit=100,表示每單位由 100 像素組成,而圖片解析度是512x512,那麼圖片在世界座標中大小就會變成 512/100 = 5.12x5.12 Unit
Sprite 在世界座標的大小 = 原圖片大小(像素) / Pixels Per Unit

UI的大小 = 原圖片大小(像素) / (Pixels Per Unit / Reference Pixels Per Unit)


Scale With Screen Size

Reference Resolution

Reference Resolution:參考解析度,美術人員出圖的標準解析度。一邊選擇市面上最常見的解析度作為標準。

  • 使用在電腦上的話,可以用 1920x1080
  • 假設你要用於 Android 或是 iOS 的手機遊戲的話,可以用 1080x1440

Screen Match Mode

Screen Match Mode:螢幕匹配模式,當目前螢幕解析度寬高不符合解析度時,用於解析度大小自適應的匹配模式。

Expand(擴大)

Expand:水平或垂直擴大 Canvas Size,讓它高於Reference Resolution,不會裁剪 UI 元素,可能會有黑邊。
計算公式:

  • scaleFactor(縮放係數) = Mathf.Min(screenSize.x(螢幕寬) / m_ReferenceResolution.x(Reference Resolution寬), screenSize.y(螢幕高) / m_ReferenceResolution.y(Reference Resolution高))
  • Canvas Size = 螢幕寬高 / scaleFactor(縮放係數)

例子: Reference Resolution 為 1920x1080 , 螢幕(screen)解析度為 800x600。
scaleFactor = Mathf.Min(800/1920, 600/1080) = Mathf.Min(0.41667, 0.5555) = 0.41667
Canvas Size = (800,600) / 0.41667 = (1920, 1440)

效果:最大程度的顯示所有 UI 元素,保留 UI 所有的細節,可能會有黑邊。

Shirk(收縮)

Shirk:水平或垂直收縮 Canvas Size,讓它低於Reference Resolution,可能會被裁減。
計算公式:

  • scaleFactor(縮放係數) = Mathf.Max(screenSize.x(螢幕寬) / m_ReferenceResolution.x(Reference Resolution寬), screenSize.y(螢幕高) / m_ReferenceResolution.y(Reference Resolution高))
  • Canvas Size = 螢幕寬高 / scaleFactor(縮放係數)

例子: Reference Resolution 為 1920x1080 , 螢幕(screen)解析度為 800x600。
scaleFactor = Mathf.Max(800/1920, 600/1080) = Mathf.Max(0.41667, 0.5555) = 0.5555
Canvas Size = (800,600) / 0.5555 = (1440, 1080)

效果:最大程度的放大 UI 元素,可能會被裁減。

Match Width Or Height

Match Width Or Height:以寬和高進行混合縮放。

  • Match:用於計算寬高匹配值。
    • 當值為 0 時,適合直立螢幕模式的遊戲。將 Canvas Size 寬度設為 Reference Resolution 的寬度,並保持比例不變,螢幕越高時可能會出現黑邊。
    • 當值為 1 時,用在橫向螢幕模式的遊戲。將 Canvas Size 高度設為 Reference Resolution 的高度,並保持比例不變,螢幕越長時可能會出現黑邊。
      計算公式:
      1
      2
      3
      4
      float logWidth = Mathf.Log(screenSize.x / m_ReferenceResolution.x, kLogBase);
      float logHeight = Mathf.Log(screenSize.y / m_ReferenceResolution.y, kLogBase);
      float logWeightedAverage = Mathf.Lerp(logWidth, logHeight, m_MatchWidthOrHeight);
      scaleFactor = Mathf.Pow(kLogBase, logWeightedAverage);

使用建議

  • 存在直立螢幕模式和橫向螢幕模式的遊戲選擇使用 ExpandShirnk
  • 不存在螢幕模式切換的遊戲(即定死為直立螢幕模式或是橫向螢幕模式)選擇使用 Match Width Or Height
  • 直式螢幕稱為 Portrait ,橫式螢幕 Landscape

Constant Physical Size(恆定物理模式)

DPI (Dots Per Inch,每英吋點數)

DPI:圖像每英吋長度內的像素點數

Physical Unit

Physical Unit:物理單位,使用的物理單位種類

  • Centimeters(cm 公分):1 英吋 = 2.54 公分
  • Millimeters(mm 公釐):1 英吋 = 25.4 公釐
  • Inches(英吋): 1 英吋 = 1 英吋
  • Points (點): 1 英吋 = 72 點
  • Picas (派卡): 1 英吋 = 6 派卡

Fallback Screen DPI:備用 DPI ,當找不到裝置 DPI 時,使用此值

Default Sprite DPI:預設圖片 DPI

計算公式:根據 DPI 算出新的 Reference Pixels Per Unit
新 Reference Pixels Per Unit = Reference Pixels Per Unit * Physical Unit / Default Sprite DPI

UI的大小 = 原圖片大小(像素) / (Pixels Per Unit / 新 Reference Pixels Per Unit)

根據裝置的 DPI 進行計算,在不同裝置上的顯示大小更加準確

World 模式

當 Canvas 的 Render Mode 選擇為 World Space 時,會將 Canvas Scaler 變為 World , 3D 世界模式。

Dynamic Pixels Per Unit

UI 中動態建立的點陣圖(例如文字),中的單位像素(類似密度)。一般值越大越清晰。因此當文字模糊時,可以考慮加大這個值。

Reference Pixels Per Unit

單位參考像素,多少像素對應 Unity 中的一個單位,預設一個單位為 100 像素。

Reference:

UGUI Canvas

Canvas 組件(Component)為 UGUI 中的根本,主要用來渲染自己的所有 UI 組件。UI 組件必須要為 Canvas 組件的子組件才可正常顯示。

Render Mode

UI 渲染方式有以下三種

  • Screen Space - Overlay(預設):螢幕空間,覆蓋模式,
    • UI 始終顯示在場景(Scene)內容前方。
    • Pixel Perfect:是否開啟無鋸齒精確渲染,性能換效果,當勾選時會有較好的 UI 顯示,但是較耗費性能
    • SortOrder:排序層編號,用於控制多個 Canvas 時的渲染先後順序。該值越高顯示越前面
    • Target Display:目標裝置,在哪個裝置上顯示。
    • Additional Shader Channels:其他著色器通道,決定著色器可以讀取哪些資料。
  • Screen Space - Camera:螢幕空間,攝影機模式,
    • 3D 物體可以顯示在 UI 之前。
    • Render Camera:用於渲染UI的攝影機,如果不設定,則會類似於覆蓋模式
      • 一般不建議直接使用主攝影機去渲染 UI
    • Plane Distance:UI 平面在攝影機前方的距離,類似整體 Z 軸的感覺。值越小該 Canvas UI 越靠近攝影機。
    • Sorting Layer:Canvas屬於的排序層,可在 Edit -> Project Setting -> Tags and Layers -> Sorting Layers 進行新增與編輯,越下方的層顯示越前面
    • Order in Layer:Canvas在所屬排序層下的順序,該值越高顯示越前面
    • 例如角色狀態,一般會選這種模式,因為玩家角色物件要顯示在 UI 前面。
  • World Space: 世界空間,3D模式。
    • Event Camera:用於處理 UI 事件(Click、Drag)的攝影機。如果不設定,不能正常註冊UI事件,有就是說如果沒設定則像是 Click 事件就無法正常使用。
      • 一般使用主攝影機
    • 把 UI 當作 3D 物件,可以圍著人物或其他物件旋轉,移動。

Reference: