学习Unity银河恶魔城游戏制作第二部分:瓦片、背景与摄像头
Tile Palette
Tile Palette,即“瓷砖调色板”,是2D关卡设计的核心工具,可以快速构建基于网格的2D场景。
其功能为:将预制的瓷砖Tile资源组织为调色板,后续可以使用画笔工具在网格上快速绘制关卡。
如果想将瓷砖资源放入调色板进行组织,需要讲下载的图像Sprite资源(首先切割好)拖入Tile Palette窗口。在拖入过程中,Unity会自动为拖入的Sprite子资源生成对应的.tile文件(作者需要自行选择这些.tile文件的存放位置)。后续即可使用这些调色板内的瓷砖资源为场景绘制相关背景。
Tile Palette窗口如图(在加入瓷砖资源过程中,总共需要选择两次保存位置:调色板资源的保存位置,与转换后的.tile瓷砖文件保存位置):
如果想对调色板上的这些瓷砖进行删除,移位等修改,可以点击右上角铅笔标志进入编辑模式(Edit),然后再使用上方的这些工具修改调色盘。
具体如何使用此调色板绘制游戏背景等场地信息,见场地绘制。
场地绘制
如果想要讲Tile Palette中的瓦片信息应用到场景中,首先需要为场景创建一个Tilemap。当初次创建时,会同时创建一个父对象Grid(用来规定网格形状)。
目前设置的场地信息包括两个部分(使用两个Tilemap进行实现):地面Ground及背景Background。其差别是:地面所属瓦片是需要有物理碰撞的,玩家可以站立于其上,而Background只起到背景绘制的功能,不产生任何物理效果。
在这个例子中,两个Tilemap对象的设置完全不同。对于地面Tilemap,需要为期添加Tilemap Collider 2D,Rigidbody 2D和Composite Collider 2D三个组件。同时需要进行一些特殊设置:
- 设置Composite Collider 2D的Geometry Type为Polygon,这样可以让碰撞体为实心多边形。这种设置适用于封闭区域
- 设置Rigidbody 2D的Body Type为Static:让对应物体永远不移动(无限质量、不受力),适用于静态地面
- 设置Tilemap Collider 2D的Composite Operation为Merge:可以将所有瓦片的碰撞体合并为一个整体给Composite Collider 2D处理,各个瓦片不会保持独立碰撞体
- 设置Tilemap Renderer的Order in Layer为0,保证其高于背景Tilemap的层次,可以保证其在上方被渲染(不被覆盖)
- 设置整个对象的Layer为Ground,这样后续玩家可以判定其为地面,能够踩踏
部分设置如图:
背景Tilemap的设置就非常简单,因为不需要有任何物理模拟,只需要让它的Tilemap Renderer中的Order in Layer低于地面层即可。
然后只需要使用Tile Palette为场景添加瓷砖即可。Tile Palette窗口上方的工具均可用以编辑场景中的Tilemap。需要注意选择当前瓦片被添加到场景中的哪一个Tilemap(在Tile Palette窗口上方选单可选)。最终效果如下:
Camera
在unity中,摄像头的很多高级功能被集中保存在Cinematic Studio这一扩展包中。可以为场景新增Cinematic中的Virtual Camera对象,这个对象会覆盖本身场景中的Main Camera对象,对摄像头施加更加高级的控制。可以进行控制的参数包括:
- Follow:目前这个摄像头默认跟随的对象
- Ortho Size:选择摄像头的大小(可以看到的范围)
- Screen X / Screen Y:跟随的角色在摄像机中的位置
- X / Y / Z Dumping:摄像机跟随角色的延迟情况,会使摄像机在某一方向的移动速度低于玩家,造成摄像机移动的延迟
- Lookahead time:会让摄像机在玩家之前移动
- Lookahead Smoothing:会让摄像机的提前移动更加平滑
- Dead Zone Width / Height:会在摄像头中心生成一块“死区”,当摄像机跟随的玩家在这片区域内移动时摄像机不会发生位移
- Soft Zone Width / Height:可以限制摄像头中心的移动,不能超出Soft Zone设置的区域
- Bias X / Y:可以设置Soft Zone相对于摄像头中心的偏移
目前的Virtual Camera对象的参数设置如下:
Background
首先,对于背景来说,重要的就是Sprite Renderer的堆叠,来确定不同背景的覆盖情况。用来管理的Sprite Renderer相关属性为:Sorting Layer和Order in Layer。
其中,Sorting Layer是大的层次划分,可以将不同图像分为Background,Ground,Player等,在较高层的图像就一定能够覆盖较低层的图像。
Order in Layer则是较低的层次划分,处于同一Sorting Layer的图像通过比较Order in Layer确定最终的覆盖情况,较高的Order in Layer对应图像能够覆盖较低的。
接下来希望实现的,是背景跟随玩家移动,也就是说,如果背景完全不动,那么角色的移动有可能超出背景的范围。若背景能够跟随角色移动,且若不同层次的背景能够以不同速度跟随,则会有很好的视觉效果。代码如下:
1 |
|
其中,parallaxEffect
决定了背景跟随玩家移动的统一程度。根据代码可知,xPosition
通过transform
得来,是代表当前背景的位置;cam.transform
是摄像机位置,由于其跟随主角,也可以视作主角位置。
因此,通过float distanceToMove = cam.transform.position.x * parallaxEffect;
可以知道当前背景应该移动的距离(玩家移动距离乘背景随玩家移动的统一程度),并且可以通过更改当前背景的transform.position
进行背景位置的修改。
当然,这样还会引发一个问题:当parallaxEffect
小于1时,会出现背景移动的比玩家慢的情况,这样久而久之,如果背景长度有限,玩家就有可能移动出背景的边界。
为了解决这个问题,首先可以获取背景的长度length = GetComponent<SpriteRenderer>().bounds.size.x;
,然后可以通过float distanceMoved = cam.transform.position.x * (1 - parallaxEffect);
知道背景比玩家少移动的距离,一旦背景比玩家少移动的距离超出了一个背景图像的距离,就让背景瞬间移动一个图像的距离(注意,背景一般由三幅同样的背景图像拼接而成,这也使得这种防止背景用完的方式能够实现)。
想要更清晰的了解此方法可见Unity对应摄像机设置。