在制作游戏时,经常需要用到将较小的重复循环的纹理图像拼成一个大图,比如地面上的尖刺,或是墙面砖块背景。遇到这种问题时通常的处理手段是像tilemap那样用单张纹理图片作为一个tile(unity中一般用sprite),将多个tile拼接起来形成一张大图。
例如有一张256x256的无缝墙面纹理,我希望用这张图铺满一个512x512大小的墙面, 512x512的墙面正好需要4个256x256的tile来拼接,拼接完成时如图1所示。
图1
但是这样处理要求拼接后的图像大小的宽和高需要分别为原图宽和高的整数倍,这样比较好处理。为了尽量满足这个要求,通常会将用作tile的图片做的非常小,这样可以满足尽量多的拼接图片不同大小的情况。
有没有一种更灵活的方式来处理这种问题,只用一个sprite就可以做出任意大小的墙面呢?
那必须有啊!
其实我们可以借助shader来完成这样一个效果。在opengl中有一个参数叫做GL_TEXTURE_WRAP,就是在纹理超出边界怎么处理。有一种模式是GL_REPEAT,就是可以将纹理进行重复。受到这个启发,我们是不是也可以利用这种重复模式,来实现缩放sprite时,纹理的大小不变,多出的部分则自动用重复的纹理进行铺满呢?
当然可以!只不过会麻烦一些......
unity中,纹理有一个wrap mode属性,可以设置成repeat或是clamp,其中repeat就是我们想要的重复模式。但是unity2d会自动将导入的纹理转换成sprite类型纹理,在sprite类型纹理的属性中,我们无法调整纹理的wrap mode属性所以我们首先需要将导入的纹理变成texture类型,如图2所示。修改完之后记得点apply进行保存。
图2
之后我们在unity编辑器新建一个sprite,这是我们发现新建的sprite不能直接使用我们修改的纹理了,所以我们需要通过脚本来用纹理生成一个sprite对象,赋给新建的sprite。像这样:
<div style="text-align: left;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>// 将你的纹理<span style="font-size: 18px; white-space: pre; background-color: rgb(240, 240, 240);">YourTextureForSprite变成sprit