我們在之前知道了AssetBundle打包的時候除了生成AssetBundle包之外,還會生成.manifest文件,我們把它稱作配置文件。從事Android開發的同學們一定不會對.AndroidManifest文件陌生,所以我們習慣上也把AssetBundle打包的時候生成的.manifest文件成爲該AssetBundle包的配置文件。
我們使用EditPlus打開配置文件看看:
我們先來看看上圖中指出的1、2、3:
1.CRC
說起CRC我們可能會有些陌生,但是說起MD5,恐怕大家都只要這玩意是幹什麼用的了。
MD5用於確保信息傳輸完整一致,也就是我們常說的校驗碼,CRC與MD5相同,屬於校驗文件方式的一種。資源包在使用之前首先要保證我接收到的包要完整吧,所以unity打包AssetBundle包,使用了CRC來進行校驗。至於CRC與MD5有什麼區別,我想這並不在我們討論的範圍之內,只需要瞭解一點:CRC用於通訊,MD5用於大容量存儲,MD5更安全,CRC效率更高。
2.Assets:
這塊區域包含的是這個AssetBundle包包含了哪些資源,我們可以看到有名爲Wood texture floor_01的png圖片和名爲Wood texture floor_01的材質,同時,它們的路徑也就很清楚的顯示了出來。
3.Dependencies:
這個就是我們之前說的依賴信息了,unity在打包的時候會根據資源之間的依賴關係自動向這其中插入相關信息。
上圖中因爲是我們共享的圖片和素材的AssetBundle包,所以在包含了圖片和材質的信息之後,並不需要依賴其他的資源,所以依賴信息的位置爲空,我們打開prefab的AssetBundle包的配置文件:
我們可以看到球體prefab打包AssetBundle之後,配置文件中包含一個校驗碼,prefab的路徑信息,最重要的是在最下方的依賴信息中,我們可以看到它依賴了我們剛剛查看的material包。
我們再來看看另外一個問題:
假如我在開發的時候,代碼加載了AssetBundle包,但是包裏依賴的資源我在工程裏都存在,那麼我需不需要加載依賴的包呢?
答案是需要的。
加載包並且實例化prefab對象的時候,我們只認依賴關係,依賴關係能爲我們提供精確地加載目標,而不需要在工程裏面挨個檢索資源。
這就是另一個內容:我們在加載某個AssetBundle包的時候,如果它依賴別的AssetBundle包,那麼我們最好在加載並使用它之前,先把依賴的包加載出來,否則可能導致材質丟失、要實例化的對象不存在等錯誤。
我們試驗下:unity工程中有了材質和貼圖,我們來加載球體:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadAssetsBundlePackage : MonoBehaviour
{
// Use this for initialization
void Start()
{
//先將資源包加載進內存
AssetBundle assetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
//然後再加載prefab
GameObject prefab = assetBundle.LoadAsset<GameObject>("Sphere");
Instantiate(prefab);
}
}
結果如下:
雖然本地有着材質和貼圖,但是球體prefab並不會使用,它認準的是資源包中依賴的材質和貼圖。
所以我們需要在加載球體的AssetBundle包之前先將材質和貼圖的AssetBundle對象加載進內存中:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadAssetsBundlePackage : MonoBehaviour
{
// Use this for initialization
void Start()
{
//先將材質和貼圖的資源包加載進內存
AssetBundle materialAssetBundle = AssetBundle.LoadFromFile("AssetBundles/material.assetsbundle");
//接着將prefab資源包加載進內存
AssetBundle sphereAssetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
//然後再加載prefab
GameObject prefab = sphereAssetBundle.LoadAsset<GameObject>("Sphere");
Instantiate(prefab);
}
}
結果我們可以發現,prefab能夠正常的加載出來了:
值得注意的是,我們在使用代碼加載AssetBundle包的時候,一定要把路徑、資源包名稱、包的後綴都寫正確,否則會找不到資源包而加載出錯。
另外,我們在剛纔說最好在加載並使用它之前,先把依賴的包加載出來,並把它加了紅,這裏要多說一句哦。
根據我代碼的測試,加載先後順序並不影響關係的依賴:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LoadAssetsBundlePackage : MonoBehaviour
{
// Use this for initialization
void Start()
{
//先將prefab資源包加載進內存
AssetBundle sphereAssetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
//然後再加載prefab
GameObject prefab = sphereAssetBundle.LoadAsset<GameObject>("Sphere");
//實例化出一個實體
Instantiate(prefab);
//3秒鐘後再加載材質和貼圖到內存中
Invoke("LoadMaterialAssetBundle",3.0f);
}
/// <summary>
/// 加載材質和貼圖
/// </summary>
void LoadMaterialAssetBundle()
{
AssetBundle.LoadFromFile("AssetBundles/material.assetsbundle");
}
}
動態圖如下:
也就是說資源加載先後並沒有強制性要求,哪怕你是後面加載進來的,只要我們之前存在關係,我就能順藤摸瓜找到你。
這個過程是沒有問題的,但是如果這個材質丟失後續補上的過程被玩家看到,那想必是很不好的遊戲體驗。所以我們知道了有這麼個情況,加載順序還是按照規範來老老實實加載吧!
原創內容,未經許可不得擅自轉載文章部分或全部內容。