一、常用的坐标系
- 世界坐标: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:
跟随效果:
*** | 以上内容仅为学习参考、学习笔记使用 | ***