Unity笔记之AssetBundle打包和加载(场景和预制体) 您所在的位置:网站首页 unityAB包卸载后资源还能用吗 Unity笔记之AssetBundle打包和加载(场景和预制体)

Unity笔记之AssetBundle打包和加载(场景和预制体)

2024-06-09 23:46| 来源: 网络整理| 查看: 265

需求:实现用AssetBundle打包和加载场景、预制体。 这是参照一位大佬的拿来改了一点,但是现在没找到大佬的文章,就先这样吧。

实现打AB包方法一:

打包工具AssetBundleBuilder.cs

using UnityEngine; using UnityEditor; using System.IO; /// /// 资源包打包工具 /// public class AssetBundleBuilder : EditorWindow { [MenuItem("打包/Windows/资源包和场景")] public static void BuildAbsAndScenesWindows() { AssetBundleBuilder assetBundleBuilder = EditorWindow.GetWindow(); assetBundleBuilder.Show(); // } static string outPath; private void OnGUI() { GUILayout.Space(10); GUI.skin.label.fontSize = 12; GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUILayout.Label("AssetBundle文件名称:", GUILayout.MaxWidth(160)); outPath = EditorGUILayout.TextField(outPath); EditorGUI.EndDisabledGroup(); //string s = EditorGUILayout.TextArea("s"); if (GUILayout.Button("开始打包场景和资源")) { BuildAbsAndScenes(BuildTarget.StandaloneWindows); } //GUILayout.EndVertical(); //EndWindows(); } [MenuItem("打包/Android/资源包和场景")] public static void BuildAbsAndScenesAndroid() { BuildAbsAndScenes(BuildTarget.Android); } [MenuItem("打包/IOS/资源包和场景")] public static void BuildAbsAndScenesIOS() { BuildAbsAndScenes(BuildTarget.iOS); } [MenuItem("打包/Windows/资源包")] public static void BuildAbsWindows() { BuildAssetBundles(BuildTarget.StandaloneWindows); } [MenuItem("打包/Android/资源包")] public static void BuildAbsAndroid() { BuildAssetBundles(BuildTarget.Android); } [MenuItem("打包/IOS/资源包")] public static void BuildAbsIOS() { BuildAssetBundles(BuildTarget.iOS); } [MenuItem("打包/Windows/场景")] public static void BuildScenesWindows() { BuildScenes(BuildTarget.StandaloneWindows); } [MenuItem("打包/Android/场景")] public static void BuildScenesAndroid() { BuildScenes(BuildTarget.Android); } [MenuItem("打包/IOS/场景")] public static void BuildScenesIOS() { BuildScenes(BuildTarget.iOS); } // 打包AssetBundle和Scenes public static void BuildAbsAndScenes(BuildTarget platform) { BuildAssetBundles(platform); BuildScenes(platform); } // 打包AssetBundles private static void BuildAssetBundles(BuildTarget platform) { // 输出路径 //string outPath = Application.streamingAssetsPath + "/Abs"; if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath); EditorUtility.DisplayProgressBar("信息", "打包资源包", 0f); BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.DeterministicAssetBundle, platform); AssetDatabase.Refresh(); Debug.Log("所有资源包打包完毕"); } // 打包Scenes private static void BuildScenes(BuildTarget platform) { // 指定场景文件夹和输出路径 string scenePath = Application.dataPath + "/AbResources/Scenes"; //string outPath = Application.streamingAssetsPath + "/Abs/"; if (Directory.Exists(scenePath)) { // 创建输出文件夹 if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath); // 查找指定目录下的场景文件 string[] scenes = GetAllFiles(scenePath, "*.unity"); for (int i = 0; i if (!Directory.Exists(directory)) return new string[0]; string searchTypes = (types == null || types.Length == 0) ? "*.*" : string.Join("|", types); string[] names = Directory.GetFiles(directory, searchTypes, SearchOption.AllDirectories); return names; } }

加载ABTest.cs

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; public class ABTest : MonoBehaviour { public Text textProgress; private void Awake() { //DontDestroyOnLoad(gameObject); //StartCoroutine(DownloadPrefab()); //StartCoroutine(DownloadScene()); LoadScene(Application.streamingAssetsPath + "/Abs/" + "test"); LoadPrefabs(Application.streamingAssetsPath + "/Abs/" + "cube.ab"); } public void LoadPrefabs(string url) { StartCoroutine(DownloadPrefab(url)); } IEnumerator DownloadPrefab(string url) { //ab包的地址 //string url = Application.streamingAssetsPath + "/Abs/" + "cube" + ".ab"; AssetBundle ab; using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)) { //yield return request.SendWebRequest(); request.SendWebRequest(); while (!request.isDone) { Debug.Log(request.downloadProgress); //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%"; yield return null; } if (request.isDone) { Debug.Log(100); //textProgress.text = 100 + "%"; } ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; if (ab == null) { Debug.LogError("AB包为空"); yield break; } } GameObject ga = ab.LoadAsset("Assets/Prefabs/cube.prefab");//加载出来 Instantiate(ga);//实例化出来 //Debug.Log(ga.name); //ab.Unload(false); Debug.Log("成功"); yield break; } public void LoadScene(string url) { StartCoroutine(DownloadScene(url)); } IEnumerator DownloadScene(string url) { //ab包的地址 //string url = Application.streamingAssetsPath + "/Abs/" + "samplescene"; //方式一 //AssetBundle ab; //using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)) //{ // //yield return request.SendWebRequest(); // request.SendWebRequest(); // while (!request.isDone) // { // Debug.Log(request.downloadProgress); // //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%"; // yield return null; // } // if (request.isDone) // { // Debug.Log(100); // //textProgress.text = 100 + "%"; // } // ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; // if (ab == null) // { // Debug.LogError("AB包为空"); // yield break; // } // string[] s = ab.GetAllScenePaths(); // SceneManager.LoadScene(s[0], LoadSceneMode.Single); //} //方式二 myLoadedAssetBundle = AssetBundle.LoadFromFile(url); scenePaths = myLoadedAssetBundle.GetAllScenePaths(); SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single); Debug.Log("成功"); yield break; } private AssetBundle myLoadedAssetBundle; private string[] scenePaths; }

这里面的加载场景有两种方式,但是最关键、核心的就是这句代码 scenePaths = myLoadedAssetBundle.GetAllScenePaths();

以上就是打包和加载了 但是这样的打包存在一定的局限性,不太建议使用这种方式。还有一种方式就是使用官方的AssetBundleBrowser来进行打包和加载(也是个人比较推荐的)。

实现打AB包方法二:

1、去PackageManager里面下载Asset Bundle Browser; 2、打开Asset Bundle Browser窗口; 在这里插入图片描述 3、把资源拖进去 在这里插入图片描述 (这里报感叹号弄成依赖资源就可以去掉了,当然也可以不管) 在这里插入图片描述 然后build根据个人需求修改就可以打包了 在这里插入图片描述 至此,打包结束。

然后就是加载资源:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; public class DemoLoadBundle : MonoBehaviour { public string bundleName = "dogpbr";//预制体ab的名字 public string assetName = "dogpbr";//加载到场景中这个物体的名字 private void Start() { DontDestroyOnLoad(gameObject); LoadDependencies(); LoadBundleScene(); } private void Update() { if (Input.GetKeyDown(KeyCode.Q)) { InstantiateBundlePrefab(); } } /// /// 保存所有AssetBundle包的物体的名字 /// public List abPrefabNameList = new List(); /// /// 保存所有AssetBundle包场景的名字 /// public List abSceneNameList = new List(); /// /// 加载所有依赖资源(这里记录的只是单个场景和单个预制体的演示) /// void LoadDependencies() { //AssetBundleManifest 记录着所有资源的依赖信息 AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows"); AssetBundleManifest manifest = assetBundle.LoadAsset("AssetBundleManifest"); //获取所有ab资源的名字 string[] s = manifest.GetAllAssetBundles(); for (int i = 0; i var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie); } //加载场景的依赖包 string[] dependencieScene = manifest.GetAllDependencies(sceneName); foreach (var dependencie in dependencieScene) { var dependencieAsync = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependencie); } } private bool Check(string name) { if (abPrefabNameList.Contains(name)) return true; if (abSceneNameList.Contains(name)) return true; return false; } AssetBundle asset;//实现可多次加载 /// /// 加载ab包的预制体(单个) /// private void InstantiateBundlePrefab() { if (asset == null) asset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + bundleName); var asset_go = asset.LoadAsset(assetName); Instantiate(asset_go); } public string sceneName = "abtestscene";//场景打包出来的名字 #region 方式一 /// /// 加载ab包的场景(单个) /// 注:加载场景的时候可能会出现一个问题,那就是场景里面存在一个ab包的预制体,但你再去加载这个预制体就会报错。(解决办法就是把你场景里面的那个预制体删掉就可以了) /// IEnumerator LoadABScene() { AssetBundle ab; using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle("")) { //yield return request.SendWebRequest(); request.SendWebRequest(); while (!request.isDone) { Debug.Log(request.downloadProgress); //textProgress.text = (request.downloadProgress * 100).ToString("F0") + "%"; yield return null; } if (request.isDone) { Debug.Log(100); //textProgress.text = 100 + "%"; } ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; if (ab == null) { Debug.LogError("AB包为空"); yield break; } string[] s = ab.GetAllScenePaths(); SceneManager.LoadScene(s[0], LoadSceneMode.Single); } } #endregion #region 方式二 /// /// 加载ab包的场景(单个) /// 注:加载场景的时候可能会出现一个问题,那就是场景里面存在一个ab包的预制体,但你再去加载这个预制体就会报错。(解决办法就是把你场景里面的那个预制体删掉就可以了) /// private void LoadBundleScene() { myLoadedAssetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + sceneName); scenePaths = myLoadedAssetBundle.GetAllScenePaths(); SceneManager.LoadScene(scenePaths[0], LoadSceneMode.Single); } private AssetBundle myLoadedAssetBundle; private string[] scenePaths; #endregion }

以上就是一整套的打包和加载了。

方法三:

因为第一种没测试过是否会把预制体的依赖资源一起打进去,所以才有了这第三种方法的记录。 Editor目录下的打包脚本: CreateAssetBundles.cs(对了,这个方法预制体打标签时不能有后缀,只能有名字)

using UnityEditor; using System.IO; public class CreateAssetBundles { [MenuItem("Assets/Build AssetBundles")] static void BuildAssetBundles() { string dir = "AssetBundles"; if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); } }

这个路径是打包到Asset同一层级的目录下,加载测试脚本里面的路径是StreamingAssets目录下,所以需自行拖到StreamingAssets目录下。 加载脚本:DownLoadAssetBundles.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class DownLoadAssetBundles : MonoBehaviour { void Start() { InstantiateBundlePrefab(); } public string assetName; AssetBundle asset;//实现可多次加载 /// /// 加载ab包的预制体(单个) /// private void InstantiateBundlePrefab() { if (asset == null) asset = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + assetName); var asset_go = asset.LoadAsset(assetName); Instantiate(asset_go); } }

以上就是方法三的打包和加载了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有