1. 程式人生 > >Cocos Creator 釋出到微信小遊戲的資源管理

Cocos Creator 釋出到微信小遊戲的資源管理

本文由本人簡書搬遷至此,並做小幅修改。

環境:Cocos Creator v1.9.1; 微信web開發者工具 v1.02.0808300,線上基礎除錯庫 1.9.92。


以下,ccc指cocos creator。資源均指Texture、Audio等非Prefab和場景的原生資源。

1. ccc resources下的資源會被全部放入小程式 res/raw-assets/resources 對應目錄下。

2. ccc 不在resources下,但直接被“參與構建的Scene”引用的資源, 會被放入小程式res/raw-assets/對應目錄下。
注意:
如果Scene為構建時正在開啟的MainScene, 該Scene會被強制參與構建。
如果Scene在resources下,該Scene會被強制參與構建。

3. ccc 參與構建的Scene(實際是個json檔案。可用文字編輯器開啟看)會被 將其內容以json檔案的形式放入res/import目錄下。

4. ccc 不在resources下,但被reources下prefab引用的資源, 會被放入小程式res/raw-assets/對應目錄下。

5. ccc resources下的prefab(實際是個json檔案。可用文字編輯器開啟看)會被 將其內容以json檔案的形式放入res/import目錄下。

6. ccc 不在resources下,但直接被“參與構建的Scene”引用的prefab會被 將其內容以json檔案的形式放入res/import目錄下。

7. ccc 不在resources下,但被上面第6條中prefab引用的資源,會被放入小程式res/raw-assets/對應目錄下。

資源、Prefab及場景的.meta檔案的內容,會被以json的形式代替儲存。
該json檔案的命名規則是:原.meta檔案中subMetas欄位下的資源的uuid。
該json檔案被放入小程式的 res/import目錄下。(按檔名的前兩位,分資料夾儲存)。

其實和Unity釋出到各原生平臺是一樣的。遊戲中的資源出現在遊戲中,只可能通過兩種方式:
1.被參與構建的場景中直接或間接引用,當場景載入時出現。
2.被resources檔案下的檔案直接或間接引用, 當引用資源的檔案被 resources.load() 到場景中時候出現。

注意:所有被從ccc放入微信小遊戲res的資原始檔,都可以在小程式 src/setting.js 中看到。


ccc->小遊戲的資源管理方式:

小程式res資料夾大於4M時預覽,會提示Error:程式碼包大小為xxxxkb,上限為4096kb,請刪除檔案後重試。

其中ccc釋出自動生成的 cocos2d-js 就有2.96M。 這個檔案可以在ccc/專案/專案設定/模組設定中刪減用不到的模組後減小。
官方文件-釋出到微信小遊戲平臺
http://docs.cocos.com/creator/manual/zh/publish/publish-wechatgame.html

按照文件,
1.構建時,勾選 md5Cache 功能。
2.將小遊戲釋出包中的 res 資料夾完整得上傳到伺服器。
3.刪除釋出包內的 res 資料夾。
4.在 game.js 中,找到對應程式碼段並新增 REMOTE_SERVER_ROOT 的設定。這裡也可在ccc的構建釋出為WechatGame時,填“遠端伺服器地址”處。

require('libs/wx-downloader.js');
wxDownloader.REMOTE_SERVER_ROOT = 'http://www.nratel.com/myfiles/';

按此方法, 包內將不包含任何res檔案,只剩程式碼檔案。
實際在手機中執行:
第一次開啟:Main場景出來前有一點時間。
之後開啟:很流暢,沒有下載載入感覺。


有個疑問?按照此方式,是在遊戲開啟時一次性下載完了所有遠端res,還是用到的本地沒有才下載?

ccc 在小遊戲中下載並儲存遠端資源的邏輯寫在 libs/wx-downloader.js 中。

簡單測試1:
一個空場景, 只引用一張圖片,
在wx-downloader.js的 nextPipe、readText、readFromLocal、ensureDirFor、downloadRemoteFile方法中各加一句log。來驗證資源載入的過程。

本地不存在時, 從遠端載入:

本地存在時, 直接從本地讀取:

可以看出, 每次載入場景和圖片時都是先呼叫readFromLocal()在本地讀取, 如果成功就直接使用,如果失敗就呼叫downloadRemoteFile()從遠端下載。

簡單測試2:
在wx-downloader.js的 downloadRemoteFile 方法中第二行加個log,來驗證資源載入時機:

cc.log("downloadRemoteFile, relatUrl: " + relatUrl);

主場景如下,點選三個按鈕時,載入各自對應的引用幾個圖示資源的介面。
主場景開啟時:
從遠端伺服器下載了MainScene對應的json檔案。以及MainScene引用的圖片資源。

 

依次點選三個按鈕:
依次在按鈕點選時,從遠端伺服器下載了各自介面Prefab對應的json檔案。以及Prefab引用的圖片資源。

 

也就是說,資源是按需載入的。

  1. 在ccc中切換場景時,通過Https下載資源到記憶體後加載使用,最後儲存到本地。
  2. 呼叫cc.loader.loadRes 載入prefab時,通過Https下載資源到記憶體後加載使用,最後儲存到本地。

這也解釋了ccc 為什麼只提供非同步的cc.loader.loadRes (和Unity不同)
正是因為在h5或小遊戲環境中, cc.loader.loadRes是按需的,包含了 下載 和 載入 的過程。。下載是非同步的。所以cc.loader.loadRes只能是非同步的。

按照ccc的資源管理的思路。考慮:

  1. 將所有釋出到微信res目錄的檔案全部放在遠端伺服器。
  2. Main場景引用的資源應儘可能的少(保證開啟遊戲到介面展示出來的速度),最好只包含一個Loading介面。
  3. 在Loading介面中使用 cc.loader.loadRes 或 cc.loader.loadResDir 將遊戲的json配置檔案以及需要即時使用的資原始檔 預下載。
  4. 在某些地方使用 “延遲載入依賴的資源”:
    場景和Prefab可勾選的選項。勾選後,被依賴的資源會在場景和Prefab使用後加載。 詳見 官方文件-延遲載入依賴的資源 最底下。

資源版本如何管理?
首先,微信不允許程式碼熱更新,每次程式碼改變都需要重新提審。這裡主要說資源的更新和管理。
按照上邊的思路進行實現,最後,資源都放在遠端伺服器上,正因為如此,資源可以在不重新提審遊戲包的情況下進行有限的更新操作(只能同名替換, 所有資源名都註冊在src/setting.js中)。 需要注意,這樣的“熱更新”是有缺陷的:因為快取機制,只有新使用者才有用,老使用者並不會下載與本地快取同名的新資源。

接下來,很重要的一點是,如何保證 開發、提審和線上 的資源互不影響, 並且能夠支援上邊的熱更(資源替換)?
方案: 在每次提審時打專案分支。資源路徑拼上分支版本。 如圖。

這樣, 最終 內網開發版(體驗版),外網提審版(體驗版),外網線上版(正式版)可以有三個獨立的入口,資源也互不影響。

最後,根據 小遊戲更新機制 加上這段程式碼,讓遊戲啟動時先進行檢查更新。

--------------------------------------------------NRatel割--------------------------------------------------

NRatel
轉載請說明出處,謝謝