官方文档
参照视频
1.AssetBundle打包
1.1设置资源的命名和后缀
命名只支持小写
1.2创建Editor文件夹,在里面创建编辑器打包AssetBundle的脚本
using UnityEditor;
using System.IO;public class CreateAssetBundles {[MenuItem("Assets/Build AssetBundles")]static void BuildAllAssetBundles(){string dir = "AssetBundles";if( Directory.Exists(dir)==false){Directory.CreateDirectory(dir);}BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);}
}
压缩方式:
BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩包下,但加载时间长
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部
注意:使用LZ4压缩,可以获得可以跟不压缩相媲美的加载速度,而且比不压缩文件要小
1.3选择菜单Assers-》点击Build AssetBundles 进行打包
得到打包后的文件
2.AssetBundle加载方式
原则上在使用资源之前需要先加载材质包,再创建prefab,防止材质丢失。share.unity3d为cubewallf的材质贴图包,share.unity3d和cubewall.unity3d加载先后顺序不影响
加载方式1:本地加载 AssetBundle.LoadFromFile
AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/share.unity3d");AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/cubewall.unity3d");GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");Instantiate(wallPrefab);
加载方式2: 内存中加载(异步) AssetBundle.LoadFromMemoryAsync
IEnumerator LoadFromMemoryAsync(string path){AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));yield return createRequest;AssetBundle bundle = createRequest.assetBundle;var prefab = bundle.LoadAsset<GameObject>("MyObject");Instantiate(prefab);}
内存中加载(同步) AssetBundle.LoadFromMemory
AssetBundle ab=AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
加载方式3:网络加载 UnityWebRequestAssetBundle
IEnumerator InstantiateObject()
{string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; UnityEngine.Networking.UnityWebRequestAssetBundle request = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(uri, 0);yield return request.SendWebRequest();AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);GameObject cube = bundle.LoadAsset<GameObject>("Cube");GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");Instantiate(cube);Instantiate(sprite);
}
(弃用)网络加载2 LoadFromCacheOrDownload(string url, int version);
IEnumerator Start(){while (!Caching.ready)yield return null;using (var www = WWW.LoadFromCacheOrDownload("https://myserver.com/myassetBundle.unity3d", 5)){yield return www;if (!string.IsNullOrEmpty(www.error)){Debug.Log(www.error);yield return null;}var myLoadedAssetBundle = www.assetBundle;var asset = myLoadedAssetBundle.mainAsset;}}
API2:LoadFromCacheOrDownload(string url, int version, uint crc); crc表示校验完整性,crc在.mainifest文件里
3.通过Manifest文件得到某个包的依赖
AssetBundles.manifest 里面包含所有包对应的依赖
代码:
AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");//固定为AssetBundles
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//固定为“AssetBundleManifest”
string[] strs = manifest.GetAllDependencies("cubewall.unity3d");
foreach (string name in strs) {print(name);//share.unity3dAssetBundle.LoadFromFile("AssetBundles/"+ name); //加载cubewall.unity3d的依赖包
}
4.AssetBundle的卸载
- 卸载可以减少内容的使用
- 不当的卸载,有可能导致丢失(材质丢失bug红等)
- AssetBundle.Unload(true) 卸载所有资源,即使有资源被使用着,推荐这个方法,卸载前确保依赖的包不被其他物体使用了。可以在切换场景是loading scene阶段去卸载
- AssetBundle.Unload(false) 卸载所有没有被使用的资源,一般不用这个方法,会导致某些资源不被卸载,导致内存被滥用
- 个别资源的卸载 1.通过Resources.UnloadUnusedAssets 2.场景切换的时候,自动调用Resources.UnloadUnusedAssets
5.Unity AssetBundle Browser Tool
使用文档
github下载地址