unity使⽤texturepack更新图⽚时图⽚错位的解决
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的图⽚,那么关于这张图⽚的属性就会存储在⼀个a的⽂件中,接下来
就是分析meta这个⽂件是怎么记录图⽚的属性的。我这⾥是将图⽚⾥⾯切了四块,我们来先看看这样的图⽚对应的meta⽂件是怎么样的,
为了⽅便说明我在⽂件的⾏尾加了注释,后⾯的注释只需要理解就可以,不必出现在meta⽂件⾥:
fileFormatVersion: 2
guid: 17cf490d12bfbff4097a8f8e8f631ef5  unity通过这个到对应的⼤图,所以我们后⾯通过plist⽣成的meta⽂件的这个值时必须要⼀致的
timeCreated: 1448287112
licenseType: Pro
TextureImporter:
fileIDToRecycleName:    由213000开头的便是⾥⾯的散图的命名,不过unity并不是记录的并不是后⾯的名字,⽽是通过前⾯的序列号213000什么的来到图⽚名字    21300002: bingztxblz_1
21300004: bingztxblz_2
21300006: bingztxblz_3  由于我只将⼤图切出来四个⼩图,所以是四个标志,由于unity是通过前⾯的序号来图⽚名字,再通过名字来到图⽚数据,所以我们就  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" "www.apple/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 ><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>
recycle是什么意思<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>
<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在写这篇⽂章时候是在家⾥,这个⼯具的代码是在公司的电脑上,所以如果有需要再贴出来吧