上一篇文档介绍了如何使用Unity创建Isometric Z As Y Tilemap(《Unity使用Isometric Z As Y Tilemap创建2.5D地图(一)如何创建Tilemap》)。本篇文章将在前文基础上继续说明,当Tilemap中的图片大小不一致、图片需要在原有网格位置上发生移动时候,如何正确处理Tile图片之间的遮挡关系。
一般Tilemap地图都是由多层组成的,例如地面层、建筑层、空中层、碰撞检测层等等。通常层与层之间区分是比较明显的,比如地面层永远在最下层,建筑物总是会显示在地面层之上。
所以我们在Grid对象下面先建两个层地面层和建筑层,分别对应Ground、Build。同时之前创建过Ground层的Palette,此处还要创建对应的Build层Palette,具体过程参考上一篇文档。
从上图可以看到,当我们选择Build Palette在Tilemap的Build层绘图后,点击运行,发现建筑图片显示在Ground层之下。这是因为默认创建的Tilemap的Ground层和Build层的Sorting Layer、Order in Layer都是相同的,此种情况,可以通过将Ground层和Build层分别设置不同级别的Sorting Layer或不同大小的Order in Layer来改变图层渲染顺序,具体这两个参数如何设置此处不再赘述。
Tips:很多时候编辑中的显示不是最终运行的显示效果,所以要经常点击运行后查看最终效果。
我们看到上图中左面和下面的墙壁显示是明显错误的,上面和右边的没有问题。这是因为上面和右面的墙壁是使用同一个Tile图片绘制的。而左面和下面的墙壁分别都用了两种不同的Tile图片绘制的,虽然2种Tile看上去很像,但会引起上图中的显示遮挡异常问题。
为了解决上述问题,需要修改Unity默认的 Transparency Sort Mode 和 Transparency Sort Axis。修改方式为, 点击菜单 Edit > Project Settings > Graphics 在 Camera Settings 属性处。
修改 Transparency Sort Mode 为 Custom Axis 自定义模式,并将 Transparency Sort Axis Y改为36,Z改为-19。这样设置表示,按照相机到Y的正方向距离渲染图形,Y值越小的越靠后显示,Z值越大越靠后显示,Z值增加到Y的比重为 − 19 36 \frac{-19}{36} 36−19。
关于如何计算Z值。可以使用一个通用公式来计算轴排序的 Z 值。通过我们创建的Grid 的 Y 尺寸,将该值乘以 -0.5,然后再减去 1。此处参考《Isometric 2D Environments with Tilemap》,文章里面讲减去0.01,个人认为应该是根据Pixels Per Unit = 100来计算的,而本文的Pixels Per Unit = 1。
在我们的简单项目例子里,按照上述方法修改是没有问题的,但是如果项目工程里使用了 LWRP(Universal RP),那么你会发现通过菜单是无法修改 Transparency Sort Mode 的,因为根本看不到 ╮(╯3╰)╭。在这种情况下只能通过代码来解决。让我们给Camera添加一个脚本,具体代码如下:
void Start()
{
var camera = GetComponent<Camera>();
camera.transparencySortMode = TransparencySortMode.CustomAxis;
camera.transparencySortAxis = new Vector3(0.0f, 36f,-19f);
#if UNITY_EDITOR
foreach (SceneView sv in SceneView.sceneViews)
{
sv.camera.transparencySortMode = TransparencySortMode.CustomAxis;
sv.camera.transparencySortAxis = new Vector3(0.0f, 36f, -19);
}
#endif
}
Tips:上述代码中#if UNITY_EDITOR的作用,表示仅在编辑器窗口下则运行此段代码。
这时候我们看到上面地图大多数显示都是正确的,只有拐角处显示有问题。这是因为本文所用的图片资源大小和高度是不对齐的,所以显示上位置有偏差。想要解决这个问题,需要调整对应拐角的Tile图片的位置解决。
通过上图中选择Tile Palette面板中的 选择工具,选择编辑中对应Tile,编辑改变Position的X、Y值来使图片显示到正确的位置。
Tips:通过菜单 Window > 2D >Tile Palette 打开Tile Pallette面板。这里有个众所周知的小技巧,可以用鼠标左键点击Position的X、Y位置通过左右移动鼠标增加或减少值的大小。
但是并不是一切都是这么简单处理的!比如下图中的鼎,它是由4个Tile图片拼接的。虽然图片都通过调整Position使图片显示在了正确位置,但是左上角的图片没显示出来,实际上它是被后面的墙挡住了。
当我们调整对应Tile的Position的Z值后,这次显示正确了。
Tilemap与非Tilemap对象之间的遮挡关系与Tile之间遮挡关系没什么区别,同样遵循Transparency Sort Axis渲染顺序,但我们需要注意一些细节。
我们看到上图中,角色只是一张静态的Sprite,虽然Sprite的 Pivot 已经设置为Bottom ,但是它与建筑的遮挡关系不是完全正确的。原因是角色对象的 Sprite Sort Point 设置为 Center 了。
调整后显示效果终于基本正常了,但是有一处和鼎的显示还是有问题。这时候还是需要通过上文说的,选择 Tile Palette 面板中的 选择工具,选择编辑中对应Tile,编辑改变 Tile 的 Position 的 Z 值来使图片显示到正确的位置。
我们看到将 Tile 的 Position Z 值调整后,显示顺序终于完全正确了。
如何计算 Tile 的正确 Position Z 值,总不能每个都要手动慢慢调整吧?
这里我根据个人理解说明一下,有说的不对的地方欢迎指正。在上面的文章提到过Z值增加到Y的比重,是根据我们设置的 Transparency Sort Axis计算的,本文设置的为 Y = 36 , Z = -19 ,所以 Tile Position Z 值计算公式应为:
Tile Z = Tile Y * T r a n s p a r e n c y S o r t A x i s Y T r a n s p a r e n c y S o r t A x i s Z \frac{Transparency Sort Axis Y}{Transparency Sort Axis Z} TransparencySortAxisZTransparencySortAxisY = Tile Y * 36 19 \frac{36}{19} 1936
关于 Tile Position Z 值的计算,换一个比较容易理解的方式解释。就是我们的图片Tile属于哪个网格,理论上它就应该显示在什么位置,它的遮挡关系也应该在它属于的网格位置四周发生变化。但因为图片大小不规则,或者图片需要浮空显示等原因,我们需要将图片的 Y 的大小进行增加或减少。这时候,如果我们还希望图片根据它原网格位置(而不是调整后的位置)进行遮挡关系计算,那么就需要修改 Z 值来平衡修改后的 Y值。
至此,按照我们上面文档内容操作,基本已经能够正确处理大部分图片遮挡关系了,但当小范围内存在大量遮挡关系需要动态计算的地方,需要大家在公式基础上进一步的调整相关Tile Position Z 值的大小。
面对无数的图片资源,如果全部手动设置工作量比较大,也不好处理。下一篇文档将讲解如何使用代码创建Tilemap相关内容。
文章链接: 《Unity使用Isometric Z As Y Tilemap创建2.5D地图(三)如何用代码创建Tilemap》