美文网首页游戏
彻底解决 Unity 中 Tilemap 缝隙问题

彻底解决 Unity 中 Tilemap 缝隙问题

作者: 廖宇雷 | 来源:发表于2017-05-13 18:43 被阅读1610次

    最近在使用 Unity 开发一个独立游戏,游戏里用到了 Tilemap。但却遇到一个让人很郁闷的问题,就是拼接的地图总是有随机出现的缝隙。

    01.png

    经过网络搜索和自己摸索,总结了几条解决此问题的技巧。

    这里有一点要提醒:因为我的游戏是像素风,所以修改下面两项设置可以获得很好的效果。如果是非像素风的游戏,那不应该修改下面两项设置,而是应该直接按照本文最后的方法对图片进行边缘扩展。

    首先,确保你的图片宽度和高度是偶数。然后对 Unity 进行如下设置:

    • 选中图片,将图片的 Filter Mode 指定为 Point (no filter)
    remove-filter.png
    • 选择菜单 Edit -> Project Settings -> Quality,打开 QualitySettings 设置。在这里选中每一个级别,将其中的 Anisotropic TexturesAnti Aliasing 都指定为 Disabled
    disable-anti-aliasing.png

    经过上述设置后,对于不改变位置和缩放的 Tilemap 来说,已经可以做到清晰显示了,连接处也不会有缝隙。

    但如果是需要移动或者缩放的地图,那么还是会出现缝隙,这就需要作进一步的处理。

    设置 1 Pixel / 1 Unit

    要在移动时消除缝隙,应该将图片的 Pixels per Unit 指定为 1。也就是一个像素对应场景里一个度量单位。

    这样我们在代码里通过对 x/y 取整,就可以很容易实现 Pixel Perfect 的显示。

    示例代码:

    transform.position = new Vector3 (Mathf.Round (x), Mathf.Round (y), 0);
    

    扩展图像边缘

    如果对 Tilemap 进行缩放,哪怕 x/y 已经取整,显示时还是可能出现缝隙,此时就必须对图片进行处理了。

    我们将原始的图片边缘进行扩展,这样在多个 Sprite 拼接为 Tilemap 时,由于有互相重叠的像素,就不会再有缝隙了。

    extrude-image.png

    这个事情当然可以让美术在制作图片时就考虑好此问题。如果是已经做好的图片,可以用简单的 Python 脚本来扩展:

    from PIL import Image as PIL_Image
    
    extrude_width = 1
    
    # open origin image
    image = PIL_Image.open('origin.png')
    w = image.size[0]
    h = image.size[1]
    
    # left_top
    left_top_point = image.crop((0, 0, 1, 1))
    # right_top
    right_top_point = image.crop((w - 1, 0, w, 1))
    # right_bottom
    right_bottom_point = image.crop((w - 1, h - 1, w, h))
    # left_bottom
    left_bottom_point = image.crop((0, h - 1, 1, h))
    # top
    top_edge = image.crop((0, 0, w, 1))
    # bottom
    bottom_edge = image.crop((0, h - 1, w, h))
    # left
    left_edge = image.crop((0, 0, 1, h))
    # right
    right_edge = image.crop((w - 1, 0, w, h))
    
    # new image
    nw = w + extrude_width * 2
    nh = h + extrude_width * 2
    newsize = (nw, nh)
    newimage = PIL_Image.new("RGBA", newsize)
    
    
    for i in range(0, extrude_width):
        newimage.paste(top_edge, (extrude_width, i))
        newimage.paste(left_edge, (i, extrude_width))
        newimage.paste(right_edge, (nw - i - 1, extrude_width))
        newimage.paste(bottom_edge, (extrude_width, nh - i - 1))
        for j in range(0, extrude_width):
            newimage.paste(left_top_point, (i, j))
            newimage.paste(right_top_point, (nw - i - 1, j))
            newimage.paste(right_bottom_point, (nw - i - 1, nh - j - 1))
            newimage.paste(left_bottom_point, (i, nh - j - 1))
    
    # copy center
    newimage.paste(image, (extrude_width, extrude_width))
    
    # save new image
    newimage.save('newimage.png')
    

    这个脚本里改变 extrude_width 就可以指定要扩展多少个像素,通常四周各扩展一个像素就够用了。

    这个脚本依赖 Pillow 库,所以先得用 easy_setup 或者 pipPillow 库装上。

    经过上述处理,Tilemap 看上去就没有任何缝隙了。

    final-map.png

    -EOF-

    相关文章

      网友评论

        本文标题:彻底解决 Unity 中 Tilemap 缝隙问题

        本文链接:https://www.haomeiwen.com/subject/tqtfxxtx.html