Unity3D屏幕自適應


  • Unity3D的四種坐標系

  1. World Space(世界坐標):我們在場景中添加物體(如:Cube),他們都是以世界坐標顯示在場景中的。transform.position可以獲得該位置坐標。
  2. Screen Space(屏幕坐標):以像素來定義的,以屏幕的左下角為(0,0)點右上角為(Screen.widthScreen.heightZ的位置是以相機的世界單位來衡量的。注:鼠標位置坐標屬於屏幕坐標,Input.mousePosition可以獲得該位置坐標,手指觸摸屏幕也為屏幕坐標,Input.GetTouch(0).position可以獲得單個手指觸摸屏幕坐標。Screen.width = Camera.pixelWidth ,Screen.height = Camera.pixelHeigth
  3. ViewPort Space(視口坐標):視口坐標是標准的和相對於相機的。相機的左下角為(0,0)點,右上角為(1,1)點Z的位置是以相機的世界單位來衡量的。
  4. GUI界面的坐標系:這個坐標系與屏幕坐標系相似,不同的是該坐標系以屏幕的左上角為(0,0)點右下角為(Screen.widthScreen.height

注意:實際屏幕坐標也是三維的,后面三種坐標的Z軸都是相對與攝像機的距離

  • 四種坐標系的轉換

  1. 世界坐標→屏幕坐標camera.WorldToScreenPoint(transform.position);這樣可以將世界坐標轉換為屏幕坐標。其中camera為場景中的camera對象。
  2. 屏幕坐標→視口坐標camera.ScreenToViewportPoint(Input.GetTouch(0).position);這樣可以將屏幕坐標轉換為視口坐標。其中camera為場景中的camera對象。
  3. 視口坐標→屏幕坐標camera.ViewportToScreenPoint();
  4. 視口坐標→世界坐標camera.ViewportToWorldPoint()
  • 【坐標系中的變換】
  1. 平移,旋轉,縮放。
  2. 旋轉和縮放發生在局部坐標系上,以局部坐標原點為中心點,兩者還滿足交換率。
  3. 平移發生在父坐標系上。

所以實現時,會先算好旋轉縮放,再算平移。Unity的轉動順序是YXZ,中間的軸是X。因為圍繞Y軸的水平搖擺最常見,圍繞X軸的垂直俯仰次常用,而圍繞Z軸的歪腦袋最少用。

  • 【Canvas 設置】

  • Canvas.RenderMode:ScreenSpace - Overlay

Canvas作為2D圖像,永遠處於屏幕的最前方,即使沒有相機也能夠看到內容。如果畫布發生大小改變,也能夠自動改變尺寸來匹配屏幕。

  1. 當ScreenOverlay的情況,因為根本沒有經過投影空間,而是直接在屏幕空間繪制,因為在屏幕空間的坐標直接繪制像素,所以Canvas的RectTransform的width*scaleX必須等於屏幕的寬、RectTransform的height*scaleY必須等於屏幕的高。
  2. Overlay情況下,Scene View世界空間的、Canvas屏幕空間的,兩者處於不同空間,它們的大小比較也就沒有可比性了,Unity這里的Editor實現是,屏幕空間1像素等於世界空間1米地把Canvas在SceneView顯示出來

Canvas的核心功能是,自動根據屏幕設備的分辨率、當前的scaleXY,算出正確的width和height,確保和屏幕匹配。

Canvas.RectTransform.scaleXYZ = Canvas.scaleFactor

scaleFactor = Mathf.Min(screenSize.x / m_ReferenceResolution.x, screenSize.y / m_ReferenceResolution.y);
scaleFactor盡可能小,結果是盡量把UI在設備屏幕給放大
1024/1280=0.8 < 720/768 所以縮放是0.8,然后將設備分辨率根據除0.8來得到適合的1280*960大小。

 設備分辨率1024*768時,基准分辯率是1280*720,unity會根據1024和768來進行縮放Canvas的width、height、scale,根據寬固定,縮放高度,即把1280縮小到1024是0.8倍,然后根據720/0.8得到960,大小縮放Scale是0.8,自動調整大小為1280*960。

  • Canvas.RenderMode:ScreenSpace - Camera

可以指定攝像機,和Screen Space-Overlay類似,但是有物體比Canvas更加接近攝像機時會顯示在前面,反之則會被Canvas遮擋。

  1. 由於使用了Camera,所以此時的Canvas和Scene View里的任意GameObject一樣,都是處於世界空間了。
  2. 所以對於ScreenSpace - Camera的Canvas來說,關鍵是如何把處於世界空間中的Canvas能夠占滿投影空間的投影平面。
  3. 所以在Camera模式下,相當要把世界坐標的Canvas轉化為屏幕坐標,要根據2D相機和Canvas的plane distance,Size
  4. Canvas.RectTransform.scaleXYZ = Canvas.scaleFactor * scaleFactorCamera
  5. 正交(Orthographic)Camera 2D模式下,Size的定義為視體的投影平面高的1/2。 比如Camera的Size是3.6,即投影平面高為500

 設備分辨率1024*768時,因為世界空間轉化到屏幕空間,所以Plane Distance相當於移動z軸相反的500,到原點。

size = 3.6米=360像素,所以相機的高度=2*size = 720像素,根據基准分辯率寬就是1280。所以基准分辯率是1280*720,

  • Canvas.height==Screen.height = 768
  • Canvas.height * scaleFactor * scaleFactorCamera = Camera.size * 2
  • 768 * scaleFactor * scaleFactorCamera = 3.6 * 2
  • 所以scaleFactorCamera = Camera.size * 2 / Canvas.height / scaleFactor = Camera.size * 2 / Screen.height / scaleFactor
  • Canvas.RenderMode:World Space:可以指定攝像機,把Canvas視為一個3D物體來處理,可以設置位置和大小。

  • 【Screen Match Mode—Expand】

當屏幕分辨率大於參考分辨率時,選擇變化較小的一個方向(橫向還是縱向),作為放大Canvas Scale的標准,另一方向上的變化則是在整體縮放以后再進行補償性的變化。此舉旨在減少擴大分辨率時由於非等比擴大而對UI整體布局造成影響。適合制作較小標准尺寸,擴充到較大屏幕。

  • 【錨點】

  

AnchorsMin:錨框左下角的點

AnchorsMax:錨框右上角的點

當AnchorsMin和AnchorsMax不在同一水平線或垂直線上的時候,就形成了錨框;

當AnchorsMin和AnchorsMax兩個點重合的時候,就形成了一種特殊情況:錨點

注冊點(Pivot):注冊點就是自身的中心點,也是個歸一化的點

當使用的是錨點的時候,使用的是絕對位置,被子物體定上錨點的父物體的大小改變、移動都不會改變子物體鎖定的錨點到子物體注冊點(Pivot)之間的距離。

當使用的是錨框的時候,使用的是 相對位置(相對父物體的位置),被子物體定上錨框的父物體的移動不會改變子物體鎖定的錨框的AnchorsMin到子物體左下角點之間的距離以及錨框的AnchorsMax到子物體右上角點之間的距離。
  •  總結:

Render Mode 選擇為Camera

UI Scale Mode選擇screen Size

Match Mode選擇Expand

UI內的子物體通過設置錨點固定在UI的位置,可以把父物體設置成跟設備分辨率大小一樣,然后把子物體根據錨點來設置相對位置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM