combotree 可以异步加载吗_Unity AssetBundle 资源打包,加载,本地缓存方式,安卓,PC本地加载路径问题...
AssetBundle的定義和作用:
1,AssetBundle是一個壓縮包包含模型、貼圖、預制體、聲音、甚至整個場景,可以在游戲運行的時候被加載。
2,AssetBundle自身保存著互相的依賴關系。
3,壓縮包可以使用LZMA和LZ4壓縮算法,減少包大小,更快的進行網絡傳輸。
4,把一些可以下載內容放在AssetBundle里面,可以減少安裝包的大小。
AssetBundle使用流程(打包方法):
1,首先要選中需要打包的資源在Inspector面板最下方指定這個資源的AssetBundle屬性(包名和后綴),注意這里的名字和后綴是不區分大小寫的,如下圖:
2,構建AssetBundle,這里需要用到編輯器擴展技術,我把資源打包在了StreamingAssets目錄下,這是一個Assets下的特殊目錄,StreamingAssets也就是流式資源載入目錄,該目錄被拷貝到build文件夾中,不會修改,一般用于放置音頻文件。代碼如下:
public class CreateAssetBundles {[MenuItem("Tools/Build AssetBundle")]static void CreateAssetBundle(){string path = "Assets/StreamingAssets";if(Directory.Exists(path) == false)//判斷這個文件夾存不存在{Directory.CreateDirectory(path);}BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.Android);} }3,在編輯器下面打包出來的AB包可以放在本地上,也可以放在服務器上加載。
AssetBundle資源的加載(本地加載,服務器下載):
1,本地同步加載AssetBundle包并且獲取包的內容方式,AssetBundle.LoadFromFile(string path),從磁盤上的文件同步加載AssetBundle,代碼如下:
private void LoadFromFile(string path){//傳入這個AB包存在本地的路徑加載本地資源AssetBundle ab = AssetBundle.LoadFromFile(path);//獲取可使用AssetBundle這個類里面的LoadAsset<T>(string name)方法獲取資源GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");Instantiate(wallPrefab);//實例化這個游戲物體}2,本地異步加載AssetBundle包并且獲取包的內容方式,AssetBundle.LoadFromMemoryAsync(byte[] bytes),代碼如下:
IEnumerator LoadFromMemoryAsync(string path){//打開二進制數組文件,并將打開的數據傳進去AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));yield return createRequest;//等待加載時間AssetBundle ab = createRequest.assetBundle;//獲取加載出來的東西GameObject prefab = ab.LoadAsset< GameObject > ("CubeWall");Instantiate(prefab);}3,下面代碼是異步加載的一個變形同步加載,AssetBundle.LoadFromMemory(byte[] bytes),他的作用有很多,下文會說到
private void LoadFromMemory(string path){//異步加載的一個變形同步加載,傳入具有AssetBundle數據的字節數組AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");//獲取這個名字的游戲物體Instantiate(wallPrefab);//實例化這個游戲物體}4,使用UnityWebRequestAssetBundle.GetAssetBundle(string uri)到服務器下載AB包,現在官方推薦的主流方式,以前使用的WWW方式下載,還有UnityWebRequest.GetAssetBundle(string uri)這兩種方式都已經棄用了;使用這個方式不但可以下載服務器上的資源,同時他也可以加載本地的資源,但是強烈建議如果要加載本地資源,還是使用本地同步/異步加載的方式比較妥當,兩種方式下面代碼都有寫到,留意代碼注釋:
IEnumerator MyUnityWebRequest(){//本地加載路徑前面要加上file://否則會出錯//string uri = @"file://D:Unity3D_ProjectAdvancedAsset Bundle ProjectAssetBundlescubewall.unity3d";//UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri);//服務器上下載UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle("http://localhost/AssetBundles/cubewall.unity3d");yield return request.SendWebRequest();if (string.IsNullOrEmpty(request.error) == false)//判斷下載有沒有出錯,request.error表示錯誤信息{Debug.Log(request.error);//輸出錯誤yield break;//退出攜程}//AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);//獲取下載到的資源//獲取資源的另外一種方式,直接獲取到UnityWebRequest下載到的東西然后強轉成DownloadHandlerAssetBundle,然后再獲取到AssetBundleAssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;GameObject prefab = ab.LoadAsset<GameObject>("CubeWall");Instantiate(prefab); }減少包大小打包方式:我們可以將一些共用的圖片/材質單獨打包成一個包,這樣做可以大大的減小AB包的大小,因為我們在打包的時候系統或默認將這個包的依賴一起打包進去的,當我們打包的A包和B包都依賴同一個材質/圖片時那么系統就會默認的將這個依賴同時打包到A包和B包里,這樣就會導致我們打包出來的AB包比較大,但當我們將A包和B包的依賴單獨打包成一個包時,這時系統就不會再將這個依賴打包到兩個包里了,這樣我們的包就會小很多,不過當我們要用到包的資源,在加載包的資源之前,先把這個包的依賴加載出來,加載包的依賴的,代碼如下:(這里加載依賴的時候需要注意的是我們要加載的是跟文件目錄名字一樣的后綴為manifest包,比如我們上面構造AB包的時候是直接在Asset文件下創建了StreamingAssets將打包出來的包放在StreamingAssets這個文件夾下,那么我們加載的依賴包就是StreamingAssets.manifest這個包)
//加載這個物體的依賴//加載生成AB包文件時系統自動生成的一個名字跟文件目錄一樣的后綴為manifest包AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");//獲取到他的AssetBundleManifest文件AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");string[] strs = manifest.GetAllDependencies("cubewall.unity3d");//獲取到傳進去的包的所有依賴的包的名字//遍歷并加載所有依賴的包foreach (string name in strs){//加載依賴,將文件的根目錄(我們打包出來的包的保存路徑)+包名(即我們自己定義的AssetBundle打包的名字和后綴)傳進去AssetBundle.LoadFromFile(rootDirectory + name);}如何將從服務器上下載回來的AB包保存到本地上,代碼如下:
1,要獲取到服務器上下載回來的數據,需要用到UnityWebRequest.Get(string uri) 這個API去下載,只有使用這個API下載回來的資源我們才是可以訪問到數據的,官方有一個專門用于下載AB包的API UnityWebRequestAssetBundle.GetAssetBundle(string uri)使用這個API下載回來的資源它是不支持原始數據訪問的,也就是說我們想要保存從服務器上下載回來的AB包資源就不能使用這個API了,從服務器上下載AB包并保存到本地的代碼如下:
//獲取服務器上的資源IEnumerator MyUnityWebRequest(){string uri = "http://localhost/AssetBundles/res.ab";//服務器地址request = UnityWebRequest.Get(uri);//要使用這種方式獲取資源,才能訪問到他的字節流//這個方法主要是用來獲取AssetBundle資源的,但他下載到的數據是不給訪問的,如果想訪問或者保存下載回來的數據用上面的UnityWebRequest.Get()//request = UnityWebRequestAssetBundle.GetAssetBundle(pathMP);yield return request.SendWebRequest();//保存下載回來的文件if (request.isDone){//構造文件流FileStream fs = File.Create(Application.persistentDataPath + "/res.ab");//將字節流寫入文件里,request.downloadHandler.data可以獲取到下載資源的字節流fs.Write(request.downloadHandler.data, 0, request.downloadHandler.data.Length);fs.Flush(); //文件寫入存儲到硬盤fs.Close(); //關閉文件流對象fs.Dispose(); //銷毀文件對象}//這里我們直接使用異步加載的一個變形同步加載,獲取下載回來的資源ab = AssetBundle.LoadFromMemory(request.downloadHandler.data);//ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;}2,從服務器下載回來的數據并保存在本地后,如何加載保存在本地的數據,方式有很多種,可以用到上面介紹的,同步加載方式;異步加載方式;或者是異步加載的變形同步加載都可以主要看需求的,我這里使用了官方推薦的專門獲取AB包的API來加載,代碼如下:
IEnumerator MyData(){//加載保存在本地的資源request = UnityWebRequestAssetBundle.GetAssetBundle(Application.persistentDataPath + "/res.ab");yield return request.SendWebRequest();ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;}把打包好的AB包直接放在本地上StreamingAssets文件夾下,在進入游戲后直接從本地進行加載的路徑問題(PC端與安卓端的路徑)
1,為什么要放在StreamingAssets這個文件夾下來加載呢,因為該目錄會被拷貝到
build文件夾中,不會修改,他是流式資源載入目錄,而且官方也專門給我們封裝了加載路徑
2,加載StreamingAssets這個文件夾下的資源的路徑是:
Application.streamingAssetsPath+"/"+文件名稱組成,這里需要加載的資源要帶后綴
這個路徑的真實路徑在PC端和安卓端都是不同的,Unity會根據發布的平臺而進行變動,
值得一提的是在Unity舊版本里面發布安卓端,使用這個路徑加載StreamingAssets
下的資源他是會報錯的,但是現在新版本(2019版)經過實驗是不會出現任何問題的,不管
是PC端還是安卓端加載都沒有任何問題,如果你的版本是舊版本或者是在安卓端加載時
路徑出現問題,那么可以使用:
"jar:file://" + Application.dataPath + "!/assets/"+文件名稱組成 這個路徑,這個路徑
是舊版本安卓端加載StreamingAssets文件夾下資源的路徑。
加載AssetBundle 資源,運行游戲時出現材質丟失問題解決方法:
1,我們在打包AB包的時候,Unity默認是不連Shader一同打包進去的,所以當我們在
發布運行的時候就會出現材質丟失的問題,所以這個時候就需要我們自行添加了,添加步驟如
下:點擊Edit>Project Settings>Graphics,然后下拉到Always Included Shaders,
將Size改大一些,然后在將丟失的那個材質所使用的Shader添加進去,然后再重新打包運
行就可解決材質丟失的問題。
總結
以上是生活随笔為你收集整理的combotree 可以异步加载吗_Unity AssetBundle 资源打包,加载,本地缓存方式,安卓,PC本地加载路径问题...的全部內容,希望文章能夠幫你解決所遇到的問題。