1. 程式人生 > >Unity 寬度適配 NGUI

Unity 寬度適配 NGUI

原則 插件 0.00 分辨 uiroot 解釋 來看 ima 參數

這是很久之前寫的一篇Note,現在移到Blog上來,可能有些參數,NGUI插件等等不和現在版本相同.不過大概的思路應該不會錯.

ps:

  可能有部分內容是摘抄自其他作者,沒辦法考證了,如有請務必聯系我.標明來源

  大部分遊戲都是高度適配,即固定高度,根據寬高比裁剪兩邊的寬度,而由於這個Note文檔是為一個豎版遊戲寫的.所以有點特立獨行的采用了寬度不變適配,而且只裁剪上方高度,以下邊緣對齊.不過,高度or寬度適配的原理是相同的.

第一部分 對於非NGUI相機 /*
* Unity 寬度不變適配的原理
*
* 以寬度確定為640,適配最小寬高比 1.5 - 1.8,即 640*960 - 640*1152 為例 (寬不變,高度從960 - 1152 之間裁剪)
*
* 1. 計算當前屏幕分辨率下,保持屏幕寬高比不變,寬度縮放為640時的高度
* 屏幕實際高/屏幕實際寬 = x/640
* x = (屏幕實際高/屏幕實際寬) * 640
*
* eg: 手機分辨率為 1136 * 640 -> x = (1136 / 640) * 640 = 1136
*
* 2. 計算當前相機Size
* Unity的相機高度由相機Size確定,Size定了之後,相機高度就固定了,不同的手機會根據這個高度和自身分辨率,確定寬度.
* Unity相機的高度像素 = Size * 2 * 100 (100為Unity相機Size和實際像素的對應關系)
* 當確定寬度不變為640時,需要變的是高,而高的變化又因為Unity根據高度和分辨率確定寬,所以,反推高為
* (Size * 2 * 100) / 640 = 屏幕實際高 / 屏幕實際寬
* Size = ( (屏幕實際高/屏幕實際寬) * 640 ) / (2 * 100)
* 帶入1步驟計算的x --> Size = x / (2 * 100)
*
* eg: Size = 1136 / 200 = 5.68
*
* 3. 計算相機需要在y軸上的移動距離 保持下面對齊
* 由於Unity是高度固定,當我們改變相機Size時,等比放大了寬和高,此時由於上面根據寬計算的高,所以寬度是正好合適的,而此時由於界面是居中的,在相機會在上下兩個位置出現裁剪變化
* (如果Size變小了,即上下兩邊被多裁掉,如果Size變大,則上下會多顯示出來一些內容),為了UI的一致性,我們只允許相機在上面進行裁剪變化,這樣就需要上下移動相機位置.保持下面不變,
* 移動距離 = (固定640寬度時的當前高度 - 1152) / ( 2 * 100 )
* 說明: 如果由於要適配最大高為1152,所以,美術的UI尺寸按照1152進行設計,而固定640寬度的所有設備計算出來的高肯定低於1152(寬高比小於1.8),因此上下會被裁剪,若UI按底部對齊,
* 則需要將相機向下移動,此時,移動的距離即為上面公式得出
*
* eg: (1136 - 1152) / 200 = -0.08 即相機在y軸需要移動 -0.08 單位高度
*
*
* 總結:
* 1. 設計最大高度1152,最小高度960,固定寬度640
* 2. 屏幕高/屏幕寬 * 640 = x;
* 3. Camera.Size = x / 200;
* 4. Camere.Transform.y += (x - 1152) / 200;
*
*/
第二部分 對於NGUI相機 1. 由於 NGUI的自帶了適配的邏輯,並且由於Unity裏一個單位等於實際的100個像素 ,例如:相機大小為1時,其實其高度為 1 * 2 * 100 = 200像素 (相機大小是指的相機框一半的大小,相機中心在中點,所以乘以2)

技術分享

這樣在Unity裏移動Obj十分麻煩,因為Position是100倍的(1單位等於100像素) NGUI為了保證我們在場景裏擺放Obj時方便逐像素的調整,所以在UI Root腳本上自動設置了LocalScale的縮放,詳情見http://blog.csdn.net/monzart7an/article/details/23366443 而且保證了相機的尺寸始終保持為1.這樣UIRoot上的縮放計算方式為: ( 1 / 設定高度 ) * 2 例如 : 設置固定高為 960 則縮放應該為 0.0020833 若固定高為960 , 實際Camera.Size = 960 /( 2 * 100 ) = 4.8 為了把Size固定在1,相當於縮放了4.8個Unity單位,相當於縮放了4.8*100 = 480個像素單位,即縮放比例為 1/480 = 0.0020833 所以UIRoot的LocalScale =1 / ( 高 / (2 * 100) * 100 ) = 1/(高/2) = 2 / 高, 此時如果沿著高移動一個物體,當移動960像素時,實際移動的Unity單位為 960 * ( 2 / 960 ) = 2 ,而Camera.Size = 1, Camera的高為 1 * 2 = 2. 所以正好是移動了一個相機的顯示區域,所以,在相機的顯示區域來看,高度 為2個Unity單位,也即960個像素單位,所以,我們在拼接UI時,可以按照像素進行拼接. 在我們進行寬度適配時,由於上述的NGUI適配算法,所以根據自身項目情況,我們需要動態的調整Camera.Size 和 Camera.LocalPostion.y 以保證顯示區域始終是向下對齊而且寬度不變的,如下圖 技術分享技術分享技術分享技術分享

分別對上圖進行解釋,圖中以固定NUGI高為1152進行示例,圖中黑色區域為1152*640像素

1) 圖一中: Camera.Size = 1. Camera.localPos.y = 0, 屏幕分辨率為 1152 * 640, 寬高比為 1.8 , UIPanel縮放為 2/1152

此時可以看到圖中相機尺寸和UIPanel尺寸完全重合,不需要對Camera做任何調整

2) 圖二中:Camera.Size = 1. Camera.localPos.y = 0, 屏幕分辨率為 960 * 640 , 寬高比為 1.5 , UIPanel縮放為 2/1152

此時可以看到當分辨率變了之後,寬高比變小,由於固定了高,所以高不變的情況下,寬變大(實際變為1152/1.5=768),此時需要縮小Camera.Size以使得在寬高比變小後,Camera顯示的寬依然保持640,

所以根據固定高1152.和固定高之後實際寬=768,寬需要縮放到640,即縮放比例為 640 / 768 = 0.8333,所以Camera.Size = 0.8333 (見圖三)

3)圖三中:Camera.Size = 0.8333. Camera.localPos.y = 0, 屏幕分辨率為 960 * 640 , 寬高比為 1.5 , UIPanel縮放為 2/1152

此時Camera.Size已經縮放為0.8333,相機區域完全和960*640顯示邊界重合,但是由於相機的寬和高同時縮小.導致相機顯示區域的上下部分被裁剪,而為了保證向下對齊,我們需要把相機向下移動,以保證實現寬適配+向下對齊.

Camera向下移動的計算方法為: (實際高 - 固定高) / 2 即為 ( 960 - 1152 ) / 2 = -96, 由於向下移動,所以得出負數 4)圖四中:Camera.Size = 0.8333. Camera.localPos.y = -96, 屏幕分辨率為 960 * 640 , 寬高比為 1.5 , UIPanel縮放為 2/1152 圖四是根據寬度適配,向下對齊的原則完成調整後的效果,可以看到圖四(分辨率960*640)的下半部分和圖一(分辨率1152*640)的下半部分完全相同,只是在圖一的上部分進行了裁剪, 所以,美術在拼UI界面時可以按照寬度不變,向下對齊的原則進行拼接

<如有錯誤,敬請指出,不勝感謝>

Unity 寬度適配 NGUI