一、坐标系介绍
世界坐标:表示物体在三维空间的坐标,通过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】屏幕坐标转换