Unity热更新学习(一) —— AssetBundle 打包和加载
理论不多说,网上,官方文档都有。 这里有一篇介绍很全面的文章:https://www.cnblogs.com/ybgame/p/3973177.html
示例和注意点记录一下,用到时以便查阅。
一、打包代码(Editor)
我所知道的,有两种打包方法:1、所有打包参数在代码里设置,完全代码控制;2、在编辑器中设置打包参数,代码简便
第一种:
在代码中指定bundle包名,指定包含在该bundle里的所有资源路径
1 [MenuItem("AssetsBundle/Build Bundle -- 代码中设置参数")] 2 static void BuildAB() 3 { 4 string path = Application.streamingAssetsPath + "/AssetsBundles/"; 5 6 if (Directory.Exists(path)) 7 Directory.Delete(path, true); 8 Directory.CreateDirectory(path); 9 10 AssetBundleBuild[] buildMap = new AssetBundleBuild[2]; 11 12 //指定bundle包名 13 buildMap[0].assetBundleName = "prefab_bundle"; 14 15 string[] assets = new string[2]; 16 assets[0] = "Assets/AssetsBundleObj/Cube.prefab"; // 必须是完整的文件名(包括后缀) 17 assets[1] = "Assets/AssetsBundleObj/Sphere.prefab"; 18 //指定bundle包含的资源路径数组 19 buildMap[0].assetNames = assets; 20 21 buildMap[1].assetBundleName = "scene_bundle"; 22 string[] scenes = new string[1]; 23 scenes[0] = "Assets/_Scenes/Scene.unity"; 24 buildMap[1].assetNames = scenes; 25 26 BuildPipeline.BuildAssetBundles(path, buildMap, BuildAssetBundleOptions.DeterministicAssetBundle, BuildTarget.StandaloneWindows); 27 }
第二种:
先在编辑器中设置参数,选中要打包的对象,设置好包名,后缀。
然后就直接打bundle包了,无需再在代码中处理包名之类的参数。
1 [MenuItem("AssetsBundle/Build Bundle -- 编辑器中设置参数")] 2 static void BuildAB2() 3 { 4 string path = Application.streamingAssetsPath + "/AssetsBundles/"; 5 6 if (Directory.Exists(path)) 7 Directory.Delete(path, true); 8 Directory.CreateDirectory(path); 9 10 BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.DeterministicAssetBundle, BuildTarget.StandaloneWindows); 11 }
二、加载代码(runtime)
通过www方法加载bundle,并把加载出来的资源实例化。
1 void OnGUI()
2 {
3 if (GUILayout.Button("加载预制体Cube"))
4 {
5 StartCoroutine(LoadObj("prefab_bundle", "cube.prefab"));//有没有.prefab后缀都正常加载
6 }
7 if (GUILayout.Button("加载预制体Sphere"))
8 {
9 StartCoroutine(LoadObj("prefab_bundle", "sphere"));
10 }
11 }
12 /// <summary>
13 /// 加载预制体
14 /// </summary>
15 /// <param name="name"></param>
16 /// <returns></returns>
17 IEnumerator LoadObj(string bundle_name, string name)
18 {
19 string path = "file://" + Application.streamingAssetsPath + "/AssetsBundles/" + bundle_name;
20 //Debug.LogError(string.Format("obj {0}", path));
21 WWW www = new WWW(path);
22 yield return www;
23 if (www.error == null)
24 {
25 AssetBundle bundle = www.assetBundle;
26 //这里LoadAsset第二个参数 有没有都能正常运行,这个类型到底什么用途还有待研究
27 GameObject go = Instantiate(bundle.LoadAsset(name, typeof(GameObject))) as GameObject;
28 //go.transform.parent = transform;
29 // 上一次加载完之后,下一次加载之前,必须卸载AssetBundle,不然再次加载报错:
30 // The AssetBundle 'Memory' can't be loaded because another AssetBundle with the same files is already loaded
31 bundle.Unload(false);
32 }else
33 {
34 Debug.LogError(www.error);
35 }
36 }