Cocos Creator 資源載入流程剖析【五】——從編輯器到執行時

寶爺發表於2019-05-09

我們在編輯器中看到的資源,在構建之後會進行一些轉化,本章將揭開Creator對資源進行的處理。

資源處理的整體規則

首先我們將Creator的開發和執行劃分為以下幾個場景:

編輯器

當我們將資源放到編輯器中時,Creator會為每個資源生成唯一的uuid以及meta檔案,並在專案的library目錄下生成對應的json檔案來描述這個資源的資訊,而uuid與資源的對映關係被放在library目錄下的uuid-to-mtime.json檔案中。由於資源的引用關係是靠uuid來維繫的,所以我們可以在Creator中隨意地修改資原始檔名、移動資源路徑,而不用擔心資源的關聯丟失問題。

我們在編輯器中編輯的prefab、anim、場景等檔案本質上是一個json檔案,Cocos Creator 設計了一套json規則用於描述各種資源,prefab的json描述了prefab的結構以及每個節點的屬性,但部分屬性會放到meta檔案中,一般是針對該資源在編輯器中的設定。

預覽

預覽的時候使用的是library目錄下的資源,不僅僅是專案assets目錄下的所有資源(包括未被引用到的資源),引擎提供的一些預設資源也可以在library目錄下找到。預覽的模板位於引擎安裝目錄下的resources/static/preview-templates,程式的啟動指令碼為boot.js。

構建

專案構建之後,資源會從library目錄下移動到構建輸出的目錄中,基本只會匯出參與構建的場景和resources目錄下的資源,及其引用到的資源。指令碼資源會由多個js指令碼合併為一個js,各種json檔案也會按照特定的規則進行打包(所謂的packAssets)。

各種資源的處理

  • 基礎圖片

圖片的meta檔案大概如下所示,除了ver和uuid之外,還有3個屬性:

  • Type有sprite和raw兩種,如果選擇了raw,那麼就不會有subMetas等屬性,而且在Creator的資源管理器皮膚中可以發現這個圖片左邊的小箭頭消失了。
  • WrapMode為環繞模式,包含clamp差值和repeat重複兩種,但這裡的設定在Creator中一般是無效的,因為在Sprite元件中是用Type進行控制,它提供了九宮格、平鋪、填充等方式。
  • FilterModel提供了3種差值過濾選項,Point點差值、Bilinear雙線性差值、Trilinear三線性差值,效能依次下降,效果依次提升。

這裡的subMetas描述了一個SpriteFrame資訊,詳情可參考Sprite元件

{
  "ver": "2.0.0",
  "uuid": "a0576798-bdf4-4f06-972e-5557dee6ee1b",
  "type": "sprite",
  "wrapMode": "clamp",
  "filterMode": "bilinear",
  "subMetas": {
    "boss_b_hp1": {
      "ver": "1.0.3",
      "uuid": "5425ad9a-e2e0-4c6e-825b-c3ea43b09e4e",
      "rawTextureUuid": "a0576798-bdf4-4f06-972e-5557dee6ee1b",
      "trimType": "auto",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": 0,
      "trimX": 0,
      "trimY": 0,
      "width": 78,
      "height": 78,
      "rawWidth": 78,
      "rawHeight": 78,
      "borderTop": 0,
      "borderBottom": 0,
      "borderLeft": 0,
      "borderRight": 0,
      "subMetas": {}
    }
  }
}

這樣的一個圖片會在library/imports/xx目錄下生成3個檔案(如果將圖片的type設定為raw則不會有SpriteFrame對應的json檔案),分別是以圖片uuid為檔名的json檔案和png,以及SpriteFrame的uuid為檔名的json檔案

Texture對應的json檔案內容如下,每一個紋理都會生成一個這樣的重複的檔案:

{
  "__type__": "cc.Texture2D",
  "content": "0"
}

SpriteFrame對應的json檔案內容如下:

{
  "__type__": "cc.SpriteFrame",
  "content": {
    "name": "boss_b_hp1",
    "texture": "a0576798-bdf4-4f06-972e-5557dee6ee1b",
    "atlas": "",
    "rect": [
      0,
      0,
      78,
      78
    ],
    "offset": [
      0,
      0
    ],
    "originalSize": [
      78,
      78
    ]
  }
}

在構建之後,資源會被匯出到res目錄下,json檔案放在import目錄下,png等資原始檔放在raw-assets目錄

  • 圖集資源

圖集分為plist和圖片兩個檔案,圖集圖片的meta和普通圖片的meta一樣,而plist檔案的meta記錄了圖集中所有碎圖的資訊。主要有ver、uuid、rawTextureUuid、size、type以及subMetas等屬性,subMetas記錄了每一個碎圖的meta資訊,結構和普通圖片的meta一樣。

{
  "ver": "1.2.4",
  "uuid": "315d61c8-b6c8-4635-b517-f868dd8b3495",
  "rawTextureUuid": "01979186-b9a2-4130-a307-a2eacb5fe30f",
  "size": {
    "width": 1024,
    "height": 1024
  },
  "type": "Texture Packer",
  "subMetas": {
    "role1001-move1.png": {
      "ver": "1.0.3",
      "uuid": "8e225dbc-7905-416f-a7ac-0730893ad30d",
      "rawTextureUuid": "01979186-b9a2-4130-a307-a2eacb5fe30f",
      "trimType": "auto",
      "trimThreshold": 1,
      "rotated": false,
      "offsetX": 0,
      "offsetY": -52,
      ...

在library目錄下會生成plist的json檔案,type為cc.SpriteAtlas,記錄了圖集中所有spriteFrames的uuid,每一個碎圖都會有一個描述其SpriteFrame的json檔案生成。最後,圖片檔案照常會有一個Texture和SpriteFrame的json生成。

{
  "__type__": "cc.SpriteAtlas",
  "_name": "role1001.plist",
  "_objFlags": 0,
  "_native": "",
  "_spriteFrames": {
    "role1001-move1": {
      "__uuid__": "8e225dbc-7905-416f-a7ac-0730893ad30d"
    },
    "role1001-move2": {
      "__uuid__": "7e0641ef-5974-4c2d-bad3-80c59a3195d8"
    },
    ...

構建之後,cc.SpriteAtlas與所有的cc.SpriteFrame會合為一個json,而圖片本身仍然會匯出cc.Texture和cc.SpriteFrame的json。

【合併初始場景依賴的所有json】會讓所有用到的json都合併成一個。【內聯所有SpriteFrame】會將所有用到的SpriteFrame的json資訊複製到引用它們的場景或prefab的json中,如果是單獨的一個SpriteFrame,會被直接合並。(這種情況下,其他場景載入該資源時如何處理?即該資源已經被打包到其他場景或prefab中。多個prefab同時引用時誰能打包到該資源呢?載入一個打包資源中的一個json,是否會直接載入該json包中的所有json)

  • AutoAtlas自動圖集

AutoAtlas可以自動將當前目錄以及子目錄下所有的圖片進行合圖,他的meta檔案描述了合圖的規則,如最大尺寸、是否允許旋轉、是否強制圖片轉為正方形、尺寸是否為2的冪、使用的合圖演算法等等...

{
  "ver": "1.1.0",
  "uuid": "691bdbcd-78c9-41da-864f-481d1af5c8ff",
  "maxWidth": 1024,
  "maxHeight": 1024,
  "padding": 2,
  "allowRotation": true,
  "forceSquared": false,
  "powerOfTwo": true,
  "heuristices": "BestAreaFit",
  "format": "png",
  "quality": 80,
  "contourBleed": false,
  "paddingBleed": false,
  "filterUnused": false,
  "subMetas": {}
}

而在library目錄下,AutoAtlas只會生成一個簡單的json檔案,在預覽的時候,AutoAtlas不會發生任何作用。

{
  "__type__": "cc.SpriteAtlas",
  "_name": "AutoAtlas"
}

構建之後,會生成cc.SpriteAtlas型別的一個json檔案,記錄所有碎圖的uuid。AutoAtlas所在目錄下的碎圖會合成一張,而它們的SpriteFrame資訊則不會像plist圖集一樣合併到圖集的json檔案中,而是每個SpriteFrame一個json檔案。

{
  "__type__": "cc.SpriteAtlas",
  "_spriteFrames": {
    "building_01": {
      "__uuid__": "d47RnkKqBHw6xXpAKXUDWt"
    },
    "building_02": {
      "__uuid__": "a8CDt9ghBA5LzcZdD79OcY"
    },
    "building_03": {
      "__uuid__": "f4JnL6lkFFjZC9QkBYLbZM"
    },
    "building_04": {
      "__uuid__": "0cwdvX5/pBXYpf4xhZG+I+"
    },
    "building_05": {
      "__uuid__": "64GzrRUetDzreLftZ9Unt5"
    }
  }
}
  • 場景與prefab

場景和prefab類似,都是用一個json檔案來描述節點樹。json檔案首先描述一個陣列,陣列的第一個元素(下標0)描述的是該資源的型別以及該資源特定的屬性,接下來是一個一個的節點、元件物件,每個物件都描述了自身的各種屬性,以及它們和其它物件的關係,其中的__id__欄位對應的值表示當前json陣列的下標。

[
  // 陣列的第一個元素,資源概述
  {
    "__type__": "cc.prefab",    // 型別,場景的__type__為cc.SceneAsset
    "_name": "",
    "_objFlags": 0,
    "_native": "",
    "data": {                   // 資料(該prefab的根節點id),場景為scene欄位
      "__id__": 1
    },
    "optimizationPolicy": 0,    // 建立優化策略(場景無該選項)
    "asyncLoadAssets": false    // 是否開啟延遲載入資源(場景無該選項)
  },
  
  // 陣列的第二個元素,prefab的根節點,其name為Base,有2個子節點,id為2和5
  {
    "__type__": "cc.Node",
    "_name": "Base",
    "_objFlags": 0,
    "_parent": null,
    "_children": [
      {
        "__id__": 2
      },
      {
        "__id__": 5
      }
    ],
    "_tag": -1,
    "_active": true,
    "_components": [],
    "_prefab": {
      "__id__": 8
    },
    "_id": "",
    "_opacity": 255,
    "_color": {
      "__type__": "cc.Color",
      "r": 255,
      "g": 255,
      "b": 255,
      "a": 255
    },
    "_cascadeOpacityEnabled": true,
    "_anchorPoint": {
      "__type__": "cc.Vec2",
      "x": 0.5,
      "y": 0.5
    },
    "_contentSize": {
      "__type__": "cc.Size",
      "width": 0,
      "height": 0
    },
    "_rotationX": 0,
    "_rotationY": 0,
    "_scaleX": 1,
    "_scaleY": 1,
    "_position": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_skewX": 0,
    "_skewY": 0,
    "_localZOrder": 0,
    "_globalZOrder": 0,
    "_opacityModifyRGB": false,
    "groupIndex": 0
  },
  {
    ...
  },
  // Sprite元件的資料,它掛載在本陣列中下標為2的Node上(第三個元素)
  {
    "__type__": "cc.Sprite",
    "_name": "",
    "_objFlags": 0,
    "node": {
      "__id__": 2
    },
    "_enabled": true,
    "_spriteFrame": {
      // 所有的__uuid__都指向了一個新的資源
      "__uuid__": "d4ed19e4-2aa0-47c3-ac57-a402975035ad"
    },
    "_type": 0,
    "_sizeMode": 1,
    "_fillType": 0,
    "_fillCenter": {
      "__type__": "cc.Vec2",
      "x": 0,
      "y": 0
    },
    "_fillStart": 0,
    "_fillRange": 0,
    "_isTrimmedMode": true,
    "_srcBlendFactor": 770,
    "_dstBlendFactor": 771,
    "_atlas": null
  },
  {
    "__type__": "cc.prefabInfo",
    "root": {
      "__id__": 1
    },
    "asset": {
      "__id__": 0
    },
    "fileId": "acUWY0/UZLeZdVqtcRkZuq",
    "sync": false
  },
  ...
]
  • 關於資源依賴和prefab巢狀
    • 場景和prefab依賴的資源,我們都可以在它們的json檔案中,找到__uuid__這樣的屬性,通過這個欄位記錄了資源間的依賴。
    • 檢視了最新的CocosCreator2.x,目前的prefab還不支援真正意義上的巢狀,目前的巢狀prefab本質上是將一個prefab的內容拷貝到另一個prefab中。
  • 關於掛載指令碼
    • 自定義的指令碼元件掛載到prefab或場景的某節點時,在json檔案中生成的元件物件的__type__對應的是該指令碼的23位uuid。
    • 指令碼定義了資源類變數,可在屬性檢查器中拖拽資源賦給指令碼變數的,prefab會記錄該資源的__uuid__,如果拖拽了prefab自身的節點,則記錄其__id__
    // 元件的__type__為指令碼的23位uuid
    "_components": [
      {
        "__type__": "b8386waIgRGVJwXT7yno4pm",
        "node": {
          "__id__": 1
        },
        // myRootNode和mySpriteFrame為指令碼中的2個變數,在屬性檢查器中拖拽的
        "myRootNode": { // myRootNode記錄著當前prefab中id為2的節點
          "__id__": 2
        },
        "mySpriteFrame": {  // mySpriteFrame記錄著一個外部的SpriteFrame的uuid
          "__uuid__": "40t3EpX7tCnq5b2lM2bG8F"
        },
      }
    ],

Scene和prefab對應的meta檔案比較簡單,prefab包含了建立優化策略選項,Scene包含了是否自動釋放資源選項,他們都包含了是否延遲載入資源的選項。大致如下所示:

// prefab的meta檔案內容
{
  "ver": "1.0.0",
  "uuid": "c7d921c2-6021-4613-93bd-6201de418e24",
  "optimizationPolicy": "AUTO",
  "asyncLoadAssets": false,
  "subMetas": {}
}

// scene檔案的meta檔案內容
{
  "ver": "1.0.0",
  "uuid": "2afc2a6e-f61e-4f46-8a52-af34d838a4b0",
  "asyncLoadAssets": false,
  "autoReleaseAssets": false,
  "subMetas": {}
}

在library目錄下,以及構建目錄中,prefab和scene基本是json檔案本身內容的一個複製。可能會根據prefab和scene的選項稍微修改json陣列首元素的內容(比如新增asyncLoadAssets欄位)。

  • Creator動畫

Creator動畫儲存在anim檔案中,每一個anim都是一個動畫Clip。我們可以在Creator中的資源管理器右鍵/新建/Animation Clip來建立新的anim動畫檔案。要使用動畫我們需要為一個節點掛載Animation元件,然後將anim檔案拖拽到Animation元件的clips屬性中。關於Creator動畫的更多詳情可以參考官方文件 https://docs.cocos.com/creator/manual/zh/animation/

anim檔案本質是一個json檔案,它的內容大致如下,除了Creator標準的json欄位,以及Clip的全域性屬性(wrapMode、speed等)外,curveData欄位記錄所有的動畫資訊,events欄位記錄了該動畫中所有的幀事件。它的meta檔案只記錄了ver、uuid以及一個空的subMetas。

{
  "__type__": "cc.AnimationClip",
  "_name": "1",
  "_objFlags": 0,
  "_native": "",
  "_duration": 0.25,
  "sample": 60,
  "speed": 1,
  "wrapMode": 1,
  "curveData": {
    "paths": {
      "build_b_2": {
        "props": {
          "position": [
            {
              "frame": 0,
              "value": [
                39,
                29
              ]
            },
            {
              "frame": 0.25,
              "value": [
                109,
                29
              ]
            }
          ]
        }
      }
    }
  },
  "events": [
    {
      "frame": 0.25,
      "func": "",
      "params": []
    }
  ]
}

該檔案會被直接拷貝到library目錄下,構建之後會直接匯出該檔案。

  • 聲音音效類資源

聲音音效資源的meta檔案非常簡單,目前唯一的一個自定義屬性就是downloadMode,即聲音的載入模式,有Web Audio和DOM Audio兩種。前者相容性更好,但會佔用更多的記憶體,故建議短音效用Web Audio,長音樂使用DOM Audio。

{
  "ver": "2.0.0",
  "uuid": "ab548e86-4fca-4320-a8a0-0c1a714d1443",
  "downloadMode": 0,
  "subMetas": {}
}

在library目錄下,Creator會為每個聲音資源生成一個以uuid為命名的json檔案,以及將聲音檔案以uuid命名。json檔案的內容如下:

{
  "__type__": "cc.AudioClip",
  "_name": "music_logo",
  "_objFlags": 0,
  "_native": ".mp3",
  "loadMode": 0
}

構建之後library目錄下的json和聲音檔案會被複制到構建目錄下的import和raw-assets目錄中。

  • Spine骨骼動畫

每個Spine都是由json(Creator暫時不支援skel格式)、atlas、png三個檔案組成,它們的meta檔案非常簡單,沒有什麼特殊的資訊。

在library目錄下,png會生成對應的SpriteFrame和Texture的json,以及圖片自身。atlas會生成一個簡單的json檔案,如下所示。骨骼json會進行轉換,變成Creator標準的資源格式json,以uuid命名,在當前目錄下會建立一個以uuid命名的目錄,放著轉換前的Spine json檔案,名為raw-skeleton.json。(Creator格式的json比原Spine的json要大不少)

{
  "__type__": "cc.Asset",
  "_name": "raptor",
  "_native": ".atlas"
}

構建之後,png對應的SpriteFrame、Texture的json,以及Atlas的json。Spine本身的json會轉換成Creator標準的資源格式json輸出到構建目錄下,而且raw-skeleton.json並不在構建目錄中。

  • 指令碼資源的處理

在Creator中支援TS和JS指令碼,這裡不討論如何編寫指令碼。指令碼的meta檔案中有幾個有意思的屬性,與Plugin相關,意為是否將該指令碼作為外掛匯入。對第三方外掛或者底層外掛,有可能需要選中Plugin選項,這樣的指令碼簡稱外掛指令碼(未勾選該選項的為普通指令碼)。指令碼外掛在打包時是不會參與構建的。

關於該選項的詳細介紹可以檢視 https://docs.cocos.com/creator/manual/zh/scripting/plugin-scripts.html

{
  "ver": "1.0.5",
  "uuid": "8c87839a-4fd0-4b9e-9363-23bbf1bd16ef",
  "isPlugin": false,
  "loadPluginInWeb": true,
  "loadPluginInNative": true,
  "loadPluginInEditor": false,
  "subMetas": {}
}

在library目錄下,TS會被編譯成JS指令碼,所有的JS指令碼都會以其uuid命名儲存。與JS檔案一起生成的還有map檔案(這裡放著編譯前的原檔案內容和路徑等相關資訊)。

構建之後所有的TS和JS指令碼會被編譯成JS,打包到一個project.dev.js檔案中。構建一般會生成4個js,記錄所有資源相關設定的settings.js,啟動指令碼main.js,開發者的程式碼project.dev.js以及cocos引擎cocos2d-js.js。如果開啟了除錯模式,構建出來的js會被精簡為一行,剔除所有的註釋和空行換行,並自動將一些變數名進行混淆,使用更簡短的命名,而不影響程式碼執行的效果。如果開啟了Source Maps,構建程式碼時會生成map檔案,否則不會生成。

我們可以在Creator編輯器中的專案選單/專案設定/模組設定下選擇剔除我們不需要用到的模組,從而精簡cocos2d-js.js檔案的大小(新一代的js打包工具如rollup.js已經可以支援到在打包的時候自動根據引用到的程式碼去剔除無用程式碼)。

  • 字型資源的處理

CocosCreator的字型可以分為3類,系統字、BMFont以及TTF字型。系統字不需要額外的字型資源,而是使用內建的系統字型。BMFont的資源是一張圖片以及一個fnt。而TTF字型的資源是一個TTF檔案。

fnt資源的meta檔案如下所示,指定了fontSize,以及使用的紋理。

{
  "ver": "2.1.0",
  "uuid": "e2fd9257-452a-4ae2-a932-e567c5fd6e91",
  "textureUuid": "1afd96d7-225c-484b-ab27-fe12902096d6",
  "fontSize": 32,
  "subMetas": {}
}

在library目錄下,除了圖片相關的Texture、SpriteFrame等json。fnt檔案會被轉成一個cc.BitmapFont的json檔案,檔案內容如下所示,_fntConfig描述了fnt字型的字號、寬高、圖集以及每一個字在圖集中的座標尺寸等資訊。

{
  "__type__": "cc.BitmapFont",
  "_name": "b0",
  "_objFlags": 0,
  "_native": "",
  "fntDataStr": "",
  "spriteFrame": {
    "__uuid__": "a3e89811-562f-4a58-943f-895c807f087b"
  },
  "fontSize": 32,
  "_fntConfig": {
    "commonHeight": 32,
    "fontSize": 32,
    "atlasName": "b0_0.png",
    "fontDefDictionary": {
      "36": {
        "rect": {
          "x": 81,
          "y": 0,
          "width": 79,
          "height": 111
        },
        "xOffset": 0,
        "yOffset": 0,
        "xAdvance": 79
      },
      ...

構建之後,cc.BitmapFont和SpriteFrame這2個json會被合併(我們往往需要同時使用到它們)。

TTF的meta檔案只有ver、uuid和空的subMetas欄位。在library目錄下會生成一個以TTF資源的uuid命名的json檔案,在相同目錄下有一個以TTF資源的uuid目錄,目錄下放著ttf資源。

{
  "__type__": "cc.TTFFont",
  "_name": "BlackHanSans-Regular",
  "_objFlags": 0,
  "_native": "BlackHanSans-Regular.ttf"
}

構建後該json檔案會剔除_objFlags欄位後匯出,而TTF檔案會匯出到raw-assets目錄下。

  • 粒子資源的處理

粒子資源大致可以分為plist和prefab兩種:

  • 對於plist粒子,存在圖片使用Base64編碼合併到plist檔案中,和引用外部粒子圖片的區別。plist的meta檔案只有ver、uuid和空的subMetas欄位。在library目錄下會生成plist和它對應的json檔案,如下所示,如果是帶紋理的粒子,會生成對應的Texture和SpriteFrame的json。構建之後會匯出plist的json檔案,在raw-assets中匯出plist檔案,如果引用了外部紋理也會匯出紋理對應的圖片和json。
{
  "__type__": "cc.ParticleAsset",
  "_name": "p_star_fly",
  "_objFlags": 0,
  "_native": ".plist",
  "texture": {
    "__uuid__": "1544eed3-42e4-46fc-a392-0c4d8b1b9847"
  }
}
  • prefab型別的粒子和普通的prefab一樣,library目錄下會生成prefab的json檔案(包含所有的粒子屬性)以及粒子的plist檔案(library目錄下預設會有一些內建的粒子系統)。而構建之後,如果粒子系統的File欄位指定了一個plist檔案,構建出來的raw-assets目錄中會匯出plist,而匯出的粒子json是一個比較簡短的json(因為大部分的屬性都定義在plist檔案中了),除非我們在編輯器中編輯了自定義的屬性。

資源打包規則

在瞭解了Creator對單個資源的處理之後,我們要對Creator資源打包規則做更深入的分析。對於資源打包,我們主要關注的2點是IO和包體,json的合併可以減少IO操作,在某些情況下也可能增大包體。

關於圖片的合併

在Creator構建後每一個圖片都會生成一個描述cc.Texture2D的json以及一個cc.SpriteFrame的json,而其中所有的cc.Texture2D.json都會被合併成一個,應該說一個專案在構建之後,正常來說最多隻會有一個cc.Texture2D的json,只是它的data欄位會很長。不論圖片是來自不同目錄的圖片、圖集、自動圖集、Spine、粒子系統或者BMFont等等,都不影響它們的cc.Texture2D.json被合併。

{
  "type": "cc.Texture2D",
  "data": "0|0|0|0|0|0|0|0|0|0|0|0"
}

圖片對應的SpriteFrame又會被怎樣合併呢?預設的情況下(即不考慮依賴和構建選項的情況)只有plist圖集和BMFont字型這兩種資源的SpriteFrame會有合併的操作。plist的json會與圖集中所有的SpriteFrame的json合併為一個json。BMFont字型的fnt對應的json會與SpriteFrame合併為一個json。

接下來我們來看一下資源依賴的情況,使用prefab去引用各種型別的資源,json又會如何合併呢?prefab引用的所有資源中,只有單個圖片和自動圖集中的SpriteFrame會被合併到prefab的json中。

如果我們在構建時勾選了“內聯所有SpriteFrame”,json又會如何合併呢?除了單個圖片和自動圖集,prefab中用到的圖集的SpriteFrame也會被合併進來,但圖集的合併是拷貝,也就是說原來的圖集和圖集中所有SpriteFrame合併的那個json仍然存在。

如果我們的資源同時被多個prefab引用,在這種情況下,是否勾選“內聯所有SpriteFrame”又會有怎樣的區別呢?

  • 不勾選的情況下,圖集多個prefab共同引用的部分SpriteFrame會被提取出來進行合併(單張圖片和AutoAtlas)。共同部分至少需要2個SpriteFrame,比如說A和B,每一個引用到公共SpriteFrame的prefab必定同時引用到A和B,如果有一個prefab只引用了A,那麼A和B就不會被合併。

Fa6qC6.png

  • 勾選的情況下,不存在共用資源的說法,每個prefab都會合並它用到的SpriteFrame(單張圖片、AutoAtlas、圖集),如果這些資源被多個prefab引用,那麼會被複制到每一個prefab的json中。

Fa6H4x.png

前面介紹了prefab的依賴對構建打包的影響,在Creator中,除了prefab可以去引用資源外,場景也可以引用外部資源,但正常情況下場景不會去將其引用的SpriteFrame打包進來。在勾選了“內聯所有SpriteFrame”的情況下,場景的json才會去合併引用到的SpriteFrame。

在勾選了“合併初始場景依賴的所有JSON”後,初始場景引用到的所有json都會被合併到初始場景的json檔案中,這種合併不是拷貝,而是將場景引用到的所有資源的json檔案合併到一起(除了SpriteFrame外,還有粒子json、plist圖集完整json、Spine骨骼json、BMFont字型json、動畫json等等)。如果沒有勾選“內聯所有SpriteFrame”,這些json只會放在啟動場景的json中,不會影響包體。值得一提的是圖片的cc.Texture2D這個json,所有被初始場景引用到的紋理會從這個json中剝離,併合併到初始場景。

相關文章