Unity 中的坐标系
前言
在制作魔剑镇魂曲的 TileMap 时用到了各种坐标系之间的转换, 当时被整得云里雾里的, 现在来回顾一下. 游戏中我只用到了笛卡尔坐标系, 没有用到极坐标系, 后面就直接简称为坐标系了.
坐标系与坐标
首先需要强调一下坐标系和坐标完全不是一回事, 文章中有很多地方涉及到坐标系和坐标, 为了避免混淆, 一定要在脑海中清晰地区分两者. 坐标系是一个系统, 而坐标只是一个表示位置的数字.
坐标是不可能独立存在的, 它必须依存于某个坐标系, 因此很多时候我们就直接简称为某某坐标. 比如在屏幕坐标系中一个点的坐标简称为 "屏幕坐标", 在世界坐标系中一个点的坐标简称为 "世界坐标".
分类
Unity 中的坐标大致分为 4 种:
坐标 | 关键字 |
---|---|
世界坐标 | World Point |
本地坐标 | Local Point |
屏幕坐标 | Screen Point |
视图坐标 | View Point |
世界坐标 (World Point)
Unity 中有一个覆盖全部游戏物体的坐标系, 所有的游戏物体都靠这个坐标系来确定自身在游戏世界中的准确位置, 这个坐标系就是世界坐标系. 有时为了明显和 "局部坐标系" 相对应也被称为 "全局坐标系". 在世界坐标系中得出的点的坐标称为世界坐标 (World Point).
但是遗憾的是在游戏物体 Inspector 面板中, Transform 处显示的 Position 是在父物体坐标系中的坐标, 而不是在世界坐标系中的坐标. 只有当物体没有父物体的时候, Transform 处显示的 Position 才是在世界坐标系中的坐标.
但是在脚本中, 使用 transform.position 获取的却是游戏物体的世界坐标.
本地坐标 (Local Point)
Unity 中每个游戏物体都有其自身坐标系, 其子物体便是使用这个坐标系来确定与父物体的相对位置关系. 在父物体坐标系下得出的点的坐标称为本地坐标 (Local Point).
由于本地坐标系和物体绑定, 因此当游戏物体进行旋转, 移动的时候, 坐标系也会进行相应的旋转和移动. 但是本地坐标却有一个特点: 不变性. 当游戏物体进行旋转, 移动的时候, 其子物体的本地坐标是不变的, 即子物体相对于自身的相对位置不会改变, 因此子物体会跟随其父物体旋转, 移动.
Unity 中模型 Mesh 保存的顶点坐标均为本地坐标, 因为本地坐标的不变性, 即使物体进行旋转或者移动, 也不会影响顶点的坐标.
在脚本中使用 transform.position 获取的是游戏物体的世界坐标, 使用 transform.localPosition 获取的便是游戏物体的本地坐标. 但是当物体没有父物体的时候, transform.localPosition 获取的也是世界坐标.
屏幕坐标 (Screen Point)
屏幕坐标系是基于游戏窗口建立的坐标系.
屏幕坐标系以像素为单位, 窗口的左下角坐标为 (0, 0), 右上角坐标为窗口大小. 脚本中可以通过 (Screen.width, Screen.height) 来获取窗口大小.
脚本中使用 Input.mousePosition 可以获得鼠标坐标, 这个坐标便是基于屏幕坐标系计算得来的. 另外使用 Input.GetTouch(0).position 可以获得单个手指触摸屏幕时手指的坐标, 这个坐标也是基于屏幕坐标系计算得来的.
需要注意的是屏幕坐标不是根据玩家显示器的大小建立的坐标系, 而是以游戏窗口建立的坐标系, 比如玩家屏幕为: 1920 X 1080, 但是游戏窗口是: 800 X 600, 那么右上角的坐标是 (800, 600).
视图坐标 (View Point)
摄像机预览窗口显示的画面, 也是基于游戏窗口建立的坐标系.
视图坐标系的大小为单位 1, 窗口的左下角坐标为 (0, 0), 右上角坐标为 (1, 1).
屏幕坐标单位化后得到的就是视图坐标.
Pivot / Center 和 Local / Global
首先必须明确的是这两个功能是用于编辑器的, 不是应用于运行时的, 他们是为了让开发者更加方便地切换信息
Pivot vs Center
Pivot 显示的位置是游戏物体在运行时的真实位置, 即 Transform 的 Position, 有的物体它的坐标和渲染出来的几何体可能并不在一个位置上, 这个可以让开发者非常方便的看到各个物体的真实位置, 当多选时, Pivot 显示的是最后一个选中的物体的真实位置
Center 显示的位置是游戏物体渲染后的几何体的中心位置, 可以让开发者方便的查看多个物体, 调整多个物体的缩放, 位移等, 当多选时, Center 显示的是多个物体的包围盒中心
Local / Global
Local 模式下, 选中物体显示的坐标系是自身坐标系, 会跟着物体旋转, 因此当需要让物体按照自身方向移动或者旋转时, 便可以使用此模式
Global 模式下, 则是始终显示世界坐标系, 这样即使物体旋转了, 调整物体的世界坐标也会非常方便
参考文章
Unity中屏幕坐标、视口坐标和世界坐标、局部坐标与其之间的相互转换
理解Unity3D中的四种坐标体系