Unity3d:Canvas適配屏幕分辨率與錨點(diǎn)(Anchors與Pivot)

系列傳送門

IOS:
IOS:使用shell命令打包并上傳Itunes
Unity3d:
Unity3d:Canvas適配屏幕分辨率與錨點(diǎn)(Anchors與Pivot)
Unity3d:在屏幕邊緣顯示其他玩家方位
Unity3d:命令行打包Android
Unity3d:命令行編譯IOS
Unity3d:使用Jenkins自動(dòng)編譯打包IOS(只能打包Development)
Unity3d:使用Jenkins自動(dòng)編譯打包IOS(打包Ad-hoc,上傳itunes)

提前預(yù)知:文章中Width和Height等屬性的使用是偽代碼缀踪,理解意思就好居砖。

1、Root Canvas(適配屏幕分辨率)

所有的UI都有一個(gè)Root Canvas驴娃,該Canvas的RectTransform不可修改奏候。
所有Canvas坐標(biāo)系方向都是右側(cè)為X軸正方向上方為Y軸正方向唇敞。
該Canvas還帶有一個(gè)Canvas Scaler組件蔗草,可以通過該組件適配不同的屏幕分辨率。

必須注意:Canvas的寬高和屏幕分辨率不是一回事疆柔。

UI Scale Mode

Canvas Scaler中有一個(gè)UI Scale Mode屬性咒精,用于確定畫布中的UI元素如何縮放。

以下假如屏幕分辨率為1500 * 3000旷档。

1.1模叙、Constant Pixel Size

使Canvas寬高保持與屏幕分辨率一致。屏幕分辨率有多大鞋屈,Canvas寬高就有多大( Scale Factor縮放因子為1時(shí))范咨。

  • Scale Factor
    按此因子縮放畫布中的所有UI元素。
    默認(rèn)縮放因子為1厂庇,則此時(shí)Canvas寬高也為1500 * 3000渠啊。
    如果縮放因子為2,則Canvas寬高為屏幕分辨率/2权旷,即750 * 1500替蛉,也就是說Canvas上的UI是原來的2倍大小。

所以,Canvas寬高 = 屏幕分辨率 / 縮放因子灭返。

1.2盗迟、Scale With Screen Size

使Canvas的寬高比與屏幕分辨率的寬高比保持一致。
縮放時(shí)需要基于下面的Reference Resolution(參考分辨率)進(jìn)行縮放熙含。
因?yàn)榇藭r(shí)屏幕分辨率的寬高比為:1500 / 3000 = 0.5罚缕,所以在該模式下,無論怎么調(diào)整參數(shù)怎静,Canvas寬高比也一直為0.5邮弹,不會(huì)變。
所以蚓聘,Canvas寬高比 = 屏幕分辨率寬高比腌乡。

1.2.1、Reference Resolution

縮放時(shí)用的參考分辨率夜牡。
下面假設(shè)參考分辨率是1080 * 1920与纽。

1.2.2、Screen Match Mode

如果屏幕分辨率與參考分辨率的寬高比不一致塘装,則根據(jù)選擇的模式對(duì)Canvas寬高進(jìn)行縮放急迂。
如果屏幕分辨率與參考分辨率的寬高比一致,該選項(xiàng)怎么調(diào)都不管用蹦肴。

1.2.2.1僚碎、Match Width or Height

基于下面Match對(duì)Canvas寬高進(jìn)行縮放。

  • Match
    取值范圍(0~1)的浮點(diǎn)數(shù)阴幌。
    是一個(gè)縮放參考值勺阐,用于確定對(duì)參考分辨率的寬進(jìn)行縮放,還是對(duì)參考分辨率的高進(jìn)行縮放矛双。
    越靠近左邊的Width渊抽,則更傾向于對(duì)參考分辨率的高進(jìn)行縮放。
    越靠近右邊的Height背零,則更傾向于對(duì)參考分辨率的寬進(jìn)行縮放腰吟。
    拖動(dòng)Slider或設(shè)置值之后,Unity會(huì)自動(dòng)計(jì)算對(duì)應(yīng)的Canvas寬高徙瓶。

    • 把Slider拖動(dòng)到Width最左邊毛雇,即Match=0。此時(shí)只對(duì)Canvas高進(jìn)行縮放侦镇,Canvas的寬與參考分辨率的寬保持一致灵疮,都是1080。因?yàn)镃anvas寬高比為0.5壳繁,所以此時(shí)Canvas高為1080 / 0.5 = 2160震捣。

    • 把Slider拖動(dòng)到Height最右邊荔棉,即Match=1。此時(shí)只對(duì)Canvas寬進(jìn)行縮放蒿赢,Canvas的高與參考分辨率的高保持一致润樱,都是1920。因?yàn)镃anvas寬高比為0.5羡棵,所以此時(shí)Canvas寬為1920 * 0.5 = 960壹若。

    • 把Slider拖動(dòng)到介于Width與Height中間的一個(gè)位置,比如Match=0.2皂冰,更靠近左邊的Width店展,此時(shí)會(huì)更傾向于對(duì)參考分辨率的高進(jìn)行縮放。

1.2.2.2秃流、Expand

縮放后赂蕴,Canvas的寬高一定不低于參考分辨率的寬高。

  • 假如使用參考分辨率的寬進(jìn)行縮放舶胀,即保持Canvas的高等于參考分辨率的高概说。因?yàn)镃anvas寬高比為0.5,所以此時(shí)Canvas的寬為1920 * 0.5 = 960嚣伐,低于參考分辨率的寬席怪,不符合Expand模式的縮放要求。

  • 假如使用參考分辨率的高進(jìn)行縮放纤控,即保持Canvas的寬等于參考分辨率的寬。因?yàn)镃anvas寬高比為0.5碉纺,所以此時(shí)Canvas的高為1080 / 0.5 = 2160船万,高于(不低于)參考分辨率的高,完全符合Expand模式的縮放要求骨田。

  • 該模式下耿导,最終Canvas的寬高分別是1080,2160态贤。

1.2.2.3舱呻、Shrink

縮放后,Canvas的寬高一定不高于參考分辨率的寬高悠汽。與Expand類似箱吕。

  • 該模式下,最終Canvas的寬高分別是960柿冲,1920茬高。

2、UI的錨點(diǎn)(Anchors與Pivot)

錨點(diǎn)說難不難假抄,只是不好描述怎栽,但可以用例子來說明丽猬。
假如Canvas擁有一個(gè)Image節(jié)點(diǎn)。
對(duì)于Image所在的坐標(biāo)系熏瞄,坐標(biāo)系方向與Canvas坐標(biāo)系方向相同脚祟。

下面看下Image節(jié)點(diǎn)的錨點(diǎn)在Canvas的不同位置的情況:

left center right stretch
top 左上角
單錨點(diǎn)
Anchors.Min(0, 1)
Anchors.Max(0, 1)
頂部邊框的中心
單錨點(diǎn)
Anchors.Min(0.5, 1)
Anchors.Max(0.5, 1)
右上角
單錨點(diǎn)
Anchors.Min(1, 1)
Anchors.Max(1, 1)
左上角、右上角
雙錨點(diǎn)
Anchors.Min(0, 1)
Anchors.Max(1, 1)
middle 左側(cè)邊框的中心
單錨點(diǎn)
Anchors.Min(0, 0.5)
Anchors.Max(0, 0.5)
正中心
單錨點(diǎn)
Anchors.Min(0.5, 0.5)
Anchors.Max(0.5, 0.5)
右側(cè)邊框的中心
單錨點(diǎn)
Anchors.Min(1, 0.5)
Anchors.Max(1, 0.5)
左側(cè)邊框的中心强饮、右側(cè)邊框的中心
雙錨點(diǎn)
Anchors.Min(0, 0.5)
Anchors.Max(1, 0.5)
bottom 左下角
單錨點(diǎn)
Anchors.Min(0, 0)
Anchors.Max(0, 0)
底部邊框的中心
單錨點(diǎn)
Anchors.Min(0.5, 0)
Anchors.Max(0.5, 0)
右下角
單錨點(diǎn)
Anchors.Min(1, 0)
Anchors.Max(1, 0)
左下角由桌、右下角
雙錨點(diǎn)
Anchors.Min(0, 0)
Anchors.Max(1, 0)
stretch 左上角、左下角
雙錨點(diǎn)
Anchors.Min(0, 0)
Anchors.Max(0, 1)
底部邊框的中心胡陪、頂部邊框的中心
雙錨點(diǎn)
Anchors.Min(0.5, 0)
Anchors.Max(0.5, 1)
右上角沥寥、右下角
雙錨點(diǎn)
Anchors.Min(1, 0)
Anchors.Max(1, 1)
左下角、左下角柠座、右上角邑雅、右下角
四錨點(diǎn)
Anchors.Min(0, 0)
Anchors.Max(1, 1)

2.1、單錨點(diǎn)

單錨點(diǎn)妈经,從Unity上看淮野,就是4個(gè)小三角形聚在一個(gè)點(diǎn)。
單錨點(diǎn)在Canvas的位置(假設(shè)為點(diǎn)p)都滿足以下邏輯:

注意:錨點(diǎn)不一定是Image所在坐標(biāo)系的原點(diǎn)吹泡。

  • 錨點(diǎn)的Pivot(0, 0)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x + Image.Width/2, p.y + Image.Height/2)骤星。
  • 錨點(diǎn)的Pivot(0, 0.5)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x + Image.Width/2, p.y)
  • 錨點(diǎn)的Pivot(0, 1)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x + Image.Width/2, p.y - Image.Height/2)爆哑。
  • 錨點(diǎn)的Pivot(0.5, 0)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x, p.y + Image.Height/2)洞难。
  • 錨點(diǎn)的Pivot(0.5, 0.5)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x, p.y),此時(shí)錨點(diǎn)即Image所在坐標(biāo)系的原點(diǎn)揭朝。
  • 錨點(diǎn)的Pivot(0.5, 1)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x, p.y - Image.Height/2)队贱。
  • 錨點(diǎn)的Pivot(1, 0)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x - Image.Width/2, p.y + Image.Height/2)
  • 錨點(diǎn)的Pivot(1, 0.5)
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x - Image.Width/2, p.y)潭袱。
  • 錨點(diǎn)的Pivot(1, 1)?
    Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo)(p.x - Image.Width/2, p.y - Image.Height/2)柱嫌。

可以總結(jié)出以下公式(p為單錨點(diǎn)在Canvas的位置,pivot為單錨點(diǎn)的Pivot屬性):
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (p.x + Image.Width * (0.5 - pivot.x), p.y + Image.Height * (0.5 - pivot.y))屯换。

2.2编丘、雙錨點(diǎn)

雙錨點(diǎn),從Unity上看彤悔,就是2個(gè)小三角形聚在一個(gè)點(diǎn)嘉抓。

2.2.1、左上角蜗巧、左下角

左上角有2個(gè)小三角形掌眠,左下角有2個(gè)小三角形
此時(shí),Image擁有PosX幕屹,Top蓝丙,Width级遭,Bottom這四個(gè)位置參數(shù)。
而且渺尘,錨點(diǎn)的Pivot的Y不起作用挫鸽。
Image的Height = (Canvas.Height - Top - Bottom) / 2
如果設(shè)置Image的Top鸥跟,Bottom都為0的話丢郊,則Image的高會(huì)與Canvas的高一致。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width * (0.5 - Pivot.x) + PosX , Image.Height / 2 + Top)医咨。

2.2.2枫匾、底部邊框的中心、頂部邊框的中心

底部邊框的中心有2個(gè)小三角形拟淮,頂部邊框的中心有2個(gè)小三角形
此時(shí)干茉,Image擁有PosX,Top很泊,Width角虫,Bottom這四個(gè)位置參數(shù)。
而且委造,錨點(diǎn)的Pivot的Y不起作用戳鹅。
Image的Height = (Canvas.Height - Top - Bottom) / 2
如果設(shè)置Image的Top昏兆,Bottom都為0的話枫虏,則Image的高會(huì)與Canvas的高一致。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width * (0.5 - Pivot.x) + Canvas.Width / 2 + PosX , Image.Height / 2 + Top)爬虱。

2.2.3模软、右上角、右下角

右上角有2個(gè)小三角形饮潦,右下角有2個(gè)小三角形
此時(shí),Image擁有PosX携狭,Top继蜡,Width,Bottom這四個(gè)位置參數(shù)逛腿。
而且稀并,錨點(diǎn)的Pivot的Y不起作用
Image的Height = (Canvas.Height - Top - Bottom) / 2单默。
如果設(shè)置Image的Top碘举,Bottom都為0的話,則Image的高會(huì)與Canvas的高一致搁廓。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width * (0.5 - Pivot.x) + Canvas.Width + PosX , Image.Height / 2 + Top)引颈。

2.2.4耕皮、左上角、右上角

左上角有2個(gè)小三角形蝙场,右上角有2個(gè)小三角形
此時(shí)凌停,Image擁有Left,PosY售滤,Right罚拟,Height這四個(gè)位置參數(shù)。
而且完箩,錨點(diǎn)的Pivot的X不起作用赐俗。
Image的Width = (Canvas.Width - Left - Right) / 2
如果設(shè)置Image的Left弊知,Right都為0的話阻逮,則Image的寬會(huì)與Canvas的寬一致。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width / 2 + Left , Image.Height * (0.5 - Pivot.x) + PosY)吉捶。

2.2.5夺鲜、左側(cè)邊框的中心、右側(cè)邊框的中心

左側(cè)邊框的中心有2個(gè)小三角形呐舔,右側(cè)邊框的中心有2個(gè)小三角形
此時(shí)币励,Image擁有Left,PosY珊拼,Right食呻,Height這四個(gè)位置參數(shù)。
而且澎现,錨點(diǎn)的Pivot的X不起作用仅胞。
Image的Width = (Canvas.Width - Left - Right) / 2
如果設(shè)置Image的Left剑辫,Right都為0的話干旧,則Image的寬會(huì)與Canvas的寬一致。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width / 2 + Left , Image.Height * (0.5 - Pivot.x) + Canvas.Height / 2 + PosY)妹蔽。

2.2.6椎眯、左下角、右下角

左下角有2個(gè)小三角形胳岂,右下角有2個(gè)小三角形
此時(shí)编整,Image擁有Left,PosY乳丰,Right掌测,Height這四個(gè)位置參數(shù)。
而且产园,錨點(diǎn)的Pivot的X不起作用汞斧。
Image的Width = (Canvas.Width - Left - Right) / 2夜郁。
如果設(shè)置Image的Left,Right都為0的話断箫,則Image的寬會(huì)與Canvas的寬一致拂酣。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width / 2 + Left , Image.Height * (0.5 - Pivot.x) + Canvas.Height + PosY)

2.3仲义、四錨點(diǎn)(左下角婶熬、左下角、右上角埃撵、右下角)

四錨點(diǎn)赵颅,從Unity上看,就是4個(gè)小三角形全都是分散的(左下角暂刘、左下角饺谬、右上角、右下角)谣拣。
此時(shí)募寨,Image擁有Left,Top森缠,Right拔鹰,Bottom這四個(gè)位置參數(shù)。
而且贵涵,錨點(diǎn)的Pivot不起作用列肢。
Image的Width = (Canvas.Width - Left - Right) / 2
Image的Height = (Canvas.Height - Top - Bottom) / 2宾茂。
如果設(shè)置Image的Left瓷马,Top,Right跨晴,Bottom都為0的話欧聘,則Image的寬高會(huì)與Canvas的寬高一致。
Image所在坐標(biāo)系原點(diǎn)在Canvas中的坐標(biāo) = (Image.Width / 2 + Left , Image.Height / 2 + Top)端盆。

3树瞭、屏幕坐標(biāo)與Canvas坐標(biāo)相互轉(zhuǎn)換

3.1、屏幕坐標(biāo)系與Canvas坐標(biāo)系

屏幕坐標(biāo)系與Canvas坐標(biāo)系都是左下角為原點(diǎn)爱谁,向右為X軸正方向,向上為Y軸正方向孝偎。

3.2访敌、屏幕坐標(biāo)轉(zhuǎn)換到Canvas坐標(biāo)系上

在屏幕坐標(biāo)系上有個(gè)點(diǎn)P(x, y),我們先把屏幕分辨率的寬高縮放到與Canvas的寬高一致衣盾,此時(shí)P點(diǎn)的坐標(biāo)也會(huì)隨著縮放寺旺。
因?yàn)槠聊蛔鴺?biāo)系與Canvas坐標(biāo)系都是左下角為原點(diǎn)爷抓,所以縮放完成后的P的位置(記作P2),就是P點(diǎn)在Canvas坐標(biāo)系上的位置阻塑。
P2 = (P.x * Canvas.Width / Screen.Width, P.y * Canvas.Height / Screen.Height)
現(xiàn)在有一個(gè)Image UI蓝撇,我們先把該Image的錨點(diǎn)設(shè)置為左下角(Anchors.Min(0, 0),Anchors.Max(0, 0))陈莽,然后把P2的位置賦值給Image的anchoredPosition渤昌,此時(shí)該Image剛好就在P點(diǎn)的位置。

3.3走搁、Canvas坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)系上

在Canvas坐標(biāo)系上有一個(gè)Image UI独柑,我們先把該Image的錨點(diǎn)設(shè)置為左下角(Anchors.Min(0, 0),Anchors.Max(0, 0))私植,然后把Canvas的寬高縮放到與屏幕分辨率的寬高一致忌栅,此時(shí)Image的anchoredPosition(記作P)也會(huì)隨著縮放。
因?yàn)槠聊蛔鴺?biāo)系與Canvas坐標(biāo)系都是左下角為原點(diǎn)曲稼,所以縮放完成后的Image的anchoredPosition(記作P2)索绪,就是Image在屏幕坐標(biāo)系上的位置。
P2 = (P.x * Screen.Width / Canvas.Width, P.y * Screen.Height / Canvas.Height)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贫悄,一起剝皮案震驚了整個(gè)濱河市瑞驱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌清女,老刑警劉巖钱烟,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫡丙,居然都是意外死亡拴袭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門曙博,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拥刻,“玉大人,你說我怎么就攤上這事父泳“愫撸” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵惠窄,是天一觀的道長蒸眠。 經(jīng)常有香客問我,道長杆融,這世上最難降的妖魔是什么楞卡? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上蒋腮,老公的妹妹穿的比我還像新娘淘捡。我一直安慰自己,他們只是感情好池摧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布焦除。 她就那樣靜靜地躺著,像睡著了一般作彤。 火紅的嫁衣襯著肌膚如雪膘魄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天宦棺,我揣著相機(jī)與錄音瓣距,去河邊找鬼。 笑死代咸,一個(gè)胖子當(dāng)著我的面吹牛蹈丸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呐芥,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼逻杖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了思瘟?” 一聲冷哼從身側(cè)響起荸百,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滨攻,沒想到半個(gè)月后够话,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡光绕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年女嘲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诞帐。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡欣尼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出停蕉,到底是詐尸還是另有隱情愕鼓,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布慧起,位于F島的核電站菇晃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚓挤。R本人自食惡果不足惜磺送,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一剩失、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧册着,春花似錦荞怒、人聲如沸觉阅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阅签。三九已至十办,卻和暖如春馅扣,著一層夾襖步出監(jiān)牢的瞬間盈蛮,已是汗流浹背兄纺。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工大溜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人估脆。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓钦奋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親疙赠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子付材,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容