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在写这篇文章时候是在家里,这个工具的代码是在公司的电脑上,所以如果有需要再贴出来吧