texturepack想必大家都很熟悉,这个工具可以讲许多张散图合并成一张大图,同时生成一个plist文件,该plist文件记录了原先散图所在生成的大图中的坐标以及大小什么的,这个工具在cocos2d-x上是很方便的。而在unity上呢?unity官方时自带了一个切图工具的,如下图,选中一张图片,在它的inspector中将sprite mode改为multiple,然后点击sprite editor就可以编辑该图片了,可以切成一块块然后使用:
但是unity的这个工具我觉得很不好用,难道美术那边做好了小散图之后合成大图,我们这边还要一个个再在unity中切块才能在工程中使用么?而且每当美术增加了图片之后,由于从新生成了一些数据,会使得图片发生错位,也就是本来这张图片应该使用的是这个小散图,却无缘无故变成了另外一张小散图能不能利用texturepack生成的plist文件为我们自动生成这些切块呢?答案是肯定的,所以本id就自己动手写了工具,由于本id熟悉c++,所以就用了mfc来完成这个工具。
第一步,我们首先需要知道在unity到底使用了什么来保存图片的数据,本id机智的通过文件名搜索找到了meta文件,对,unity工程中,每一张图片都对应这一个meta文件,比如有一张test.png的图片,那么关于这张图片的属性就会存储在一个test.png.meta的文件中,接下来就是分析meta这个文件是怎么记录图片的属性的。我这里是将图片里面切了四块,我们来先看看这样的图片对应的meta文件是怎么样的,为了方便说明我在文件的行尾加了注释,后面的注释只需要理解就可以,不必出现在meta文件里:
fileFormatVersion: 2 guid: 17cf490d12bfbff4097a8f8e8f631ef5 unity通过这个找到对应的大图,所以我们后面通过plist生成的meta文件的这个值时必须要一致的 timeCreated: 1448287112 licenseType: Pro TextureImporter: fileIDToRecycleName: 由213000开头的便是里面的散图的命名,不过unity并不是记录的并不是后面的名字,而是通过前面的序列号213000什么的来找到图片名字,然后再通过名字来找到需要的数据,这也就是造成了上述的图片错位的原因,因为新增加的图片加了进来,可能会造成原来的id与原来的图片名字发生错乱 21300002: bingztxblz_1 21300004: bingztxblz_2 21300006: bingztxblz_3 由于我只将大图切出来四个小图,所以是四个标志,由于unity是通过前面的序号来找图片名字,再通过名字来找到图片数据,所以我们就可以将序号后面的名字进行替换,替换成plist中的名字,这样才能跟美术保持一致 serializedVersion: 2 mipmaps: mipMapMode: 0 enableMipMap: 1 linearTexture: 0 correctGamma: 0 fadeOut: 0 borderMipMap: 0 mipMapFadeDistanceStart: 1 mipMapFadeDistanceEnd: 3 bumpmap: convertToNormalMap: 0 externalNormalMap: 0 heightScale: .25 normalMapFilter: 0 isReadable: 0 grayScaleToAlpha: 0 generateCubemap: 0 cubemapConvolution: 0 cubemapConvolutionSteps: 8 cubemapConvolutionExponent: 1.5 seamlessCubemap: 0 textureFormat: -1 maxTextureSize: 1024 textureSettings: filterMode: -1 aniso: 16 mipBias: -1 wrapMode: 1 nPOTScale: 0 lightmap: 0 rGBM: 0 compressionQuality: 50 spriteMode: 2 spriteExtrude: 1 spriteMeshType: 1 alignment: 0 spritePivot: {x: .5, y: .5} spriteBorder: {x: 0, y: 0, z: 0, w: 0} spritePixelsToUnits: 100 alphaIsTransparency: 1 textureType: 8 buildTargetSettings: []由这里开始便是每一张小图里面的数据,比如所在坐标,大小等等 spriteSheet: sprites: - name: bingztxblz_0 rect: serializedVersion: 2 x: 0 y: 59 width: 30 height: 30 alignment: 0 pivot: {x: 0, y: 0} border: {x: 0, y: 0, z: 0, w: 0} - name: bingztxblz_1 rect: serializedVersion: 2 x: 30 y: 59 width: 30 height: 30 alignment: 0 pivot: {x: 0, y: 0} border: {x: 0, y: 0, z: 0, w: 0} - name: bingztxblz_2 rect: serializedVersion: 2 x: 0 y: 29 width: 30 height: 30 alignment: 0 pivot: {x: 0, y: 0} border: {x: 0, y: 0, z: 0, w: 0} - name: bingztxblz_3 rect: serializedVersion: 2 x: 30 y: 29 width: 30 height: 30 alignment: 0 pivot: {x: 0, y: 0} border: {x: 0, y: 0, z: 0, w: 0} spritePackingTag: userData: assetBundleName: assetBundleVariant:
下面我们再来看看plist文件是怎么样的:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>frames</key> <dict> <key>chat1.png</key> 这里就是小散图的数据了,包含了图片大小,在大图中的坐标等等,我们需要将这里的数据转为meta中的数据 </span> <dict> <key>frame</key> <string>{{1,169},{222,191}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{222,191}}</string> <key>sourceSize</key> <string>{222,191}</string> </dict> </span> <span style="color:#ff0000;"><key>chat2.png</key> <dict> <key>frame</key> <string>{{224,169},{225,160}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{225,160}}</string> <key>sourceSize</key> <string>{225,160}</string> </dict> <key>chat3.png</key> <dict> <key>frame</key> <string>{{298,1},{78,76}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{78,76}}</string> <key>sourceSize</key> <string>{78,76}</string> </dict> <key>chat4.png</key> <dict> <key>frame</key> <string>{{377,1},{78,76}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{78,76}}</string> <key>sourceSize</key> <string>{78,76}</string> </dict> <key>chat5.png</key> <dict> <key>frame</key> <string>{{1,1},{296,167}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{296,167}}</string> <key>sourceSize</key> <string>{296,167}</string> </dict> <key>select_chat.png</key> <dict> <key>frame</key> <string>{{224,330},{215,57}}</string> <key>offset</key> <string>{0,0}</string> <key>rotated</key> <false/> <key>sourceColorRect</key> <string>{{0,0},{215,57}}</string> <key>sourceSize</key> <string>{215,57}</string> </dict> </dict> <key>metadata</key> <dict> <key>format</key> <integer>2</integer> <key>realTextureFileName</key> <string>ui_chat.png</string> <key>size</key> <string>{512,512}</string> <key>smartupdate</key> <string>$TexturePacker:SmartUpdate:9174790d5600f8017cf2643d841134ba$</string> <key>textureFileName</key> <string>ui_chat.png</string> </dict> </dict> </plist>
明白了上面的关于unity图片的调用,meta以及plist的文件存储原理,我们就可以开始大刀阔斧地干了,其中需要注意的地方有
1,plist的文件中的坐标系是以上角为原点,而unity的meta文件是以左下角为原点,所以需要做一个相减的处理;
2,meta文件中guid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx必须保持一致否则原来使用了该图的工程中的图片会找不到图片;
3,如果新增加了图片,那么我们一定要保证原来的图片名字与id在新文件中也是一样的,比如原meta文件中有21300000: bingztxblz_0,那么新生成的meta文件也必须要是21300000: bingztxblz_0,否则会发生图片错乱,至于新增加的文件,可以增加在原id的末尾
本id在写这篇文章时候是在家里,这个工具的代码是在公司的电脑上,所以如果有需要再贴出来吧