1. 程式人生 > >Unity中四種座標系之間的關聯

Unity中四種座標系之間的關聯

一 World Space(世界座標):

世界座標按照笛卡爾座標系定義出來的絕對座標系,下面的各種座標系都建立在世界座標的基礎上。我們知道二維平面內任意一個點可以用二維座標(x,y)來表示,如果將這個概念延伸到三維空間內,那麼三維空間內任意一個點都可以用三維座標(x,y,z)來表示。這就是世界座標的概念啦,座標系通常可以分為左手座標系和右手座標系,而Unity3D採用的是左手座標系。在Unity3D中我們可以使用transform.position來獲取場景中一個物體的世界座標,通常情況下編輯器中的Inspector視窗是以世界座標來描述一個3D物體的位置的,除非當一個3D物體存在父物體的時候,它會以相對座標來描述其位置。


我們在場景中新增物體(如:Cube),他們都是以世界座標顯示在場景中的。transform.position可以獲得該位置座標。

1. 程式碼獲取的transform.position都是一致的

無論是3d還是2d,ugui/ngui,父子關係,transform.position都是以場景中心(0,0)的位置開始計算,單位長度也都是一樣的。

x軸:左負右正

y軸:上正下負

z軸:里正外負

無論怎樣的UI,怎樣的層級關係,程式碼裡輸出Debug.log(go.transform.position),輸出的總是相對於場景中心(0,0)的距離,也是獲取世界座標的方法。

2. 檢視面板的position數值和程式碼獲取的position數值不一致

ngui和ugui的Transform和Recttransform的position顯示的數值和程式碼裡獲取的transform.position不一致。

ugui btn程式碼位置position=new Vector(1,0,0),面板顯示(31.3,0,0)

ngui btn程式碼位置position=new Vector(1,0,0),面板顯示(371,0,0)

具體比例不是很清楚,可能和測試環境有關。

3. 父子關係的容器,檢視面板position和程式碼獲取position不一致

cube和ngui/ugui的子物件的Transform/Recttansform在檢視面板中顯示的Position數值是相對於父容器的,

但是程式碼裡獲取的Transform/RectTransfrom的position是相對於場景中心的。

獲取世界座標:go.transform.position

獲取本地座標:go.tranfrom.localPosition   (cube/ngui/ugui,無論層級關係,都是獲取的是檢視面板中的座標)

可推斷ugui/ngui都是在場景中的一個容器之中,所以檢視面板顯示的都是相對於父容器的座標,而不是世界座標。

二 Screen Space(螢幕座標):

以畫素來定義的,以螢幕的左下角為(0,0)點,右上角為(Screen.width,Screen.height),Z的位置是以相機的世界單位來衡量的。

螢幕座標是一個3D座標,Z軸是以相機的世界單位來衡量的。螢幕座標和相機之間滿足:Screen.width=Camera.pixelWidth和Screen.height=Camera.pixelHeight這兩個條件。

滑鼠位置Input.mousePosition獲取的是螢幕座標。

例如場景解析度1024x768,如果螢幕被縮小至100x100,那麼點選右上角是100x100,而不是解析度的1024x768。

三 ViewPort Space(視口座標)

視口座標是標準化後的螢幕座標。相機的左下角為(0,0)點,右上角為(1,1)點,Z的位置是以相機的世界單位來衡量的。

四 繪製GUI介面的座標系:

這個座標系與螢幕座標系相似,不同的是該座標系以螢幕的左上角為(0,0)點,右下角為(Screen.width,Screen.height)。

座標轉換:

世界座標 -> 本地座標:貌似不用轉,直接可以position和localPosition獲取。

本地座標 -> 世界座標:

世界座標→螢幕座標:camera.WorldToScreenPoint(transform.position);這樣可以將世界座標轉換為螢幕座標。其中camera為場景中的camera物件。

螢幕座標→視口座標:camera.ScreenToViewportPoint(Input.GetTouch(0).position);這樣可以將螢幕座標轉換為視口座標。其中camera為場景中的camera物件。

視口座標→螢幕座標:camera.ViewportToScreenPoint();

 視口座標→世界座標:camera.ViewportToWorldPoint();

父子物件關係:

SetParent(Transform parent, bool worldPositionStays);

false:不保留世界座標。改變層級關係後,座標數值不變,位置變化,會相對於父物件移動。

true(預設):世界座標不變。改變層級關係後,不會移動。