一、常用的坐標系
- 世界坐標:World Space
簡單來說,我們通過 transform.position | transform.rotattion 獲取得到的位置和旋轉信息都是基於世界坐標系的,可以說,我們很大一部分的操作都是基於世界坐標系。
- 觀察坐標:Eye Space
我們在 Unity 的 Game 視圖中觀察到的畫面始終是由攝像機提供的,“Eye Space”也就是基於攝像機的一個坐標系(簡單來說就是把攝像機看作原點位置)。
- 視口坐標:View Port
視口是針對游戲顯示的畫面進行描述的,View Port 用於描述整個游戲畫面的坐標,左下角為(0,0),右上角為(1,1)。
我們在設計分屏游戲的時候可以通過攝像機所占據的視口空間來控制分屏所屬的位置。
- 屏幕坐標:Screen Space
屏幕坐標和像素是相掛鈎的,也就是說屏幕坐標和分辨率有關,屏幕的左下角為(0,0),但右上角為(screen.width,screen.height)。
比如游戲的分辨率為1280*720,那么 screen.width=1280;screen.height=720。
要注意的是,我們在獲取鼠標位置的時候,通過 Input.mousePosition 獲取鼠標的位置,這里獲取到的鼠標位置是基於屏幕坐標的。
而通過該函數返回的是 Vector3 類型的變量,但 z 軸始終為 0。
二、坐標轉換
1、屏幕坐標轉世界坐標
1 public Vector3 myscreenToworld(Vector3 mousepos, Transform targetTransform) 2 { 3 // 先計算攝像機到目標的向量 4 Vector3 dir = targetTransform.position - Camera.main.transform.position; 5 // 計算投影 6 Vector3 normardir = Vector3.Project(dir, Camera.main.transform.forward); 7 // 計算世界坐標 8 Vector3 worldpos = Camera.main.ScreenToWorldPoint(new Vector3(mousepos.x, mousepos.y, normardir.magnitude)); 9 return worldpos; 10 }
2、世界坐標轉屏幕坐標
1 Vector3 mywordToScreen = Camera.main.WorldToScreenPoint(new Vector3(worldPos.x, worldPos.y, worldPos.z));
3、世界坐標轉視口坐標
1 Vector3 myworldToview = Camera.main.WorldToViewportPoint(worldPos.x, worldPos.y, worldPos.z);
4、視口坐標轉世界坐標
1 Vector3 myviewToworld = Camera.main.ViewportToWorldPoint(new Vector3(viewPortPos.x, viewPortPos.y, zInfo));
5、視口坐標轉屏幕坐標
1 Vector3 myviewToscreen = Camera.main.ViewportToScreenPoint(viewPortPos.x, viewPortPos.y, viewPortPos.z);
6、屏幕坐標轉視口坐標
1 Vector3 myscreenToview = Camera.main.ScreenToViewportPoint(screenPos.x, screenPos.y, screenPos.z);
這些函數都有一個很明顯的共同點,就是這些函數都是 Camera 的成員函數,輸入和輸出的都是 Vector3 類型的變量,也就是說這些函數都是針對當前攝像機的一個變換操作。
三、轉換示例
通過坐標間的相互轉化,實現血條跟隨人物移動的需求
1 using UnityEngine; 2 3 public class HPFollow : MonoBehaviour 4 { 5 // 人物頭頂 6 public Transform heroHeadTrans; 7 8 // 攝像機 9 10 public Camera mainCamera; 11 // 血條 12 public RectTransform hpTrans; 13 14 // Canvas畫布 15 public RectTransform canvasTrans; 16 17 void Update() 18 { 19 // 先將世界坐標轉換成屏幕坐標 20 Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(mainCamera, heroHeadTrans.position); 21 22 // 再將屏幕坐標轉換成UGUI坐標 23 Vector2 localPoint; 24 25 if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasTrans, screenPoint, mainCamera, out localPoint)) 26 { 27 hpTrans.anchoredPosition = localPoint; 28 } 29 } 30 }
修改 Canvas 的 RenderMode 以及設置 Render Camera:
跟隨效果:
*** | 以上內容僅為學習參考、學習筆記使用 | ***