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的圖片,那麼關於這張圖片的屬性就會存儲在一個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在寫這篇文章時候是在家裏,這個工具的代碼是在公司的電腦上,所以如果有需要再貼出來吧

發佈了39 篇原創文章 · 獲贊 17 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章