胶州专业网站建设公司,网站开发的软硬环境怎么描述,班级网页设计素材,网站建设与管理实践心得目录
1、文章介绍
2、具体思路和写法 #xff08;1#xff09;AB包的打包 #xff08;2#xff09;AB包的加载 #xff08;3#xff09;AB包卸载
3、结语 1、文章介绍
本篇博客主要起记录和学习作用#xff0c;简单的介绍一下AB包批量的打包和加载AB包的方式1AB包的打包 2AB包的加载 3AB包卸载
3、结语 1、文章介绍
本篇博客主要起记录和学习作用简单的介绍一下AB包批量的打包和加载AB包的方式若各位同学有幸看到本篇博客希望能够对你有所帮助。 2、具体的思路和写法
1AB包的打包
先介绍一下打ab包所要用到的api BuildPipeline.BuildAssetBundle(string outputPath,AssetBundleBuild[] builds,BuildAssetBundleOptions assetBundleOptions,BuildTarget targetPlatform)
参数1ab包输出路径 参数2ab包信息(主要是assetBundleNameab包名字assetNames资源名) 注意assetNames一定是要Assets下的路径不要使用windows路径不然打包会报错 /// summary/// paraBuild AssetBundles from a building map./para/// /summary/// param nameoutputPathOutput path for the AssetBundles./param/// param namebuildsAssetBundle building map./param/// param nameassetBundleOptionsAssetBundle building options./param/// param nametargetPlatformTarget build platform./param/// returns/// paraThe manifest listing all AssetBundles included in this build./para/// /returnspublic static AssetBundleManifest BuildAssetBundles(string outputPath,AssetBundleBuild[] builds,BuildAssetBundleOptions assetBundleOptions,BuildTarget targetPlatform){BuildTargetGroup buildTargetGroup BuildPipeline.GetBuildTargetGroup(targetPlatform);return BuildPipeline.BuildAssetBundles(outputPath, builds, assetBundleOptions, buildTargetGroup, targetPlatform);}
打包之前的准备工作 一般ToB的小项目会有一些资源迭代的需求所以场景资源单独放到文件夹中管理每次有新的迭代时只对最新版本中的场景资源进行增量打包。 UI资源同样的道理但是小项目UI资源不需要分版本管理除非是企业级的项目需要热更或者需要版本管理则分版本管理。 下面是具体代码 打包的时候需要注意的事项打场景包一定不能压缩否则会加载不出来要使用BuildAssetBundleOptions.None。打其他资源的时候可以选择LZ4压缩BuildAssetBundleOptions.ChunkBasedCompression。LZ4压缩是LZMA和不压缩之间的折中方案构建的 AssetBundle 资源文件会略大于 LZMA 压缩但是在加载资源时不需要将所有的资源都加载下来所以速度会比 LZMA 快。建议项目中使用它。
using System;
using System.Collections.Generic;
using System.IO;
using NWH.Common.AssetInfo;
using UnityEditor;
using UnityEngine;
using Object UnityEngine.Object;namespace editor.AssetBundle
{public class BuildAssetBundle : Editor{/// summary/// 场景资源路径/// /summaryprivate static string _scenePath ${Application.dataPath}/AssetBundle/;/// summary/// UI资源路径/// /summaryprivate static string _uiPath ${Application.dataPath}/AssetBundle/Resources/;/// summary/// 最终场景包输出目录/// /summarypublic static string SceneOutPutPath ${Application.persistentDataPath}/assetbundle_orgin;/// summary/// 最终prefab包输出目录/// /summarypublic static string UiOutputPath ${Application.persistentDataPath}/assetbundle_uiorgin;[MenuItem(UnityTools/打包资源)]public static void BuildAssetsBundle(){BuildAllScenes();BuildAllPrefabs();//刷新文件AssetDatabase.Refresh();}private static void BuildAllScenes(){var directorys Directory.GetDirectories(_scenePath, V*);var folder directorys[directorys.Length - 1];//获取指定文件夹下所有的.unity文件var sceneFiles Directory.GetFiles(folder $/Scenes/, $*.unity,SearchOption.AllDirectories);for (int i 0; i sceneFiles.Length; i){//打包进度EditorUtility.DisplayProgressBar($正在打包场景中..., sceneFiles[i], 1.0f);if (!Directory.Exists(SceneOutPutPath)){Directory.CreateDirectory(SceneOutPutPath);}//批量打包所有的.unity文件 设置输出路径和输出windows平台AssetBundleBuild buildPacket new AssetBundleBuild();buildPacket.assetBundleName ${Path.GetFileNameWithoutExtension(sceneFiles[i]).ToLower()}.unity3d;buildPacket.assetNames new string[] { sceneFiles[i].Substring(sceneFiles[i].IndexOf(Assets/)) };var abManifest BuildPipeline.BuildAssetBundles(SceneOutPutPath,new AssetBundleBuild[]{buildPacket},BuildAssetBundleOptions.None,BuildTarget.StandaloneWindows64);}EditorUtility.ClearProgressBar();}private static void BuildAllPrefabs(){//获取指定文件夹下所有的.prefab文件var uiFiles Directory.GetFiles(_uiPath, $*.prefab,SearchOption.AllDirectories);if (!Directory.Exists(UiOutputPath)){Directory.CreateDirectory(UiOutputPath);}ListAssetBundleBuild buildInfoList new ListAssetBundleBuild();for (int i 0; i uiFiles.Length; i){//打包进度EditorUtility.DisplayProgressBar($正在打包预设中..., uiFiles[i], 1.0f);AssetBundleBuild buildInfo new AssetBundleBuild();buildInfo.assetBundleName ${Path.GetFileNameWithoutExtension(uiFiles[i]).ToLower()}.unity3d;buildInfo.assetNames new string[] { uiFiles[i].Substring(uiFiles[i].IndexOf(Assets/)) };buildInfoList.Add(buildInfo);AssetBundleManifest buildManifest BuildPipeline.BuildAssetBundles(UiOutputPath, buildInfoList.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);}EditorUtility.ClearProgressBar();}}
} 打包完成后输出的文件 2AB包的加载 加载场景和UI资源我使用的是同步加载需要用到异步加载或者网络加载的同学可以去看看其他的文章介绍。
AssetBundle.LoadFromFile 从磁盘上的文件同步加载 AssetBundle。该函数支持任意压缩类型的捆绑包。 如果是 lzma 压缩则将数据解压缩到内存。可以从磁盘直接读取未压缩和使用块压缩的捆绑包。
与 LoadFromFileAsync 相比该版本是同步的将等待 AssetBundle 对象创建完毕才返回。
这是加载 AssetBundle 的最快方法。
using System.Collections;
using System.Collections.Generic;
using UnityEditor.VersionControl;
using UnityEngine;
using utils;public class ABMgr : IMgrABMgr
{/// summary/// 包路径/// /summaryprivate string packagePath;/// summary/// ab包缓存/// /summaryprivate Dictionarystring, AssetBundle abCache;/// summary/// 主包/// /summaryprivate AssetBundle mainAB null;/// summary/// 主包中的配置文件----用来获取依赖包/// /summaryprivate AssetBundleManifest manifest null;protected override void Init(){base.Init();abCache new Dictionarystring, AssetBundle();packagePath ${Application.persistentDataPath}/assetbundle_uiorgin/;}private AssetBundle LoadABPackage(string abName){AssetBundle ab;if (mainAB null){mainAB AssetBundle.LoadFromFile(packagePath assetbundle_uiorgin);manifest mainAB.LoadAssetAssetBundleManifest(AssetBundleManifest);}var dependencies manifest.GetAllDependencies(abName);for (int i 0; i dependencies.Length; i){if (!abCache.ContainsKey(dependencies[i])){ab AssetBundle.LoadFromFile(packagePath dependencies[i]);abCache.Add(dependencies[i], ab);}}if (abCache.ContainsKey(abName)) return abCache[abName];else{ab AssetBundle.LoadFromFile(packagePath abName);abCache.Add(abName, ab);return ab;}}public T LoadResourcesT(string abName, string resName) where T : Object{AssetBundle ab LoadABPackage(abName);return ab.LoadAssetT(resName);}
}ab包加载单例基类
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace utils
{public class IMgrT : MonoBehaviour where T: IMgrT{private static T instance;public static T Instance{get{if (instance ! null) return instance;instance FindObjectOfTypeT();//防止脚本还未挂到物体上找不到的异常情况自行创建空物体挂上去if (instance null){new GameObject(IMgrTo typeof(T)).AddComponentT();}else instance.Init(); //保证Init只执行一次return instance;}}private void Awake(){instance this as T;Init();}protected virtual void Init(){}}
} 下面随便写一个例子看看加载出来的效果 // Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.Space)){OnLoadScene();}if (Input.GetKeyDown(KeyCode.A)){var go GameObject.Find(Canvas)?.gameObject;//加载资源var testui Instantiate(ABMgr.Instance.LoadResourcesGameObject(testui.unity3d, testui));if (testui ! null go ! null){testui.transform.SetParent(go.transform);testui.transform.localPosition Vector3.zero;testui.transform.localScale Vector3.one;}}}private void OnLoadScene(){var ab AssetBundle.LoadFromFile(${Application.persistentDataPath}/assetbundle_orgin/scene1.unity3d);Debug.LogError(ab.name);SceneManager.LoadScene(scene1, LoadSceneMode.Additive);}
3AB包的卸载 在AssetBundle的资源使用完成后需要对其进行卸载以释放其占用的内存空间。AssetBundle的卸载主要靠AssetBundle.Unload这个API实现。该方法需要传入一个bool类型的参数如果传入的是true则会卸载AssetBundle本身及从AssetBundle加载的全部资源。如果传入的是false则会保留已经加载的资源。 在大多数情况下都推荐使用AssetBundle.Unload(true)因为如果传入false会造成内存资源的浪费。
如果不得不使用AssetBundle.Unload(false)则只能用以下两种方式卸载单个对象
在场景和代码中消除对不需要的对象的所有引用。完成此操作后调用Resources.UnloadUnusedAssets。 以非附加方式加载场景。这样会销毁当前场景中的所有对象并自动调用Resources.UnloadUnusedAssets。
// 1.解除引用后调用
Resources.UnloadUnusedAssets();
// 2.上文提到的卸载ab所加载的所有asset
ab.Unload(true); 3、结语 这篇文章到这里就结束了主要是记录一下自己在项目中使用到的对场景和UI打AB包用法后续还会进行更深入的研究资源加密、解密、分类管理等等。希望这篇文章对你有帮助喜欢的朋友点个赞吧。谢谢。