AssetBundle使用模式

AssetBundle使用模式

版本檢查:2017.3-難度:高級

這是關於資產,資源和資源管理系列文章的第五章。

本系列的前一章介紹了AssetBundles基礎知識,其中包括各種加載API的低級行爲。本章討論在實踐中使用AssetBundles的各個方面的問題和可能的解決方案。

管理加載的資產

在內存敏感的環境中仔細控制加載的對象的大小和數量非常重要。從活動場景中移除時,Unity不會自動卸載對象。資產卸載在特定時間觸發,也可以手動觸發。

AssetBundles本身必須小心管理。由本地存儲上的文件(在Unity高速緩存中或通過AssetBundle.LoadFromFile加載的文件)支持的AssetBundle具有最小的內存開銷,很少消耗超過幾十千字節。但是,如果存在大量的AssetBundles,則此開銷仍可能會出現問題。

由於大多數項目允許用戶重新體驗內容(例如重玩同一個關卡),因此知道何時加載或卸載AssetBundle非常重要。如果AssetBundle卸載不當,它可能導致內存中的對象重複。 在某些情況下不當卸載AssetBundles也會導致不良行爲,例如導致紋理丟失。要理解爲什麼會發生這種情況,請參閱資產,對象和序列化章節的對象間引用關係部分。

管理資產和AssetBundles時要了解的最重要的一點是,在爲UnloadAllLoadedObjects參數調用AssetBundle.Unload的 true或false時的行爲差異。

該API將卸載正在調用的AssetBundle的頭信息。所述unloadAllLoadedObjects參數確定是否還從卸載這個AssetBundle實例化的所有對象。如果設置爲true,則源自AssetBundle的所有對象也將立即被卸載 - 即使它們當前正在活動場景中使用。

描述

如果調用了AssetBundle.Unload(true),那麼M將從場景中移除,銷燬並卸載。但是,如果調用AssetBundle.Unload(false),則AB的標題信息將被卸載,但M仍將保留在場景中並且仍然有效。調用AssetBundle.Unload(false)會中斷M和AB之間的鏈接。,果稍後再次加載AB,則AB中包含的對象的新副本將被加載到內存中。
描述

如果稍後再次加載
AB,將重新加載AssetBundle標題信息的新副本。但是,M並未從AB的這個新副本中加載Unity不會在AB和M的新副本之間建立任何關聯。

描述

果調用AssetBundle.LoadAsset()來重載M, Unity不會將M的舊副本解釋爲AB中數據的實例,因此Unity將加載M的新副本,在場景中會有兩個相同的M副本。

描述

對於大多數項目來說,這種行爲是不可取的。大多數項目應該使用AssetBundle.Unload(true),用一種方法來確保對象不重複。兩種常用方法是:

  1. 在應用程序的整個生命週期(例如在級別之間或在加載屏幕期間)卸載臨時AssetBundles時具有明確定義的點。這是更簡單和最常見的選擇。

  2. 僅當各個對象的所有構成對象都未使用時,才維護各個對象的引用計數並卸載AssetBundles。這允許應用程序卸載並重新加載單個對象而不復制內存。

如果應用程序必須使用AssetBundle.Unload(false),那麼單個對象只能通過兩種方式卸載:

  1. 在場景和代碼中消除對不需要的對象的所有引用。完成後,調用sources.UnloadUnusedAssets

  2. 非加性地加載場景。這將銷燬當前場景中的所有對象並自動調用Resources.UnloadUnusedAssets

如果一個項目有明確定義的點,可以使用戶等待對象加載和卸載(例如在遊戲模式或級別之間),則應使用這些點來卸載儘可能多的對象並加載新的對象。

最簡單的方法是將項目的離散塊打包到場景中,然後將這些場景及其所有依賴項構建到AssetBundles中。然後,應用程序可以進入“加載”場景,完全卸載包含舊場景的AssetBundle,然後加載包含新場景的AssetBundle。

雖然這是最簡單的流程,但有些項目需要更復雜的AssetBundle管理。由於每個項目都不同,因此沒有通用的AssetBundle設計模式。

在決定如何將對象分組爲AssetBundles時,如果必須同時加載或更新對象,通常最好先將對象捆綁到AssetBundles中。例如,考慮角色扮演遊戲。個別地圖和過場動畫可按場景分組爲AssetBundles,但在大多數場景中都需要一些對象。可以構建AssetBundles來提供肖像,遊戲中的用戶界面以及不同的角色模型和紋理。後面的對象和資產可以被分組到第二組資產包中,這些資產包在啓動時加載並在應用的整個生命週期內保持加載狀態。如果Unity必須在AssetBundle卸載後從它的AssetBundle重新加載對象,則可能會出現另一個問題。在這種情況下,重新加載將失敗,對象將作爲(缺失)對象出現在Unity編輯器的層次結構中。

這主要發生在Unity丟失並恢復對其圖形上下文的控制時,例如,當移動應用程序被暫停或用戶鎖定其PC時。在這種情況下,Unity必須將紋理和着色器重新上傳到GPU。如果這些資產的源AssetBundle不可用,則應用程序將以洋紅色呈現場景中的對象。

4.2.分配

將項目的AssetBundles分發給客戶端有兩種基本方式:與項目同時安裝或在安裝後下載。

是否在安裝之後或之後發佈AssetBundles的決定是由項目運行平臺的功能和限制決定的。移動項目通常選擇安裝後下載,以減少初始安裝大小並保持在無線下載大小限制以下。控制檯和PC項目通常會在AssetBundles初始安裝時運送。

正確的體系結構允許在安裝後將新內容或修訂的內容修補到補丁中,而不管最初如何交付AssetBundles。有關這方面的更多信息,請參閱Unity手冊的“ 使用AssetBundles進行修補”部分。

4.2.1.隨項目一起打包

將AssetBundles與項目一起發送是最簡單的發佈方式,因爲它不需要額外的下載管理代碼。爲什麼一個項目可能會在安裝時包含AssetBundles有兩個主要原因:

  • 減少項目構建時間並允許更簡單的迭代開發。如果這些AssetBundles不需要與應用程序本身分開更新,那麼AssetBundles可以通過將資產包存儲在流式資產中而包含在應用程序中請參閱下面流媒體資源部分。

  • 發佈可更新內容的初始版本。通常這樣做是爲了節省最終用戶在初次安裝後的時間,或者作爲以後打補丁的基礎。流式資產對於這種情況並不理想。但是,如果編寫自定義下載和緩存系統不是一種選擇,則可以從Streaming Assets。將可更新內容的初始修訂加載到Unity緩存中

4.2.1.1.流媒體資產

在安裝時在Unity應用程序中包含任何類型的內容(包括AssetBundles)的最簡單方法是在構建項目之前將內容構建到/ Assets / StreamingAssets /文件夾中。構建時包含在StreamingAssets文件夾中的任何內容都將被複制到最終的應用程序中。

本地存儲上StreamingAssets文件夾的完整路徑可在運行時通過屬性Application.streamingAssetsPath訪問。然後可以在大多數平臺上通過AssetBundle.LoadFromFile加載AssetBundles。

Android開發人員:在Android上,StreamingAssets文件夾中的資源存儲到APK中,並且可能需要更多時間才能加載(因爲存儲在APK中的文件可能使用不同的存儲算法)。使用的算法可能會因Unity版本而異。您可以使用7-zip等存檔器打開APK以確定文件是否被壓縮。如果是這樣,您可以期望AssetBundle.LoadFromFile()執行得更慢。在這種情況下,您可以使用UnityWebRequest.GetAssetBundle檢索緩存版本作爲解決方法。通過使用UnityWebRequest,AssetBundle將在第一次運行期間解壓縮並緩存,從而使後續執行速度更快。請注意,這將需要更多的存儲空間,因爲AssetBundle將被複制到緩存中。或者,您可以導出您的Gradle項目,並在構建時向您的AssetBundles添加擴展。然後,您可以編輯build.gradle文件並將該擴展名添加到noCompress部分。完成後,您應該可以使用AssetBundle.LoadFromFile()而無需支付解壓縮性能成本。

注意:流式資產在某些平臺上不是可寫位置。如果安裝後需要更新項目的AssetBundles,則可以使用WWW.LoadFromCacheOrDownload或編寫自定義下載程序。

4.2.2.下載後安裝

將AssetBundles交付給移動設備的最佳方法是在應用程序安裝後下載它們。這也允許在安裝後更新內容而不強制用戶重新下載整個應用程序。在許多平臺上,應用程序二進制文件必須經過昂貴且冗長的重新認證過程。因此,開發一個良好的安裝後下載系統至關重要。

交付AssetBundles的最簡單方法是將它們放置在Web服務器上並通過UnityWebRequest交付。Unity會自動將下載的AssetBundles緩存在本地存儲上。如果下載的AssetBundle是LZMA壓縮的,則AssetBundle將以未壓縮或重新壓縮爲LZ4(取決於Caching.compressionEnabled設置)的形式存儲在緩存中,以便將來加載更快。如果下載的捆綁包壓縮了LZ4,則AssetBundle將被壓縮存儲。如果緩存填滿,Unity將從緩存中刪除最近最少使用的AssetBundle。有關更多詳細信息,請參閱內置緩存部分。

通常建議使用來啓動UnityWebRequest如果可能,或WWW.LoadFromCacheOrDownload只有使用Unity 5.2或以上。如果內置API的內存消耗,緩存行爲或性能對於特定項目不可接受,或者項目必須運行特定於平臺的代碼以實現其要求,則只投資於定製下載系統。

可能阻止使用UnityWebRequest或WWW.LoadFromCacheOrDownload的情況示例:

  • 當需要對AssetBundle緩存進行細粒度控制時

  • 當項目需要實施自定義壓縮策略時

  • 當項目希望使用平臺特定的API來滿足某些要求時,例如需要在非活動狀態下傳輸數據。

    • 示例:使用iOS的後臺任務API在後臺下載數據。
  • 如果AssetBundles必須在Unity沒有適當的SSL支持的平臺(如PC)上通過SSL提供。

4.2.3.內置緩存

Unity有一個內置的AssetBundle緩存系統,可用於緩存通過UnityWebRequest API 下載的AssetBundles,該API包含一個接受AssetBundle版本號作爲參數的重載。此編號不存儲在AssetBundle內部,並且不由AssetBundle系統生成。

緩存系統跟蹤傳遞給UnityWebRequest的最新版本號。當使用版本號調用此API時,高速緩存系統通過比較版本號來檢查是否存在緩存的AssetBundle。如果這些數字匹配,系統將加載緩存的AssetBundle。如果數字不匹配,或沒有緩存的AssetBundle,Unity將下載一個新副本。這個新副本將與新版本號相關聯。

緩存系統中的AssetBundles僅由其文件名來標識,而不是由其下載的完整URL標識。這意味着具有相同文件名的AssetBundle可以存儲在多個不同的位置,例如內容傳送網絡。只要文件名稱相同,緩存系統就會將它們識別爲相同的AssetBundle。
每個應用程序都要決定將版本號分配給AssetBundles的適當策略,並將這些數字傳遞給UnityWebRequest。這些數字可能來自各種唯一標識符,例如CRC值。請注意,儘管AssetBundleManifest.GetAssetBundleHash()也可用於此目的,但我們不建議使用此功能進行版本控制,因爲它僅提供估算值,而不是真正的散列值計算)。

有關更多詳細信息,請參閱Unity手冊的使用AssetBundles進行修補部分。

在Unity 2017.1以後,緩存API已經擴展到提供更精細的控制,允許開發人員從多個緩存中選擇一個活動緩存。以前的Unity版本只能修改Caching.expirationDelayCaching.maximumAvailableDiskSpace以刪除緩存的項目(這些屬性保留在Cache類中的Unity 2017.1中)。expirationDelay是自動刪除AssetBundle之前必須經過的最小秒數。如果在此期間沒有訪問AssetBundle,它將被自動刪除。

maximumAvailableDiskSpace>指定本地存儲空間量(以字節爲單位),緩存在開始刪除最近使用過的最近比expirationDelay使用的AssetBundles之前可能會使用的空間量達到限制時,Unity將刪除最近最少打開的緩存中的AssetBundle(或通過Caching.MarkAsUsed標記爲已使用)。Unity會刪除緩存的AssetBundles,直到有足夠的空間完成新的下載。

4.2.3.1.緩存啓動

由於AssetBundles是通過其文件名來標識的,因此可以使用應用程序隨附的AssetBundles來“啓動”緩存。爲此,請將每個AssetBundle的初始版本或基本版本存儲在/ Assets / StreamingAssets /中。該過程與“項目發貨”部分中詳細介紹的過程相同。

第一次運行應用程序時,可以通過從Application.streamingAssetsPath加載AssetBundles來填充緩存。從此,應用程序可以正常調用UnityWebRequest(UnityWebRequest也可用於最初從StreamingAssets路徑加載AssetBundles)。

4.2.3.自定義下載程序

編寫自定義下載程序可讓應用程序完全控制AssetBundles的下載,解壓縮和存儲方式。由於所涉及的工程工作並不平凡,我們只爲大型團隊推薦這種方法。編寫自定義下載器時有四個主要考慮事項:
* 下載機制
* 存儲位置
* 壓縮類型
* 修補

有關修補AssetBundles的信息,請參閱使用AssetBundles修補部分。

4.2.3.1.下載

對於大多數應用程序,HTTP是下載AssetBundles最簡單的方法。但是,實現基於HTTP的下載程序不是最簡單的任務。自定義下載程序必須避免過多的內存分配,過多的線程使用和過多的線程喚醒。Unity的WWW類不適合這裏詳盡描述的原因。

在編寫自定義下載器時,有三個選項:

  • C#的HttpWebRequest和WebClient類
  • 自定義本機插件
  • 資產商店包
4.2.3.1.1. C#類

如果應用程序不需要HTTPS / SSL支持,則C#的WebClient類提供了下載AssetBundles最簡單的機制。它能夠將任何文件直接異步下載到本地存儲,而無需過多管理內存分配。

要使用WebClient下載AssetBundle,請分配該類的一個實例,並將其傳遞給AssetBundle的URL以下載和目標路徑。如果需要對請求參數進行更多控制,可以使用C#的HttpWebRequest>類編寫下載程序:

  1. 從HttpWebResponse.GetResponseStream獲取一個字節流。

  2. 在堆棧上分配一個固定大小的字節緩衝區。

  3. 從響應流中讀入緩衝區。

  4. 使用C#的File.IO API或任何其他流式IO系統將緩衝區寫入磁盤。

4.2.3.1.2.資產商店包

多個資產商店軟件包提供本地代碼實現,以通過HTTP,HTTPS和其他協議下載文件。在爲Unity編寫自定義本機代碼插件之前,建議您先評估可用的Asset Store軟件包。

4.2.3.1.3.自定義原生插件
編寫自定義本機插件是在Unity中下載數據最耗時,但最靈活的方法。由於編程時間要求高且技術風險高,只有在沒有其他方法能夠滿足應用程序要求的情況下才推薦此方法。例如,如果應用程序必須在Unity中沒有C#SSL支持的平臺上使用SSL通信,則可能需要定製本機插件。

自定義本機插件通常會包裝目標平臺的本機下載API。示例包括iOS上的NSURLConnection和Android上的java.net.HttpURLConnection。請參閱每個平臺的本機文檔以獲取有關使用這些API的更多詳細信息。

4.2.3.2.存儲

在所有平臺上,Application.persistentDataPath指向一個可寫的位置,應該用於存儲應該在應用程序運行之間保持的數據。在編寫自定義下載器時,強烈建議使用Application.persistentDataPath的子目錄來存儲下載的數據。

Application.streamingAssetPath不可寫,對於AssetBundle緩存來說是一個糟糕的選擇。streamingAssetsPath的示例位置包括:

  • OSX在.app包內;不可寫。
  • Windows:在安裝目錄中(例如Program Files; 通常不可寫
  • iOS:在.ipa包內; 不可寫
  • Android:在.apk文件中; 不可寫

4.3.資產分配策略

決定如何將項目資產劃分爲AssetBundles並不簡單。很容易採用簡單的策略,比如將所有對象放置在自己的AssetBundle中或僅使用一個AssetBundle,但這些解決方案具有明顯的缺點:

  • 擁有太少的AssetBundles …

    • 增加運行時內存使用量
    • 增加加載時間
    • 需要更大的下載量
  • 擁有太多的AssetBundles …

    • 增加構建時間
    • 可能會使開發複雜化
    • 增加總下載時間

關鍵的決定是如何將對象分組爲AssetBundles主要戰略是:

  • 邏輯實體
  • 對象類型
  • 併發內容

有關這些分組策略的更多信息可以在手冊中找到。

4.4.常見的陷阱

本節介紹使用AssetBundles項目中常見的幾個問題。

4.5.1.資產重複

Unity 5的AssetBundle系統將在對象構建到AssetBundle中時發現對象的所有依賴關係。此依賴關係信息用於確定將包含在AssetBundle中的一組對象。

明確分配給AssetBundle的對象只會構建到該AssetBundle中。當Object的AssetImporter的assetBundleName屬性設置爲非空字符串時,對象將被“顯式分配” 。這可以在Unity Editor中通過在對象的檢查器中選擇一個AssetBundle或從編輯器腳本中完成。

也可以將對象分配給AssetBundle,方法是將它們定義爲AssetBundle構建映射的一部分,該映射要與重載的BuildPipeline.BuildAssetBundles()函數一起使用,該函數接受一組AssetBundleBuild。

在AssetBundle中未明確分配的任何對象都將包含在所有包含引用未標記對象的1個或多個對象的AssetBundle中。

例如,如果將兩個不同的對象分配給兩個不同的AssetBundles,但都具有對公共依賴項Object的引用,則該依賴Object將被複制到兩個AssetBundles中。重複的依賴關係也將被實例化,這意味着依賴關係對象的兩個副本將被視爲具有不同標識符的不同對象。這將增加應用程序AssetBundles的總大小。如果應用程序加載它的父項,這也會導致Object的兩個不同副本被加載到內存中。

有幾種方法可以解決這個問題:

1.確保構建到不同AssetBundles中的對象不共享依賴關係。任何共享依賴關係的對象都可以放置在同一個AssetBundle中,而不需要重複依賴關係。
* 對於具有許多共享依賴項目的項目,此方法通常不可行。它生產的單片AssetBundles必須經常重建和重新下載,以避免方便或高效。
2.分段AssetBundles,以便不會同時加載共享依賴關係的兩個AssetBundles。
* 此方法可能適用於某些類型的項目,例如基於級別的遊戲。但是,它仍然會不必要地增加項目的AssetBundles的大小,並增加構建時間和加載時間。
3. 確保所有依賴項資產都內置到自己的AssetBundles中。這完全消除了重複資產的風險,但也帶來了複雜性。應用程序必須跟蹤AssetBundles之間的依賴關係,並確保在調用任何AssetBundle.LoadAsset API 之前加載了正確的AssetBundles 。

通過位於UnityEditor名稱空間中的AssetDatabase API跟蹤對象依賴關係。正如命名空間所暗示的,這個API僅在Unity編輯器中可用,而不是在運行時。AssetDatabase.GetDependencies可用於查找特定對象或資產的所有直接依賴關係。請注意,這些依賴關係可能有其自己的依賴關係。此外,AssetImporter API可用於查詢分配有任何特定對象的AssetBundle。

通過組合AssetDatabase和AssetImporter API,可以編寫一個編輯器腳本,以確保將所有AssetBundle的直接或間接依賴關係分配給AssetBundles,或者沒有兩個AssetBundle共享尚未分配給AssetBundle的依賴關係。由於複製資產的內存成本,建議所有項目都有這樣的腳本。

4.5.2.雪碧的圖集重複

任何自動生成的精靈圖集將被分配給包含從其生成精靈圖集的精靈對象的AssetBundle。如果精靈對象被分配給多個AssetBundles,那麼精靈圖集將不會被分配給一個AssetBundle並且將被複制。如果Sprite對象未分配給AssetBundle,則精靈地圖集也不會被分配給AssetBundle。

爲了確保精靈圖集沒有重複,請檢查標記在同一精靈圖集中的所有精靈分配到同一個AssetBundle。
請注意,在Unity 5.2.2p3及更早版本中,自動生成的精靈地圖將永遠不會分配給AssetBundle。因此,它們將被包含在包含其組成精靈的任何AssetBundles中,以及任何引用其組成精靈的AssetBundles中。由於這個問題,強烈建議所有使用Unity的sprite打包程序的Unity 5項目都升級到Unity 5.2.2p4,5.3或任何更新版本的Unity。

4.5.3.Android紋理

由於Android生態系統中的設備碎片較多,通常需要將紋理壓縮爲多種不同的格式。雖然所有Android設備都支持ETC1,但ETC1不支持帶alpha通道的紋理。如果應用程序不需要OpenGL ES 2支持,則解決該問題的最簡單方法是使用所有Android OpenGL ES 3設備支持的ETC2。

大多數應用程序需要在ETC2支持不可用的舊設備上發貨。解決此問題的一種方法是使用Unity 5的AssetBundle變體(有關其他選項的詳細信息,請參閱Unity的Android優化指南)。

要使用AssetBundle變體,所有無法使用ETC1進行乾淨壓縮的紋理必須分離爲僅紋理的AssetBundles。接下來,使用特定於供應商的紋理壓縮格式(如DXT5,PVRTC和ATITC)創建足夠的這些AssetBundles變體以支持Android生態系統的非ETC2功能片。對於每個AssetBundle Variant,將包含的紋理的TextureImporter設置更改爲適合Variant的壓縮格式。

在運行時,可以使用SystemInfo.SupportsTextureFormat API檢測對不同紋理壓縮格式的支持。應該使用此信息來選擇和加載包含以受支持格式壓縮的紋理的AssetBundle Variant。

有關Android紋理壓縮格式的更多信息可以在這裏找到。

4.5.4.iOS文件句柄過度使用

Unity的當前版本不受此問題影響。

在Unity 5.3.2p2之前的版本中,Unity會在AssetBundle加載的整個過程中持有一個打開的文件句柄。這在大多數平臺上都不是問題。但是,iOS將進程可能同時打開的文件句柄數限制爲255.如果加載AssetBundle會導致超出此限制,則加載調用將失敗,並顯示“Too Many Open File Handles”錯誤。

對於嘗試將內容分成數百或數千個AssetBundles的項目,這是一個常見問題。

對於無法升級到補丁版本的Unity的項目,臨時解決方案是:

  • 通過合併相關的AssetBundles來減少使用的AssetBundles的數量

  • 使用AssetBundle.Unload(false),關閉AssetBundle的文件句柄,並手動管理加載的對象的生命週期

4.5。AssetBundle變體

AssetBundle系統的一個關鍵特性是引入了AssetBundle變體。變體的目的是允許應用程序調整其內容以更好地適應其運行時環境。當加載對象和解析實例ID引用時,變體允許不同的AssetBundle文件中的不同UnityEngine.Objects顯示爲“相同”對象。從概念上講,它允許兩個UnityEngine.Objects顯示爲共享相同的文件GUID和本地ID,並標識實際的UnityEngine.Object以通過字符串變體ID加載。

這個系統有兩個主要用例:

1.變體簡化了適用於給定平臺的AssetBundles的加載。
* ##### 示例:構建系統可能會創建一個AssetBundle,其中包含適用於獨立DirectX11 Windows版本的高分辨率紋理和複雜着色器,以及適用於Android的具有較低保真度內容的第二個AssetBundle。在運行時,項目的資源加載代碼可以爲其平臺加載相應的AssetBundle Variant,並且傳遞到AssetBundle.Load API的對象名稱不需要更改。
2.變體允許應用程序在同一平臺上加載不同的內容,但使用不同的硬件。
* 這是支持各種移動設備的關鍵。在任何真實世界的應用程序中,iPhone 4都不能像最新的iPhone一樣顯示相同的內容保真度。
* 在Android上,AssetBundle Variants可用於解決設備間屏幕縱橫比和DPI之間巨大的分割問題。

4.5.1.限制

AssetBundle Variant系統的一個關鍵限制是它需要使用不同的資產來構建變體>即使這些資產之間的唯一差異是其導入設置,也適用此限制。如果內置到變體A和變體B中的紋理之間的唯一區別是在Unity紋理導入器中選擇的特定紋理壓縮算法,則變體A和變體B必須仍然是完全不同的資產。這意味着變體A和變體B必須是磁盤上的單獨文件。

這種限制使大型項目的管理複雜化,因爲特定資產的多個副本必須保存在源代碼管理中。當開發人員希望更改資產的內容時,必須更新資產的所有副本。這個問題沒有內置的解決方法。

大多數團隊都實施他們自己的AssetBundle變體形式。這是通過建立AssetBundles來完成的,後者在文件名後面添加了明確的後綴,以便識別給定AssetBundle所代表的特定變體。在構建這些AssetBundles時,自定義代碼以編程方式更改包含的資產的導入器設置。一些開發者已經擴展了他們的定製系統,以便能夠改變附屬於預製件的組件上的參數。

4.6.壓縮還是未壓縮?

是否壓縮AssetBundles需要一些重要的考慮因素,其中包括:

  • 加載時間:從本地存儲或本地緩存加載時,未壓縮的AssetBundles比加載壓縮的AssetBundles要快得多。

  • 構建時間:在壓縮文件時,LZMA和LZ4非常緩慢,Unity Editor按順序處理AssetBundles。具有大量AssetBundles的項目將花費大量的時間壓縮它們。

  • 應用程序大小:如果AssetBundles在應用程序中發貨,則壓縮它們將減少應用程序的總大小。或者,可以在安裝後下載AssetBundles。

  • 內存使用情況:在Unity 5.3之前,所有Unity的解壓縮機制都要求在解壓縮之前將整個壓縮的AssetBundle加載到內存中。如果內存使用率很重要,請使用未壓縮或LZ4壓縮的AssetBundles。

  • 下載時間:如果AssetBundles很大,或者用戶處於帶寬受限的環境中,例如在低速或計量連接上下載,則壓縮可能只需要。如果只有幾兆字節的數據通過高速連接傳送到PC,則可能會忽略壓縮。

4.6.1.緊縮壓縮

主要由使用Crunch壓縮算法的DXT壓縮紋理組成的束應該被構建爲未壓縮的。

4.7.AssetBundles和WebGL

Unity強烈建議開發人員不要在WebGL項目上使用壓縮的AssetBundles。

WebGL項目中的所有AssetBundle解壓縮和加載必須在主線程上進行。這是因爲Unity的WebGL導出選項當前不支持工作線程。AssetBundles的下載使用XMLHttpRequest委託給瀏覽器,XMLHttpRequest在Unity的主線程上執行。這意味着壓縮的AssetBundles在WebGL上加載非常昂貴。

如果您使用的是Unity 5.5或更高版本,請考慮避免使用LZMA作爲您的AssetBundles,並使用LZ4進行壓縮,而不是按需解壓縮。如果您需要較小的壓縮大小,那麼LZ4會提供,您可以配置您的Web服務器以在HTTP協議層面(在LZ4壓縮之上)對文件進行gzip壓縮。Unity 5.6將LZMA作爲WebGL平臺的壓縮選項進行刪除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章