一、坐標系介紹
世界坐標:表示物體在三維空間的坐標,通過transfrom.position即可獲取該物體自身的世界坐標
屏幕坐標:重點介紹的一個坐標系,屏幕坐標跟分辨率有關
分辨率為720*1280,則Screen.width為720,Screen.height為1280;屏幕的左下角坐標為(0, 0),右上角為(Screen.width, Screen.height)
常用的Input.mousePosition就是獲得的鼠標在屏幕坐標的位置,移動端的Input.GetTouch(0).position也是獲得到手指在屏幕坐標的位置
視口坐標:視口坐標的左下角為(0, 0),右上角為(1, 1)
UGUI坐標:物體的本地坐標如anchoredPosition和localPosition等
二、世界坐標相關轉換
世界坐標轉屏幕坐標:底層實現是首先世界坐標轉成視口坐標,視口坐標再轉成屏幕坐標,所以直接轉換的API是unity封裝過的,有興趣的可以查下底層
Vector2 screenPos = camera.WorldToScreenPoint(worldPos) Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(camera, worldPos)//此處的camera為場景camera
世界坐標轉視口坐標:
Vector2 viewPortPos = camera.WorldToViewportPoint(worldPos)
世界坐標轉UGUI坐標:給出A物體世界坐標,計算將A物體放到B物體下,A相對於B物體的UGUI坐標(anchoredPosition) / 將A物體轉換為基於B物體節點下的本地坐標
Vector2 anchoredPosition = B.transform.worldToLocalMatrix:MultiplyPoint(A.transform.positon)
Vector2 anchoredPosition = B.transform.InverseTransformPoint(A.transform.positon)
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, screenPos, camera, out worldPos)
屏幕坐標轉視口坐標:
Vector2 viewPortPos = camera.ScreenToViewportPoint(screenPos)
屏幕坐標轉UGUI坐標:
若Canvas的RenderMode為Overlay時,cam參數應該為null,其他模式給定渲染canvas的相機即可
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPos, camera, out localPos)
//血條跟隨人物頭頂移動 using UnityEngine; public class HPFollow : MonoBehaviour { public Transform heroHead; public Camera camera; public RectTransform hp; public RectTransform canvasTransform; void Update() { Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(mainCamera, heroHead.position);// 先將3D坐標轉換成屏幕坐標 Vector2 localPoint;// 再將屏幕坐標轉換成UGUI坐標 if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasTransform, screenPoint, camera, out localPoint)) { hp.anchoredPosition = localPoint; } } }
四、視口坐標相關轉換
視口坐標轉屏幕坐標:
Vector2 screenPos = camera.ViewportToScreenPoint(viewPortPos)
視口坐標轉世界坐標:常用於獲得相機視口邊界的世界坐標位置
//當viewPortPos = new Vector2(0,0) 則可以獲取到左下角的世界坐標 //當viewPortPos = new Vector2(1,1) 則可以獲取到右上角的世界坐標 Vector3 worldPos = camera.ViewportToWorldPoint(new Vector3(viewPortPos.x , viewPortPos.y)
五、UGUI坐標相關轉換
UGUI坐標轉世界坐標:
//將A物體的坐標轉換為世界坐標 Vector3 worldPos = B.transform.TransformPoint(A.transform.localposition)
UGUI坐標轉屏幕坐標:
UGUI坐標->世界坐標->屏幕坐標
UGUI坐標轉視口坐標:
UGUI坐標->世界坐標->視口坐標
六、RectTransformUtility相關轉換
using UnityEngine; public class TransformUtility { public static Camera ScenceCamera;// 場景相機 public static Camera UGUICamera;//UGUI相機 /// <summary> /// 世界坐標轉屏幕坐標 /// </summary> public static Vector2 WorldToScreenPoint(Vector3 worldPoint) { return RectTransformUtility.WorldToScreenPoint(ScenceCamera, worldPoint); } /// <summary> /// 世界坐標轉屏幕坐標 /// </summary> public static Vector2 WorldToScreenPoint(Camera cam, Vector3 worldPoint) { return RectTransformUtility.WorldToScreenPoint(cam, worldPoint); } /// <summary> /// 屏幕坐標轉世界坐標 /// </summary> public static bool ScreenPointToWorldPointInRectangle(RectTransform rect, Vector2 screenPoint, out Vector3 worldPoint) { return RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, screenPoint, UGUICamera, out worldPoint); } /// <summary> /// 屏幕坐標轉世界坐標 /// </summary> public static bool ScreenPointToWorldPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector3 worldPoint) { return RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, screenPoint, cam, out worldPoint); } #region 屏幕坐標轉UGUI坐標 /// <summary> /// 屏幕坐標轉某個RectTransform下的localPosition坐標 /// </summary> public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, out Vector2 localPoint) { return RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, UGUICamera, out localPoint); } /// <summary> /// 屏幕坐標轉某個RectTransform下的localPosition坐標 /// </summary> public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint) { return RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, screenPoint, cam, out localPoint); } #endregion }
以上便是本人最近研究的關於Unity常用坐標轉換的相關總結,如有不對之處,還望多多指正!
參考博文:【Unity UGUI】屏幕坐標轉換