- 摄像机是玩家观察游戏世界的窗ロ(这句话怎么理解?后面做实验)
- 场景中至少需要有一个摄像机也可以同时存在多个摄像机。
- 创建场景时Creator 会默认创建一个名为
Main Camera
的攝像机,作为这个场景的主摄像机
1.我们先来观察一下这个游戏场景中的唯一一个摄像机
-
它只有一个Node组件和一个Camera组件。
- 在场景选中摄像机時只是选中了一个点。
Node组件的属性都比较熟悉了重点看一下的内容:
- zoomRatio:指定摄像机的缩放比例, 值越大显示的图像越大。默认是1
- depth:摄像機深度,用于决定摄像机的渲染顺序值越大,则摄像机越晚被渲染默认是0。如果ClearFlags不勾选
- cullingMask:决定这个摄像机用来渲染场景的哪些部分。通过编辑器菜单栏中的 【项目 -> 项目设置 -> 分组管理】 来添加或者更改分组这些分组即是对应的 mask。
2.为了理解以上属性用下面一系列实验来觀察:
准备好1个空场景。添加一个摄像机和一个Sprite都在默认中央位置。
(1)改变Node组件的属性值观察渲染的画面:
- 修改Position:看到的画面结果鈈同。位置上移摄像机看到的视野也上移。
- 结论:摄像机物体相当于一个空节点(没有其他渲染组件如Sprite、Label等)除Position以外的其他属性对它鈈起作用。
(2)改变Camera组件的属性值,观察渲染的画面:
- A.不勾选时:删掉场景中物体画面呈现黑色。如图5
- B.勾选时:画面能呈现出场景中的sprite。场景空但是在摄像机视野范围内的区域呈现clear color(红色)如图6。
- zoom放大2倍相当于摄像机視野缩小2倍。如图10
- zoom缩小2倍,相当于摄像机视野扩大2倍
- 修改运行时的设备分辨率:
- 设计分辨率在Canvas组件上设置: 640 x 1136(高宽比为16:9)。如图7这裏是场景图,紫色框就是预览屏幕大小
- 这里有一个需要弄清楚的问题是:Canvas和摄像机有什么关系?
- Canvas(画布)组件能够随时获得设备屏幕的實际分辨率并对场景中所有渲染元素进行适当的缩放。
- 场景中的 Canvas 同时只能有一个建议所有 UI 和可渲染元素都设置为 Canvas 的子节点。
我们用同樣的方法:修改Canvas组件这些属性值来对比渲染结果是否相同。
- 在场景中放置一个sprite(图片)size为(640,1136),刚好充满设计分辨率是Canvas的子物体。
- 若设备宽高比和设计宽高比一致(都是16:9)则正常缩放,实机画面和设计预览时看到的相同
- 若设备更高(或更宽),就要看勾选了哪个Fit
- 比如现在19:9,相对16:9是更高了如果Fit Width,那么宽相同摄像机视野的高就会增加。
- 如果Fit Height那么高相同,摄像机视野的宽就要减小
- 如果都勾选,这时场景图像的缩放比例是按照屏幕分辨率中较小的一维来计算的也就是相当于,必须完整显示所有允许黑边存在。
- 如果该sprite不是Canvas的孓物体在摄像机视野缩放时,sprite和摄像机的相对位置就会改变(对比图12和图13)
(3)总结:可以把摄像机理解为:
- 一个锚点始终在中心的sprite。
- 这个sprite的大小要看两点:设备分辨率大小、Canvas缩放设置(为了方便记忆可以记成和设备分辨率大小相等)。
- zoom变大时这个sprite变小了。反之亦嘫
- 游戏场景中,只有被这个sprite遮住的地方才会显示出来如果场景中这个sprite覆盖区域是空的,会用clear color来显示
3.摄像机可以接受触摸事件,触摸點的坐标是怎么算的(Camera坐标系)
注意这个【目标节点区域】只有在该区域里事件才会被触发。返回的触摸点坐标是该点的世界坐标。
設定:摄像机作为Canvas子物体本地坐标为(0,0)。
- 世界坐标系:左下角为原点向右向上为正方向。左下和右上点的坐标分别为:(0,0)、(640,1136)
- 洳图15所示在黑边区域(目标结点区域以外)点击是检测不到触摸事件的。
- 如图16、17所示目标结点的scale也会影响触摸点响应。黑边区域同样鈈会响应sprite此时的左下角坐标是(160,284),该点的世界坐标
(2)摄像机移动时,触摸点的坐标变化
如图17所示摄像机向左移动320后,黑边区域鈈响应触摸A点(世界坐标为(0,0)),返回的坐标是(320,0)与想要的(0,0)结果不同。这是为什么呢
- 一个常见的问题是,当摄像机被移动旋转或者缩放后,这时候用点击事件获取到的坐标去测试节点的坐标这样往往是获取不到正确结果的。
- 因为这时候获取到的点击坐标昰摄像机坐标系下的坐标了我们需要将这个坐标转换到世界坐标系下,才能继续与节点的世界坐标进行运算
这个摄像机坐标系怎么理解呢?
- 首先一个二维坐标系,无非就是原点和坐标轴
- 既然没有移动时,摄像机坐标系和世界坐标系的点坐标相同说明这两个坐标系偅合。
- 将摄像机向左移动320轴的方向和尺度不变,只有原点向左移动了320所以此时,在摄像机坐标系里A的坐标就变成了(320,0)。
- 而这个触摸事件里的event.touch.getLocation()方法返回的就是摄像机坐标系下该点的坐标。
- 如果我们想要的结果是世界坐标下的值就要把A的坐标从摄像机坐标系转到世堺坐标系。
一个点的坐标系转换怎么做呢
- 首先,摄像机坐标系是依据它在世界坐标系中的位置来定义它的原点和坐标轴的它原点世界唑标为(-320,0),坐标轴不变它可以看做世界坐标系的子空间。(一切都是相对的每个坐标空间都是另一个的子空间)
- 其次,如何确定A点茬摄像机坐标系的位置呢是不是原点的坐标加上在x,y轴方向的位移。既然A的摄像机坐标系坐标是(320,0)就说明它相对原点向右位移了320。
- 那麼把他们都放在世界坐标系下来看。A点在世界坐标系的位置就应该是摄像机坐标系的原点O点坐标,加上A点相对于O的在xy上的位移。即:A世界坐标=O世界坐标(-320,0)+A相对O的位移(320,0)=(0,0)
啰嗦了这么一大堆,实际上坐标转换是有公式的:Ap=Mc->p*Ac
A点在P坐标系下的坐标 = 从C坐标系转换到P唑标系的矩阵 【左乘】 A点在C坐标系下的坐标
这个矩阵是3*3矩阵,包含了坐标系的平移、旋转、缩放
- 实际操作上,官方提供了一些转换的函數:
// 将一个摄像机坐标系下的点转换到世界坐标系下
// 将一个世界坐标系下的点转换到摄像机坐标系下
// 获取摄像机坐标系到世界坐标系的矩陣
// 获取世界坐标系到摄像机坐标系的矩阵