天天看點

AssetBundle and the AssetBundle Manager介紹

AssetBundle and the AssetBundle Manager 介紹 AssetBundle允許從本地或者遠端伺服器加載Assets資源,利用AssetBundles技術,Assets資源可以放在遠端伺服器上,這種技術增加了項目靈活性并且減少項目初始包的大小。 本文介紹AssetBundles并且讨論一步一步的介紹怎麼樣使用它,怎樣将資源打包到AssetBundle中,如何使用以及如何處理資源的引用計數,所有這些我們都可以使用AssetBundle Manader來簡化AssetBundle建構、測試和釋出環節。最後會介紹一個使用AB和Variants實際項目的例子。 示例 在讀本文開始之前,最好先從官方下載下傳下載下傳示例 什麼是AssetBundle AssetBundles是Unity編輯器中在編輯過程中建立的一些檔案,這些檔案可以在項目運作環境中使用。AssetBundles可以包含的資源檔案比如模型,材質,貼圖和場景等等,注意:AssetBundles不能包含腳本! 具體來說,一個AssetBundle就是把資源或者場景以某種方式緊密集合在一起的一個檔案。這個AssetBundle檔案可以被單獨加載到unity應用程式中。這允許模型、貼圖、音效設定很大的場景這些資源進行流式加載或者異步加載。當然AssetBundle檔案也可以本地緩存這樣能夠在程式啟動的時候立馬被加載出來。但AssetBundle技術主要目的就是需要的時候從遠端伺服器下載下傳需要的資源。AssetBundle可以包含任何unity可識别的資源檔案,甚至包括二進制檔案。但就是不能包含腳本檔案。 有很多AssetBundle的使用案例。資源在程式中可以被加載和釋放。Post-release DLC可以被輕易的實作。應用程式釋出的時候可以使得包體變得更小,在應用程式啟動的時候加載需要加載的資源。應用程式國際化也會變得相對簡單,我們可以根據玩家的地理位置來判斷加載對應的資源檔案。應用程式可以用新的資源檔案來達到修複、更新的目的。 AssetBundles怎麼管理和規劃更取決于具體的項目需求。以下有一些基本的規則以便我們更好的了解AssetBundle。

* AssetBundle需要整體的下載下傳和緩存的

* AssetBundle不需要整體的加載到應用程式中

* Assets在AssetBundles中是具有互相依賴性的

* Assets在AssetBundle中可以和其他資源共享依賴

* 每一個AssetBundle都有一些技術開銷,在檔案加載上和對檔案的管理上

* AssetBundle必須針對平台進行打包 每一個AssetBundle都是被整體下載下傳的,就算它不會立馬被用到甚至不會在目前場景中用到,它也會占用下載下傳和磁盤空間資源。 一個AB檔案被整體下載下傳之後,我們可以根據需要去加載裡面的資源。 一個資源可能會對其他資源有依賴關系,比如一個模型可以有很多依賴關系,一個遊戲中的模型不僅僅隻有網格資料,實際上他是一個擁有很多依賴資源組成的一個共同體。

AssetBundle and the AssetBundle Manager介紹

一個網格模型及其所使用的材質 這個坦克模型的Mesh Render依賴材質資源,材質又依賴貼圖資源。是以這個坦克模型依賴三個檔案資源并不是僅僅就一個網格資源

AssetBundle and the AssetBundle Manager介紹

這個坦克模型的資源依賴鍊:模型 > 材質 >紋理 Assets資源之間也是可以互相依賴的,例如:兩個不同的模型可以共享相同的材質,這個材質是依賴貼圖資源。

AssetBundle and the AssetBundle Manager介紹

不同的岩石模型共享相同的材質 在組織AssetBundle結構的時候,需要去平衡開銷,把AssetBundle分成若幹個很小的AssetBundle的時候會很耗性能,但如果做成一個大的AssetBundle又會包含許多不需要用到的資源,是以要根據你實際的項目來平衡。 AssestBundle的目錄被以優化的方式編譯到目标平台上根據目标平台的導出設定,因為這樣是以AssestBundles需要導出到各個目标平台。 依賴關系和依賴管理 關于依賴和依賴管理有幾個重要的點 資源依賴永遠不會丢失。如果這個依賴的assest在AssestBundle被建立時沒有指定任何的AssestBundle,依賴的Assest連同選中的Assest将被添加到AssestBundle,這是非常友善和避免依賴Assest的損失。但是這也可能導緻Assets重複。例如,使用兩個岩石上面共享相同的Material,如果岩石列在單獨的AssetBundles和Material沒有顯式地指定一個AssetBundle,将被添加到包含那種Material的兩個 AssetBundles包中。值得注意的事,當這麼做的時候,兩個重複的資源将被存儲在各自的AssetBundles而且依賴關系也破裂了,每個模型的Assest将依賴自己複制出來的Material,沒有了共享Assest的任何優勢。為了防止這種情況的發生,這些材料需要顯式地指定一個AssetBundle,這可以實作對自己和其他資源的分享。用這種方法,這兩個岩石的AssestBundle将依賴這個岩石Material。 關于依賴資訊都存儲在Mamnifest檔案中,這個檔案很像AssetBundle的資源的table檔案。當AB建構時,unity統一生成大量資料,這些資料儲存清單的細節,每一個目标平台都有一個對應的清單,清單列出所有為目前平台所需要的AssetBundles存儲,跟蹤和依賴項。使用清單可以查詢所有AssetBundle和他們的依賴項。 有一個關于AssetBundles的特别的設定被叫做 AssetBundle Variants,AssetBundle Variants目的在于一種特殊的情況:在項目中重新映射一個不同Assest中的單個對象,這對于一個需要基于标準分辨率、語言、定位、或使用者偏好選擇不同的Assest特别有用。 AssetBundle Variants可以容納所需的各種Asset的覆寫所有支援選擇對象和所需的Asset可以根據需要被映射到該對象的選擇的AssetBundle Variants。 AssetBundles檔案包含資産檔案,如模型、材料、材質和場景。AssetBundles在輯器編輯建立在遊戲中使用,AssetBundles旨在從本地或遠端加載資源。AssetBundles可以變異映射到對象根據現場使用者的偏好。 Working with AssetBundles and the AssetBundle Manager 介紹 對于使用AssetBundles的一個關鍵和重要的工作是對Asset建構測試,通常,AssetBundles會定期的發生改變,是以需要定期的建立AssetBundles,然後将其上傳到一個遠端伺服器并測試托管的AssetBundles資源。 本章重點介紹使用AssetBundles Manader。AssetBundle Manager提供了一個進階的API大大提高了工作流。 使用AssetBundles 使用AssetBundles有以下幾步:

* 在編輯器裡面建構AssetBundles

* 上傳AssetBundles到外部存儲

* 在運作時下載下傳AssetBundles

* 從AssetBundles中加載物體

值得注意的是一些AssetBundles可以存儲在本地,以保證立即加載,這有助于防止一個應用程式的安裝不能從遠端下載下傳所有的AB資源。例如,當應用程式沒有通路下載下傳内容時将從本地AssetBundles加載預設語言和本地資料。 值得注意的是,一個AssetBundles會根據平台進行打包,AssetBundles根據導入的設定和目标平台中的設定建構為目标平台的AB資源。 在下面的場景中,一種方式就是打包包括地面,沙丘,岩石,仙人掌,樹。這些場景允許包括所有獨立的材質。坦克模型會有自己的AssetBundles,這樣允許改變或者更新玩家資訊。想要完成這個坦克的GameObject建立,需要額外依賴兩個AssetBundle一個是材質球,一個是紋理,這麼做對于更新這個材質球和紋理來說,将會造成最小的麻煩,也允許選擇版本或者多個版本,從多個版本中選擇一個需要的AssetBundle來實作平台,國際化或者目标裝置的區分。

AssetBundle and the AssetBundle Manager介紹

一個簡單的場景 在Editor模式下組織和建構AssetBundles,資源必須配置設定給一個AssetBundle,當檢視一個資源,在Inspector面闆中右下角可以看到這個AssetBundle的名字和Variant。預覽視窗打開才能看到。

AssetBundle and the AssetBundle Manager介紹

還沒有配置設定的坦克資源 使用AssetBundle名稱下拉菜單進行配置設定資源,在這裡要不選擇一個現有的要不建立一個新的。

AssetBundle and the AssetBundle Manager介紹

配置設定一個資源到AssetBundle 建立一個新的AssetBundle,選擇New并且文本輸入框就會有效讓你輸入名字

如果要移除一個資源,隻要選擇None就可以

如果想從清單中删除一個AssestBundle名字,那必須要把所有的配置設定給這個AssestBundle的資源的名字都從AssestBundle中删除掉。然後可以選擇Remove Unused Names,将删除所有沒被使用的AssestBundle的名字。

AssetBundle and the AssetBundle Manager介紹

AssetBundles名字必須小寫,如果不遵循的話,unity會自動處理成小寫。

AssetBundle and the AssetBundle Manager介紹

這樣AssetBundles名字就被強制改成了小寫。 使用AssetBundles Variants 允許以各種不同的解決方案解決加載問題,包括下載下傳、存儲和更新,一種特定的情況就是AssetBundle 可以依據裝置來加載不同的使用者偏好等,這是利用AssetBundle Variants。對場景中的一個物體上同一個資源AssetBundle Variants提供不同的Variants,AssetBundle Variants可以實作替換不同的資源到同一個物體上,隻有一種Variants可以在任何時間進行加載。 AssetBundle Variants在很多情況上多可以使用,AssetBundle Variants可以為不同分辨率的機器或者高低顯示卡配置不同的機器或者不同面數的多邊形提供相同的資源,AssetBundle Variants可以根據文本、圖像、紋理和字型可以為每個受支援的語言不同,地區或主題建立不同的對象。這些資源儲存了一系列資訊。 以下是AssetBundle的小例子

AssetBundle and the AssetBundle Manager介紹
AssetBundle and the AssetBundle Manager介紹
AssetBundle and the AssetBundle Manager介紹

在上面例子中,兩個檔案夾MyAssets-SD和HD同時被配置設定到myassets的AssetBundle,然後得到一個是别名分别是hd和sd,注意這兩個資源具有相同的名稱和結構,在建立一個資源的時候父目錄被指定到一個AssetBundle上,沒有被指到任何一個AssetBundle上。 值得注意的是下面的圖檔的AssetBundle有一個路徑variant/myassets

AssetBundle and the AssetBundle Manager介紹

這将為名叫myassets的AssestBundle建立一個父菜單,叫variant。一旦一個資源被配置設定好了之後需要被打包和測試。 一旦資源被指定到 AssetBundle, 這個 AssetBundle 将要被編譯和測試。 使用 AssetBundle Manager Unity 提供了直接使用 AssetBundle 的底層 API. 但是這篇教程不會覆寫這些底層 API。關于底層 API 的更多資訊,請閱讀這個連結。 關于編譯,測試和管理 AssetBundle,這篇教程會專注到 AssetBundle Manager 和它的高層 API 上。 AssetBundle Manager 是一個可下載下傳的,可以安裝在目前 Unity 項目中的包,它提供高層 API 和改進了 AssetBundle 的流程。AssetBundle Manager 可以再 這裡 下載下傳。要在項目中使用 AssetBundle Manager,簡單的将它加到目前的項目的 Asset 檔案夾中。 編譯和測試 AssetBundle 可能是在開發過程中的一個痛點。資源會時常的改變。使用底層 AssetBunle API 時,測試需要規律的編譯和上傳 AssetBundle 到一個遠端伺服器上,然後從當我的項目建立一個網絡連接配接來測試遠端伺服器上的 AssetBundle。相對于直接操作 AssetBundle 的底層 API, AssetBundle Manager 大幅度的優化了流程。AssetBundle Manager 提供的最核心的功能是一個模拟模式,一個本地的 AssetBundle 伺服器和一些快捷的菜單去編譯 AssetBundle 和無間隙地和本地 AssetBundle 伺服器合作。 把 AssetBundle Manager 加入到項目之後将會在 Asset 菜單中建立一個叫 AssetBundles 的新菜單項。

AssetBundle and the AssetBundle Manager介紹

Assets > AssetBundles 選中 AssetBundles 菜單将會顯示一個小菜單選項。

AssetBundle and the AssetBundle Manager介紹

Assets > AssetBundles 菜單項 模拟模式開啟後,允許編輯器不用實際編譯就可以模拟 AssetBundle。要打開模拟模式,選擇 Simulation Mode 菜單項。對勾符号表示模拟模式已經開啟。要關閉模拟模式就再選擇一次菜單項目。然後對勾符号會被移除,模拟模式會被禁用。 當模拟模式開啟後,編輯器會檢視哪些資源被指定到了 AssetBundle,然後從項目的 hierarchy 中直接使用他們,就像他們在 AssetBundle 中一樣。但是這些 AssetBundle 不需要編譯。從這點來看,在編輯可以工作到了 AssetBundle 編譯後放到遠端伺服器上一樣可以工作。 開啟模拟模式最大的好處是,隻要資源被正确地指定到 AssetBundle ,在目前運作的項目測試前不需要停下來去編譯和重新部署 AssetBundle 就可以修改,操作,導入,删除資源。當開啟模拟模式之後,測試是馬上生效的。 注意 AssetBundle 變體在模拟模式下不支援。測試 AssetBundle 變體,AssetBundle 需要重新編譯和部署。但是,本地的資源伺服器支援 AssetBundle 變體。 AssetBundle Manager 也可以開啟一個本地資源伺服器來從編輯器或者本地或移動端的 build 來測試。當本地資源伺服器開啟後,AssetBundle 必須編譯,然後放到項目跟目錄中,跟 Assets 檔案夾同級的 AssetBundles 檔案夾裡。

AssetBundle and the AssetBundle Manager介紹

本地資源伺服器要求的 AssetBundes 檔案夾位置 AssetBundles 本地托管之後, 從目前項目中通路本地資源伺服器隻需要幾行的代碼就可以友善的通路。請閱讀 AssetBundle 示例項目中的示例,我們會在教程的下面覆寫到。 編譯和儲存到 AssetBundle 到項目根目錄的 AssetBundles 檔案夾中可以從 Assets/AssetBundles 菜單中選擇 Build AssetBundles 來完成。當 Build AssetBundles 被選擇之後, Unity 将會編譯所有有資源指定的 AssetBundle, 然後為目前的平台編譯和優化他們,最後儲存他們和一個主清單到項目根目錄下的 AssetBundles 檔案夾下。如果沒有 AssetBundles檔案夾,Unity 會建立一個。在 AssetBundles 檔案夾裡,AssetBudle 按照編譯目标平台來組織。

AssetBundle and the AssetBundle Manager介紹

“AssetBundles” 檔案夾,按照編譯目标平台來分組 AssetBundle 被編譯後部署到遠端伺服器或者開始本地資源伺服器,這些 AssetBundles 可以在運作期下載下傳和插入到項目中。 AssetBundle 練習 練習 AssetBundle, 這教程将會使用 AssetBundle Manager。AssetBundle Manager 會應付 AssetBundle 的加載和他們相關的資源依賴。利用 AssetBundle Manager 來從 AssetBundle 中加載資源,腳本需要使用 AssetBundle Manager 提供的 API。 AssetBundle Manager 的 API 包括:

  • Initialize() 初始化 AssetBundle 清單對象
  • LoadAssetAsync() 從指定的一個 AssetBundle 中加載資源并處理所有的依賴
  • LoadLevelAsync() 從指定的一個 AssetBundle 中加載場景并處理所有的依賴
  • LoadDependencies() 加載指定的 AssetBundle 的所有獨立的 AssetBundle
  • BaseDownloadingURL 設定用來自動下載下傳依賴的基本位址
  • SimulateAssetBundleInEditor 在編輯器中設定模拟模式
  • Vraiants 設定目前的變體
  • RemapVariantName() 根據目前的變體決定正确的 AssetBundle

示例檔案放置在 AssetBundle Manager 内的 AssetBundle Sample 檔案加下。有 3 個基礎的示例場景和一個進階的示例場景在 AssetBundleSample/Scenes 檔案夾下:

  • “AssetLoader” 示範了怎麼樣從 AssetBundle 加載普通資源
  • “SceneLoader” 示範了怎麼樣從 AssetBundle 加載場景
  • “VariantLoader” 示範了怎麼樣加載 AssetBundle 變體
  • “LoadTanks” 更進階,示範了複雜一點的,從同一個場景中加載場景,資源,和 AssetBundle 變體的示例。

    每個場景都各個被非常基礎的腳本驅動着:LoadAsset.cs,LoadScenes.cs,LoadVariants.cs 和 LoadTanks.cs。

目前重申一下 AssetBundle Manager 提供的流程還是很重要的。 為了能成功的試驗 AssetBundle 的使用,這裡有三種可能的情景: 第一個情景,沒有使用 AssetBundle Manager, AssetBundle 将需要被編譯和部署,所有的測試都會在最終完整準備後完成。在這個場景中,每次項目中資源的改變,都需要編譯和部署新的 AssetBundle。 AssetBundle Manager 在流程上提供了兩個改進。他們是本地資源伺服器和模拟模式。 在模拟模式中,編輯器内運作項目時,AssetBundle Manager 會模拟編譯後的 AssetBundles。這是使用 AssetBundle 的最快的流程。隻需簡單的使用 “Assets/AssetBundles/Simulation Mode” 菜單打開 “模拟模式”, 然後測試項目。沒有 AssetBundle 會被編譯。盡管如此,要注意 AssetBundle 變體在模拟模式下不工作。還有要注意的是,模拟模式開始後,資源可以再項目中操作,并且改變後的效果在 Sence 視圖中可以看到,而這使用部署後的 AssetBundle 是不行的。 本地資源伺服器提供了部署的 AssetBundle 更精确的示範,但是需要 AssetBundle 被編譯和存儲到項目中的預設檔案夾。當本地資源伺服器開啟之後,被編譯的 AssetBundle 将可以被編輯器和所有運作在本地的,可以通過本地網絡連接配接編輯器的 build 使用。注意這個是能本地測試 AssetBundle 變體的唯一方式。 要運作示例場景,AssetBundle Manager 必須運作在這些模式中的一種。要成功運作 AssetBundle 變體,AssetBundle 必須被編譯并且本地資源伺服器必須被開啟。 示例 1:加載資源 使用 “Asset/AssetBundles/Simulation Mode” 菜單打開模拟模式

打開 “AssetBundleSample/Scenes/AssetLoader” 場景

注意場景是個空的隻有一個主錄影機,方向光和遊戲對象 “Loader”

進入 PlayMode

然後會注意到一個 cube 已經從 AssetBundle 加載到場景裡面了

這個場景是被 “LoadAssts.cs” 腳本驅動的。 在腳本編輯器裡面打開腳本 “AssetBundleSample/Scripts/LoadAssets.cs” 腳本裡有兩個公共變量: public string assetBundleName; 和 public string assetName; public string assetBundleName; 儲存了要被加載的 AssetBundle 的名字

public string assetName; 儲存了要已加載的 AssetBundle 中加載的資源的名字

這個腳本是由一個 Start() 函數和被 Start() 調用的兩個協程組成的。Initialize() 調用了 DontDestoryOnLoad(), 設定了 AssetBundle 的路徑和初始化了 AssetBundle 清單。在 InstantiateGameObjectAsync() 中,如果資源不為空,AssetBundleManager.LoadAssetAsync() 調用資源和 AssetBundle 的名字。 重點注意下,在 “AssetBundleSample/Assets” 路徑下檢視 “MyCube” 資源,會發現 “MyCube” 依賴于 “MyMaterial”,而 “MyMaterial” 依賴于 “UnityLogo”。腳本中隻有 “MyCube” 資源被調用,但是所有的依賴資源都被正确的加載了。 AssetBundle 的路徑怎麼設定也值得注意下。當場景在編輯器中或者從一個開發版 Build 中運作時,這段代碼會給本地資源伺服器設定 AssetBundle 的位置。(更多關于開發版 Build,請檢視釋出 Builds 文檔。)模拟模式開啟後,AssetBundle 會在編輯器中被模拟,這個設定将不會被使用。 對 DontDestoryOnLoad() 作用的了解。雖然在這個非常簡單的腳本中并不是絕對需要它,但是他的存在是假設這個腳本會作為一個更複雜的項目的 AssetBundle 加載器基礎,它需要在場景變化的以後依然存在。 示例 2:加載場景 使用 “Asset/AssetBundles/Simulation Mode” 菜單打開模拟模式

開始 “AssetBundleSample/Scenes/SceneLoader” 場景

注意場景是個空的隻有一個主錄影機,方向光和遊戲對象 “Loader”

開打 PlayMode

然後會注意到一個 cube 和 plane 已經從 AssetBundle 加載到場景裡面了

這個場景被 “LoadScene.cs” 腳本驅動着。 在腳本編輯其中打開 “AssetBundleSample/Scripts/LoadScenes.cs” 腳本。 腳本裡有個兩個公共變量:public string sceneAssetBundle; 和 public string sceneName; sceneAssetBundle; 保持了要加載的 AssetBundle 的名字

sceneName; 保持了要從已加載的 AssetBundle 裡加載的場景的名字

這個腳本是有一個 Start() 函數和被 Start() 調用的兩個協程組成的。Initialize() 調用了 DontDestoryOnLoad(), 設定了 AssetBundle 的路徑和初始化了 AssetBundle 清單。在 InitializeLevelAsync() 裡使用 AssetBundleManager.LoadLevelAsync() 調用場景名字和 isAdditive 來請求一個場景。如果場景為空,AssetManager 會在控制台顯示出錯誤,然後協程結束。 重點注意下,在 “AssetBundleSample/Assets” 路徑下檢視 “MyCube” 資源,會發現 “MyCube” 依賴于 “MyMaterial”,而 “MyMaterial” 依賴于 “UnityLogo”。隻有 “TestScene” 場景被請求了。但在 “TestScene” 中的 “Cube” 和所有依賴的資源都被 AssetBundle Manager 正确的加載了。 AssetBundle 的路徑怎麼設定也值得注意下。當場景在編輯器中或者從一個開發版 Build 中運作時,這段代碼會給本地資源伺服器設定 AssetBundle 的位置。(更多關于開發版 Build,請檢視 釋出 Builds 文檔。)模拟模式開啟後,AssetBundle 會在編輯器中被模拟,這個設定将不會被使用。 對 DontDestoryOnLoad() 作用的了解。雖然在這個非常簡單的腳本中并不是絕對需要它,但是他的存在是假設這個腳本會作為一個更複雜的項目的 AssetBundle 加載器基礎,它需要在場景變化的以後依然存在。 示例 3:變體 要使用 AssetBundle 變體,需要編譯 AssetBundle, 因為模拟模式下不支援它。在編譯 AssetBundle 和它的變體錢,確定所有的資源以及被正确地指定 AssetBundle 名字和如果要被 AssetBundle 變體利用到的話,AssetBundle 變體的名字也要指定。

AssetBundle and the AssetBundle Manager介紹

同時擁有 AssetBundle 名字和 AssetBundle 變體名字的資源 當所有的資源都指定到 AssetBundle 或者 AssetBundle 變體後,選擇 “Assets/AssetBundles/Build AssetBundles” 菜單來編譯它們。

AssetBundle and the AssetBundle Manager介紹

預設情況下,AssetBundle 會根據目前的平台優化,并編譯進項目跟目錄下的 “AssetBundles” 檔案夾内,并按平台分組。 為了簡化流程,不部署新編譯出來的 AssetBundle 遠端,需要開啟本地資源伺服器。通過 “Assets/AssetBundles/Local AssetBundle Server” 可以開啟本地資源伺服器。

AssetBundle and the AssetBundle Manager介紹

本地資源伺服器應該想其他任何網絡連接配接一樣受限制,可能是權限需求,防火牆和其他限制。本地資源伺服器啟動時會被設定到預設 IP 位址和端口的本地資源通路的伺服器,通常是 http://192.168.1.115:7888/. 這個隻是暫時的,它被存儲在 AssetBundleManager/Resources/AssetBundleServerURL 檔案裡面。這些資訊會被 AssetBundleManager 設定或自動改變,使用者不需要關注它們。

AssetBundle and the AssetBundle Manager介紹

當本地資源伺服器運作的時候,編譯後 AssetBundle 可以被本地測試。 選擇 “Assets/AssetBundles/Simulation Mode” 確定模拟模式被禁用了

選擇 “Assets/AssetBundles/Local AssetBundle Server” 確定本地資源伺服器開啟

打開 “AssetBundleSample/Scenes/VariantLoader”

注意場景是個空的隻有一個主錄影機,方向光和遊戲對象 “Loader”

退出 PlayMode (如果在 PlayMode 下)

打開 PlayMode

選擇 “Load HD”

注意同一個 Cube 和 Sprite 加載進場景了,但是材質和他依賴的獨立紋理和 Sprite 紋理卻從不同的 AssetBundle 加載。這些材質有不同的顔色,圖檔有更高的分辨率。

這個場景是被 “LoadVariant.cs” 腳本驅動的。 從編輯器中打開 “AssetBundleSample/Scripts/LoadVariants”。 這個腳本跟 “LoadScenes.cs” 幾乎差不多。主要的差別就是用來差別需要加載的 AssetBundle 變體的變量和設定目前變體的代碼。還有用來建立 UI 按鈕的額外的代碼。 public string variantSceneAssetBundle; 儲存要加載的 AssetBundle 的名字

public string variantSceneName; 儲存要從已加載的 AssetBundle 中加載的場景名字

private string[] activeVariants; 儲存用來區分需要加載的 AssetBundle 變體的 AsssetBundleVariantNames

private bool bundlesLoaded 用來在加載完資源之後隐藏 UI

腳本由一個 BeginExample() 函數和被 Start() 調用的兩個協程組成。 BeginExample() 在 OnGUI()函數中 被 Load HD 或者 Load SD 按鈕調用。Initialize() 調用了 DontDestoryOnLoad(), 設定了 AssetBundle 的路徑和初始化了 AssetBundle 清單。在 BeginExample() 方法裡,在調用 Initialize() 和 InitializeLevelAsync() 之間,目前的變體被設定了。這裡被設定的值從靠 OnGUI 裡的 “Load HD” 或者 “Load SD” 按鈕建立的。在 InitializeLevelAsync() 裡使用 AssetBundleManager.LoadLevelAsync() 調用場景名字和 isAdditive 來請求一個場景。如果場景為空,AssetManager 會在控制台顯式出錯誤,然後協程結束。 這裡需要重視的是 AssetBundle 變體是怎麼樣加載的。activeVariants 數組包含了所有可能的 “激活的” 變量名清單。這個數組用來設定 AssetBundleManager.ActiveVariants 屬性。當加載一個含有變體的 AssetBundle 時,AssetBundle Manager 将會選擇在 ActiveVariants 屬性裡含有 “激活” 的變體名字的 AssetBundle。目前的示例中,ActiveVariants 屬性隻包含一個元素。目前的變體要麼是 “sd”,要麼是 “hd”。在 ActiveVariants 屬性中有多個實體是有可能的。比如,可能有下面一些 AssetBundle: my-material.sd,my-material.hd, my-text.english,my-text.catalan,my-text.welsh。ActiveVariants 屬性可以包含 “hd” 和 “danish” 兩者或者 “sd” 和 “english” 等等任何可以有其他可能組合的變體名。這種方式下,AssetBundle Manager 分開可以加載 hd/sd 圖檔和語言選擇。 有些規則值得注意下。如果,因為一些因素,有一些指定了變體的 AssetBundle,但是在 ActiveVariants 屬性裡沒有 “激活” 的變體名 - 比如目前例子中的 “sd” 或者 “hd” 不在 ActiveVraiants 屬性中 - AssetBundle Manager 将會簡單的選擇第一個它發現的正确名字的 AssetBundle 而忽略變體名。再如果,又因為一些因素,在 ActiveVariants 屬性裡對同一個 AssetBundle 集合有多個 “激活” 的變體名 - 比如, 在目前的例子裡,“sd” 和 “hd” 都在 ActiveVariants 屬性裡 - AssetBundle Manager 将選擇在 ActiveVariants 屬性中的第一個變體名。 示例 4:坦克示例 這個更複雜的示例将包括這篇文章中的所有内容,包括從 AssetBundle 中加載場景和為分辨率,内容和位置加載 AssetBundle 變體。 選擇 “Assets/AssetBundles/Simulation Mode” 確定模拟模式被禁用了

選擇 “Assets/AssetBundles/Local AssetBundle Server” 確定本地資源伺服器開啟

打開 “AssetBundleSample/Scenes/TanksLoader”

注意場景是個空的隻有一個主錄影機,方向光和遊戲對象 “Loader”

進入 PlayMode

選擇一個分辨率,風格和語言

注意在 UI 裡的選擇項就是加載的資源

如果沒有顯式的選擇一個,AssetBundleManager 将自動選擇(基于上面的原則)一個并且在指令行輸出一個警告。

場景靠 “LoadTanks.cs” 腳本驅動。 在編輯器裡面打開 “AssetBundleSample/Scripts/LoadTanks.cs” 腳本。 這個腳本與 “LoadScenes.cs” 和 “LoadAssets.cs” 非常像。腳本使用代碼去加載依賴變體的場景和一樣依賴變體的額外的遊戲對象。也有一些額外的代碼建立 UI 按鈕。

  • public string sceneAssetBundle; 儲存攜帶場景的 AssetBundle 的名字
  • public string sceneName; 儲存要從已加載的 AssetBundle 中加載的場景名字。
  • public string textAssetBundle; 儲存攜帶文字資源的 AssetBundle 的名字
  • public string textAssetName; 儲存要從已加載的 AssetBundle 中加載的文字資源的名字
  • private string activeVariants; 儲存要傳給 AssetBundleManager 的 ActiveVariants
  • private bool bundlesLoaded; 用來資源加載之後隐藏 UI
  • private bool sd, hd, normal, desert, englisth, danish; 儲存用來設定 ActiveVariants 的值
  • private string tankAlbedoStyle, tankAlbedoResolution, languge; 儲存用來設定 ActiveVariants 的值

腳本由一個 BeginExample() 函數和被 Start() 調用的兩個協程組成。 BeginExample() 在 OnGUI()函數中 被 “Load Scene” 按鈕調用。Initialize() 調用了 DontDestoryOnLoad(), 設定了 AssetBundle 的路徑和初始化了 AssetBundle 清單。在 BeginExample() 方法裡,在調用 Initialize() 和 InitializeLevelAsync() 之間,目前的變體被設定了。這裡被設定的值從靠 OnGUI 裡的 “Load Scene” 按鈕建立的。在 InitializeLevelAsync() 裡使用 AssetBundleManager.LoadLevelAsync() 調用場景名字和 isAdditive 來請求一個場景。如果場景為空,AssetManager 會在控制台顯式出錯誤,然後協程結束。在 InstantiateGameObjectAsync() 中資源和 AssetBundle 名字被 AssetBundleManager.LoadAssetAsync() 調用。如果調用的資源不為空,它會被執行個體化。如果 AssetBundle 不能被加載或者資源不能被請求,控制台會列印出錯誤來。 這小結要注意的内容是,多個 資源,AssetBunle 和 AssetBunle 變體怎麼被通路和加載進場景裡,和怎麼樣在運作期設定這些值。 友情提醒 新手翻譯,翻譯不對之處多多見諒! 參考連結

  • 原文

工程下載下傳 https://git.oschina.net/dingxiaowei/AssetBundleManager.git

繼續閱讀