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在寫這篇文章時候是在家裏,這個工具的代碼是在公司的電腦上,所以如果有需要再貼出來吧