1.本地异步
1 IEnumerator LoadFromMemoryAsync(stringpath)2
3 {4
5 AssetBundleCreateRequest createRequest =AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));6
7 yield returncreateRequest;8
9 AssetBundle bundle =createRequest.assetBundle;10
11 var prefab = bundle.LoadAsset("MyObject");12 Instantiate(prefab);13
14 }
2.本地同步(同步会造成主线程的卡顿,造成游戏画面的不流畅)
1 public classLoadFromFileExample extends MonoBehaviour {2 function Start() {3 var myLoadedAssetBundle = AssetBundle.LoadFromFile(bine(Application.streamingAssetsPath, "myassetBundle"));4 if (myLoadedAssetBundle == null) {5 Debug.Log("Failed to load AssetBundle!");6 return;7 }8 var prefab = myLoadedAssetBundle.LoadAsset("MyObject");9 Instantiate(prefab);10 }11 }
3.从web端下载并加载 (要引用working命名空间)
IEnumerator IE_LoadAssetBundleByName(stringbundleName)
{while (!Caching.ready)
{yield return null;
}stringfileType;#if UNITY_STANDALONE_WIN || UNITY_EDITORfileType= "file://";#elif UNITY_ANDROID && !UNITY_EDITORfileType= "jar://";#endifUnityWebRequest request= working.UnityWebRequest.GetAssetBundle(fileType + assetBundlePath + "/" , 0);yield return request.SendWebRequest();//开始请求
while (!request.isDone)
{
Debug.Log("正在下载:" +request.downloadProgress.ToString());yield return 1;
}if(request.isDone)
{
Debug.Log("完成");
}if (request.isNetworkError ||request.isHttpError)
{
Debug.Log("错误");
}else//完成
{
Debug.Log("完成可用");
AssetBundle ab=DownloadHandlerAssetBundle.GetContent(request);//完成以后就能用了
if (ab == null)
{yield break;
}
}
request.Dispose();
}
加载好的AssetBundle使用以下这段代码
1 T objectFromBundle = bundleObject.LoadAsset(assetName);
T是要加载的资源类型。
决定如何加载资源时有几个选项。我们有LoadAsset,LoadAllAssets和他们同行的异步LoadAssetAsync和LoadAllAssetsAsync分别。
这是如何同步从AssetBundles加载资源:
要加载单个GameObject:
1 GameObject gameObject = loadedAssetBundle.LoadAsset(assetName);
要加载所有资源:
1 Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();
异步加载资源,在访问资产之前,您需要等待此操作完成。
单个资源:
AssetBundleRequest request = loadedAssetBundleObject.LoadAssetAsync(assetName);yield returnrequest;var loadedAsset = request.asset;
所有资源:
AssetBundleRequest request =loadedAssetBundle.LoadAllAssetsAsync();yield returnrequest;var loadedAssets = request.allAssets;
但是,为了节省空间,我们在打包AssetBundle包的时候经常把多个资源的依赖项单独打包。比如说有两个模型modelA和modelB,他们共同使用了matA的材质球,这个matA就是modelA和modelB的依赖项,如果我们只加载modelA或者modelB,那么这两个模型的材质是丢失的。所以为了避免这个情况,我们要根据依赖文件来先找到依赖项并加载它(bundle包)。
加载依赖文件:
1 private void GetAssetBundleManifest(stringpath)2 {3 AssetBundle maniFestAb = AssetBundle.LoadFromFile(path + "/AssetBundles");4 if (maniFestAb == null)5 {6 Debug.Log("加载失败");7 return;8 }9 AssetBundleManifest manifest = maniFestAb.LoadAsset("AssetBundleManifest");//AssetBundleManifest基本固定的,不用改
10
11 string[] strArrAllAb = manifest.GetAllAssetBundles();//获取所有包的包名(就是我们打包时候取的名字,连带了路径)
12
13 for (int i = 0; i < strArrAllAb.Length; i++)14 {15 //做你想做的事,推荐放到字典里,以后想加载的时候查找一次(废话)
16 }17 AssetBundle.UnloadAllAssetBundles(true);//如果用不到了记得卸载资源,把我们要的信息放个一个字典里就好,只加载一次(再次废话)。
18 }
好了,我们虽然加载了资源,但是assetbundle包其实还留在内存中。这时候,为了节约性能,我们要把不用的资源删除。
可以使用这个:AssetBundle.Unload(bool)
参数区别:
a. 参数是true的时候是完全卸载资源,包括了AB包(AssetBundle,一下都简称AB包,每次都打太麻烦了)和实例化的资源。就算是正在引用的资源也会被卸载,如果使用不当,会造成纹理丢失之类的情况。应该确保资源确实没有哪里引用了,才调用AssetBundle.Unload(true);
b. 参数是false的时候会卸载所有没有被引用的资源,这就造成了源AB包已经被卸载,实例化出来、并被人使用者的某资源就没有了标记,再次加载这个物体的时候要重新加载ab包,加载你要的某资源,之前加载的某资源虽然没有用了,但是还存在于游戏内存中,这样下去就会越积越多,就炸了。
所以要调用一下Resources.UnloadUnusedAssets();这个方法。另外,在游戏场景切换的时候,引擎也会自动的调用这个方法,把不存在引用的资源卸载。
如果觉得《assetbundle能不能删除_AssetBundle 加载 使用以及卸载》对你有帮助,请点赞、收藏,并留下你的观点哦!