游戏物体的参考坐标系解析
Unity场景中的游戏物体有4种坐标系:世界坐标系(局部坐标系)、屏幕坐标系、绘制GUI界面的坐标系、视图坐标系。
1、世界坐标(局部坐标)
世界坐标是指游戏物体相对于“父级是游戏场景Scene对象”的坐标系;而局部坐标系是相对于“父级是普通的游戏对象”(如Parent)的坐标系。一定程度上可以说,局部坐标是一种特殊的世界坐标。
注意Parent对象的Position/Rotation/Scale的值
注意Red对象的Position/Rotation/Scale的值
测试代码如下:
1 2 3 4 5 6 | void Start () { Debug.Log( "Red子对象的Position:" +transform.position+ " localPosition:" +transform.localPosition+ " Parent父对象的Position:" +transform.parent.position+ "localPosition:" +transform.parent.localPosition); Debug.Log( "Red子对象的Rotation:" + transform.rotation+ " localRotation:" + transform.localRotation+ " Parent父对象的Rotation:" + transform.parent.rotation + "localRotation:" + transform.parent.localRotation); Debug.Log( "Red子对象的localScale:" +transform.localScale); } |
运行结果如下:
结论1:对象的localPosition/localRotation/localScale与Inspector属性面板中Position/Rotation/Scale对应。所以,直接修改属性面板中Position/Rotation/Scale的值,是相对于局部坐标的。
结论2:tranform.position/rotation是相对于世界坐标的
结论3:Parent父对象的localPosition/localRotation与Position/Rotation对应值相等。说明如果游戏对象的父对象直接是“Scene对象”时,局部坐标与世界坐标“等价”。
2、屏幕坐标
以像素为单位,它是一个3D坐标,以屏幕的左下角为(0,0),右上角为(Screen.Width,Screen.Height);而Z的位置是依据相机的世界单位来衡量的(若游戏物体在相机的前方,则Z>0;反之,Z<0)。值得注意的是,鼠标(Input.mousePosition)或者手指触摸屏(Input.GetTouch(0).position)在屏幕中产生的都是屏幕坐标。另外,屏幕坐标和相机之间有个关系:Screen.width=Camera.pixelWidth和Screen.height=Camera.pixelHeight。
3、视图坐标系
视口坐标是相对于相机的,以左下角为(0,0),右上角为(1,1)。另外,Z的位置也是根据相机的世界单位来衡量。与屏幕坐标对比发现,似乎是把屏幕坐标进行了个“标准化”。因此,可以称视图坐标为“特殊化的屏幕坐标”。
4、绘制GUI界面的坐标系
它是一个2D坐标,而且还是一个绝对坐标。和屏幕坐标有点儿相似,以屏幕的左上角为(0,0),右下角为(screen.width,screen.height)。但是,实际布局UI过程化中,是需要考虑到UI自适应的问题,是不会使用绝对坐标来设定UI元素位置的。
自4.6版Unity新的UGUI系统以来,对GUI坐标有了新的“升级”,引入了“Anchor”与“Pivot”等概念,使我们方便的调节UI坐标来布局。
我们知道RectTransform继承自Transform,Image属性面板中XY Z轴中的值与Image的RectTransform组件的anchoredPosition3D以及Image的Transform组件的localPosition的值相同。另外,Image的RectTransform组件的anchoredPosition是Vector2d(不含Z的)。
5、各种坐标之间的转化
(1)屏幕坐标转换为世界坐标
API:Camera.main.ScreenToWorldPoint(Vector3 v)举例:RPG游戏中,角色向鼠标点击的地面位置移动。
(2)世界坐标转换为屏幕坐标
API:Camera.main.WorldToScreenPoint(Vector3v) 举例:NPC头顶显示的文字与血条。
(3)屏幕坐标转换为视图坐标
API:Camera.main.ScreenToViewportPoint(Vector3 v)
(4)世界坐标转换为视图坐标
API:Camera.main.WorldToViewportPoint(Vector3 v);
如果有不足之处,请指正!