一、Unity的坐标系体系
世界坐标系 (World Space)、屏幕坐标系 (Screen Space)、视口坐标系 (Viewport Space)、GUI界面坐标系 (GUI System)
左右手定则:用手握住 z 轴,大拇指朝向 z 轴正方向,然后用手的四指从 x 轴正方向握拳头,如果是左手 90 度就能把四指握到 y 轴就是左手坐标系,如果是右手 90 度握紧后到了 y 轴就是右手坐标系。
1.1、GUI 界面坐标系
在unity中创建的UI按钮,都是在GUI界面坐标系中,它的原点 (0, 0)
在最左上角,因为屏幕宽度是 Screen.width
,高度是 Screen.height
,所以 GUI 体系右下角的坐标为: (Screen.width, Screen.height)
, 这是一个二维的坐标体系,坐标 z
的值都为 0 。
1.2、视口坐标系
当使用多个摄像机,在同一个场景中显示多个视口的时候,必须要考虑视口坐标系。
一个相机对应一个视口,视口预览( Camera Preview )展示了相机所看到的所有物体,很显然,它默认大小是 (width = 1, height = 1) ,位置也是从 0 到 1 :坐标系左下角为 (0, 0) ,右上角是 (1, 1) ,一般视口坐标系主要用在相机显示中,设置Viewport Rect参数即可。
1.3、屏幕坐标系
重点内容:
经常需要处理鼠标的相关事件(鼠标位置、单击、双击事件等),手机上的触摸反馈,这些原始数据都是屏幕坐标系相关的。
Input.mousePosition
获取的就是鼠标在屏幕中的位置坐标。屏幕坐标系中原点 (0, 0)
位于左下角,右上角是 (Screen.width, Screen.height)
深度值z都为0。但是屏幕坐标转换成世界坐标后物体的 z
值是取决于相机的,因此: gameObject.z = camera.z
注意:
屏幕宽高比Aspect会影响画面的显示效果。
1.4、 世界坐标系
重点内容:
任何情况下: transform.position
都是返回物体的世界坐标值,即使你所使用的是子物体!
另外,屏幕坐标系转换成世界坐标系的过程中,由于世界坐标系是有z值的,不能通过以下方法直接转换:
var position = Input.mousePosition;
var worldPoint = Camera.main.ScreenToWorldPoint(position);
//无z值信息
需要知道幕布到投影仪的距离,才可以将幕布上的一个点转换到世界上来:
public Vector3 myscreenToworld(Vector3 mousepos,Transform targetTransform)
{
//先计算相机到目标的向量
Vector3 dir = targetTransform.position - Camera.main.transform.position;
//计算投影
Vector3 normardir = Vector3.Project(dir, Camera.main.transform.forward);
//计算是节点,需要知道处置屏幕的投影距离
Vector3 worldpos = Camera.main.ScreenToWorldPoint(new Vector3(mousepos.x, mousepos.y, normardir.magnitude));
return worldpos;
}
在开发过程中,经常要处理子物体的相对 transform
值,这时可以把父物体当做世界,子物体当做世界中的物体,使用这些函数,换一下坐标就和处理绝对坐标一样了。方法为:把相机放到一个产生了合适旋转角度的父物体当中!这样做的效果就是:相机就相当于子物体,父物体旋转了,子物体就不需要额外旋转了,这时候相机的局部旋转就为 0 。这在有些场景中使用起来很方便,相机已经是父物体世界中的子物体了。
计算相对坐标:
//获取的是世界坐标
var childPosition = childObject.transform.position;
//转化为父物体下的相对坐标,相当于位于父物体世界中
var relativePosition = parentObject.transform.InverseTransformPoint(childPosition);
//转化为世界坐标,注意:这里不能传入 childPosition ,因为 childPosition 就是世界坐标
var worldPosition = parentObject.transform.InverseTransformPoint(relativePosition);
//所以,下面结果是相等的!
print(childPosition == worldPosition);
1.5、其它坐标系转换
世界坐标转屏幕坐标系:
//世界坐标转屏幕坐标系
Camera.main.WorldToScreenPoint();
//世界转视口
Camera.main.WorldToViewportPoint();
//视口转屏幕
Camera.main.ViewportToScreenPoint();
//或者
Vector2(Viewposition.x*Screen.width,Viewposition.y*Screen.hight);