【Unity学习笔记】Canvas Scaler组件
聲明:此篇文章是個人學(xué)習(xí)筆記,并非教程,所以內(nèi)容可能不夠嚴(yán)謹(jǐn)。可作參考,但不保證絕對正確。如果你發(fā)現(xiàn)我的文章有什么錯誤,非常歡迎指正,謝謝哦
UI自適應(yīng)
在學(xué)習(xí)Canvas Scaler組件之前,先來了解一下UI自適應(yīng),UI自適應(yīng)就是讓我們可以不對每種分辨率的屏幕上都設(shè)計一種UI布局,而只需要在開發(fā)的時候設(shè)計一種UI布局,就可以讓UI在不同分辨率的屏幕上都能盡量正常的顯示,這將會節(jié)省巨大的工作量。
而這一次要學(xué)習(xí)的Canvas Scaler組件就是用來快速的實現(xiàn)UI自適應(yīng)功能的組件。
Canvas Scaler組件
官方文檔:https://docs.unity3d.com/cn/current/Manual/script-CanvasScaler.html
畫布縮放器組件用于控制畫布中 UI 元素的整體縮放和像素密度。此縮放會影響畫布下的所有內(nèi)容,包括字體大小和圖像邊框。我們可以利用該組件去縮放全部UI元素從而適配不同分辨率的屏幕。
Canvas Scaler組件有三種模式,依次介紹
| UI Scale Mode | 縮放模式 |
| Constant Pixel Size | 無論屏幕大小如何,UI 元素都保持相同的像素大小。 |
| Scale With Screen Size | 屏幕越大,UI 元素越大。常用來設(shè)置UI自適應(yīng)。 |
| Constant Physical Size | 無論屏幕大小和分辨率如何,UI 元素都保持相同的物理大小。 |
第一種模式 Constant Pixel Size
這個模式也是在Canvas在沒有附加任何Canvas scaler情況下的默認(rèn)功能。但是,借助Canvas Scaler中的“Scale Factor”屬性,可以自由設(shè)定UI元素縮放的比例。
在這種模式下,錨點如果采用“矩形模式”(我自己取得名字)就會呈現(xiàn)一種在Rect Transform中提到的縮放效果,不過看起來挺奇怪的
在這種模式下,錨點如果采用“點模式”(還是我自己取得名字)也依然會按照在Rect Transform中提到的固定效果。但需要注意的是,這個時候UI元素的效果就會像該元素的名字一樣,保持像素大小不變,不管屏幕大小如何變動。
| Scale Factor | 按此系數(shù)縮放畫布中的所有 UI 元素,即這個數(shù)是全部UI元素的縮放比例。 |
| Reference Pixels Per Unit | 如果精靈具有此“Pixels Per Unit”設(shè)置,則精靈中的每個像素將覆蓋 UI 中的一個單位。 |
在Constant Pixel Size模式下,用代碼實現(xiàn)UI自適應(yīng)
在這種模式下,不管屏幕大小如何變化,UI元素會保持原大小不變。但是我們可以通過Scale Factor去縮小放大這些UI元素,縮放是按照UI元素原比例進(jìn)行縮放,所以要實現(xiàn)UI自適應(yīng)關(guān)鍵是確定Scale Factor設(shè)為多大值。
可以看出,當(dāng)屏幕尺寸發(fā)生變化時,UI元素?zé)o非是太寬,太長或者既太寬又太長而造成重疊。
通常屏幕尺寸變化要同時考慮寬、高兩邊的變化。但是我們只能設(shè)置一個縮放比例Scale Factor。因此要實現(xiàn)能用的UI自適應(yīng)就要在這個系數(shù)上面做文章。
為了便于理解,先只考慮一側(cè)的變化,這里拿寬度舉例。
1.首先所有的UI元素的錨點要為“點模式”(可以將錨點放在四個角之一,這樣UI元素距離四個角的距離不變),這樣所有UI元素才能統(tǒng)一實現(xiàn)原比例顯示。
2.在代碼中將“運行時的屏幕寬度”除以“編輯時的屏幕寬度”,將Scale Factor的值設(shè)為該值,從而讓所有UI元素縮放相應(yīng)倍數(shù)。為了方便觀察我把自適應(yīng)代碼放在了Update函數(shù),實際上只需要放在Start函數(shù)中,運行一次即可。
void Start(){canvasScaler = GetComponent<CanvasScaler>();}// Update is called once per framevoid Update(){//獲取運行時的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height;//編輯時屏幕分辨率為650x400//將ScaleFactor設(shè)為 實際屏幕寬度/編輯時屏幕寬度canvasScaler.scaleFactor = screenWidth / 650;}效果:當(dāng)屏幕寬度隨意變化,UI元素能隨之按比例縮放。但當(dāng)屏幕高度變化時,UI無變化,有可能會發(fā)生UI元素重疊的情況。
當(dāng)同時考慮寬和高的變化時,可以有很多方案。這里記錄三種:
方案一:按寬高權(quán)重大小決定最終縮放效果
方案邏輯:
分別計算出寬高的縮放比例,再根據(jù)權(quán)重來分配寬縮放比例、高縮放比例對最終效果的影響程度。
這個方案可以選擇寬、高的縮放分別對最終結(jié)果的影響大小。
void Update(){//獲取運行時的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height; //總之,應(yīng)當(dāng)隨下面兩個浮點數(shù)的較小那個變化float w = screenWidth / 650;float h = screenHeight / 400;//編輯時屏幕分辨率為650x400canvasScaler.scaleFactor = propotion * h + (1 - propotion) * w;}效果:當(dāng)propotion為0時,只有寬度會影響UI縮放,高度不影響。當(dāng)propotion為1時,只有高度會影響UI縮放,寬度不會。而propotion在0~1之間時,寬高按權(quán)重影響UI縮放。在某些分辨率下也會出現(xiàn)UI重疊的情況。
效果圖
方案二 :按縮放比例較小的那一側(cè)縮放:
方案邏輯:
1.如果高、寬兩側(cè)中有一側(cè)縮小一側(cè)放大,那么就取縮小那一側(cè)的值
2.如果高、寬兩側(cè)都縮小,那么就取縮小程度較大的那一側(cè)的值
3.如果高、寬兩側(cè)都放大,那么就取放大程度較小的那一側(cè)的值
總之就取 實際屏幕高/編輯時屏幕高 實際屏幕寬/編輯時屏幕寬 較小的那個值
代碼:為了更好觀察才放在了Update函數(shù)中,實際上只需要放在Start函數(shù)中,運行一次即可。
void Update(){//獲取運行時的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height; //總之,應(yīng)當(dāng)隨下面兩個浮點數(shù)的較小那個變化float w = screenWidth / 650;float h = screenHeight / 400;//編輯時屏幕分辨率為650x400if (w < h)canvasScaler.scaleFactor = w;elsecanvasScaler.scaleFactor = h;}效果:當(dāng)屏幕寬度隨意變化,UI元素能隨之按比例縮放,UI不會發(fā)生重疊。但如果有背景UI,就會發(fā)現(xiàn)當(dāng)屏幕大小發(fā)生變化時,如果寬高變化率不同就會相比原來多擴展(expand)出一部分空白(下圖呈黑色)。
方案三:按縮小比例較大的那一側(cè)縮放
方案邏輯:
1.如果高、寬兩側(cè)中有一側(cè)縮小一側(cè)放大,那么就取放大那一側(cè)的值
2.如果高、寬兩側(cè)都縮小,那么就取縮小程度較小的那一側(cè)的值
3.如果高、寬兩側(cè)都放大,那么就取放大程度較大的那一側(cè)的值
總之就取 實際屏幕高/編輯時屏幕高 實際屏幕寬/編輯時屏幕寬 較大的那個值
代碼:為了更好觀察才放在了Update函數(shù)中,實際上只需要放在Start函數(shù)中,運行一次即可。
void Update(){//獲取運行時的屏幕分辨率screenWidth = UnityEngine.Screen.width;screenHeight = UnityEngine.Screen.height; //總之,應(yīng)當(dāng)隨下面兩個浮點數(shù)的較小那個變化float w = screenWidth / 650;float h = screenHeight / 400;//編輯時屏幕分辨率為650x400if (w > h) //只需要把這里的<改成>canvasScaler.scaleFactor = w;elsecanvasScaler.scaleFactor = h;}效果:在一定程度上能夠自適應(yīng),但是會出現(xiàn)UI元素重疊的情況.如果有背景UI就可以發(fā)現(xiàn),隨屏幕變化背景UI會出現(xiàn)裁剪的情況。
效果圖
三種方案的總結(jié):
方案一:可以通過調(diào)整權(quán)重,來影響在不同分辨率屏幕的效果。最終可以通過不斷調(diào)整數(shù)值選擇一種在所有已知的分辨率里面平均效果不錯的權(quán)重。
方案二:在所有分辨率里面UI均不會重疊,可以自動縮放。但是可能會在某些分辨率下的效果不好,比如縮得太小。
方案三:在寬、高變化程度差不多得情況下得效果和方案二差不多,但是有一點點視覺上得區(qū)別。不適合寬高比例變化程度差異很大得情況。
這三種方案并不需要手寫代碼,可以直接設(shè)置,怎么設(shè)置看下面。
第二種模式 Scale With Screen Size
| Reference Resolution | 參考分辨率/編輯時的分辨率/設(shè)計UI布局時的分辨率。最好在每次項目開始時就設(shè)置好。 |
| Screen Match Mode | 當(dāng)實際分辨率與參考分辨率(Reference Resolution)不同時,縮放畫布的模式。這個屬性就是用來直接設(shè)置上面那三種方案的。 Match Width or Height 僅以寬度或高度或按二者的某種權(quán)重比值對畫布進(jìn)行縮放,這一項和上面的方案一類似,但是效果有些差異,估計是計算方法有異,權(quán)重具體看Match屬性。 Expand 水平和垂直方向都會縮放,經(jīng)過測試,此項效果和上面的方案二效果一模一樣。 Shrink 經(jīng)過測試,此項效果和上面的方案三效果一模一樣。 偶然間發(fā)現(xiàn)自己上面手寫的三個方案的代碼功能竟然和這里一樣,所以我有理由猜測這個模式是基于Constant Pixels Size模式寫出來的,或者二者有同樣的父類? 這三種模式的特點上面已經(jīng)說過了,估計實際項目中要根據(jù)上線平臺的屏幕分辨率多多嘗試,看哪個效果更好就選哪個。 |
| Match | 當(dāng)Match移到最左邊時,僅寬度變化會影響畫布縮放,當(dāng)Match移到最右邊時,僅高度會影響畫布縮放。當(dāng)Match移到中間某個點時,按二者的權(quán)重對畫布進(jìn)行縮放。 |
| Reference Pixels Per Unit | 如果精靈具有此“Pixels Per Unit”設(shè)置,則精靈中的每個像素將覆蓋 UI 中的一個單位。 |
第三種模式:Constant Physical Size
這種模式看起來就感覺不常用,先不過多研究,等涉及到的時候再回過頭來看看。
| Physical Unit | 用于指定位置和大小的物理單位。;centimeter 厘米;millimeter 毫米;inche 英寸;Point 點;pica 派卡 |
| Fallback Screen DPI | 在屏幕 DPI 未知時采用的 DPI。 |
| Default Sprite DPI | 用于精靈的每英寸像素,使其“Pixels Per Unit”設(shè)置與“Reference Pixels Per Unit”設(shè)置匹配。 |
| Reference Pixels Per Unit | 如果精靈具有此“Pixels Per Unit”設(shè)置,則其 DPI 將與“Default Sprite DPI”設(shè)置匹配。 |
總結(jié)
以上是生活随笔為你收集整理的【Unity学习笔记】Canvas Scaler组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中考计算机操作题试题文档,初中信息技术中
- 下一篇: Unity Canvas Scaler