Unity资源管理--AssetBundle学习

Unity资源目录

当用Unity创建一个工程的时候,目录如下:
在这里插入图片描述
Assets:存放Unity工程实际的资源目录。
Library:存放Unity处理完毕的资源,由unity自动转化生成。
Log:存放日志文件。
Packages:统一管理各种packages组件,使用PackageManager进行管理。
ProjectSettings:存放Unity的各种项目设定。

当进行项目迁移时,只需要将Assets、Packages以及ProjectSettings三个目录拷贝即可。

Unity提供了Resource加载和AssetBundle加载两种方式

引用这篇文章的内容 Unity资源管理(二)-Resources文件夹

强烈不建议使用Resources系统,原因如下:
使用Resources文件夹将会使细粒度的内存管理变得更难
对Resources文件夹的不恰当使用会导致应用程序构架和启动时间变长
随着Resources文件夹数量的增加,在这些文件夹中管理Asset将会变得越来越难
使用Resources系统会降低项目向不同平台提供定制内容的能立,并且导致项目无法进行增量内容更新

AssetBundle学习

AssetBundle 官方API文档

AssetBundles的压缩方式:LZMA、LZ4、不压缩

1. 加载AssetBundles

AssetBundle.LoadFromMemory(Async optional) // 不推荐,此API会消耗两倍于AB大小的内存
AssetBundle.LoadFromFile(Async optional) // 推荐使用
UnityWebRequest.GetAssetBundle // 在Unity 5.2及更早版本中使用 WWW.LoadFromCacheOrDownload

2. 从AssetBundles中加载Assets

LoadAsset(LoadAssetAsync) // 加载单个或者少量时使用
LoadAllAssets(LoadAllAssetsAsync) // 加载多数或者所有Assets时使用
LoadAssetWithSubAssets(LoadAssetWithSubAssetsAsync)

3. 构建AssetBundls管线

BuildPipeline.BuildAssetBundles

4. 卸载不使用的AssetBundls

AssetBundle.unload(true) // false会有引用丢失的风险

tips:开发一个良好的分离下载系统是至关重要的


自动打包至指定文件夹

  • 自动添加label
using UnityEngine;
using UnityEditor;
using System.IO;namespace ABFW
{public class AutoSetLabels{[MenuItem("AssetBundleTools/Set AB Label")]public static void SetABLable(){// 清空标记AssetDatabase.RemoveUnusedAssetBundleNames();// AB根目录 调用文件ABPath.cs统一获取路径string strNeedSetlabelRoot = ABPath.GetABResourcesPath();// 通过根路径获取目录DirectoryInfo dirTempInfo = new DirectoryInfo(strNeedSetlabelRoot);DirectoryInfo[] dirSceneDirArray = dirTempInfo.GetDirectories();// 遍历所有路径foreach (DirectoryInfo currentDIR in dirSceneDirArray){Debug.Log("输出目录所有" + currentDIR);string tmpScenesDIR = strNeedSetlabelRoot + "/" + currentDIR.Name;int tmpIndex = tmpScenesDIR.LastIndexOf("/");string tmpScenesName = tmpScenesDIR.Substring(tmpIndex + 1);JudgeDIRorFileByRecursive(currentDIR, tmpScenesName);}// 刷新列表AssetDatabase.Refresh();Debug.Log("-----------------AB初始化完成--------------------");}/// <summary>/// 递归判断是否为目录/文件,修改AssetBundle/// </summary>/// <param name="fileSysInfo">目录信息</param>/// <param name="scenesName">场景名称</param>private static void JudgeDIRorFileByRecursive(FileSystemInfo fileSysInfo, string scenesName){if (!fileSysInfo.Exists){Debug.Log("文件或者目录名称:" + fileSysInfo + "不存在,请检查");return;}DirectoryInfo dirInfoObj = fileSysInfo as DirectoryInfo;FileSystemInfo[] fileSysArray = dirInfoObj.GetFileSystemInfos();// 遍历文件 设置标签foreach (FileSystemInfo fileInfo in fileSysArray){FileInfo fileInfoObj = fileInfo as FileInfo;if (fileInfoObj != null){// 文件类型 设置lableSetFilesABLabel(fileInfoObj, scenesName);}else{// 目录文件 递归JudgeDIRorFileByRecursive(fileInfo, scenesName);}}}/// <summary>/// 设置AB标签/// </summary>/// <param name="fileInfoObj">文件信息</param>/// <param name="scenesName">场景名称</param>private static void SetFilesABLabel(FileInfo fileInfoObj, string scenesName){if (fileInfoObj.Extension == ".meta") return;// AB名string strABName = GetABName(fileInfoObj, scenesName);// 获取文件的相对路径,从Assets/开始int tmpIndex = fileInfoObj.FullName.IndexOf("Assets");string strAssetFilepath = fileInfoObj.FullName.Substring(tmpIndex);AssetImporter tmpImporterObj = AssetImporter.GetAtPath(strAssetFilepath);// 设置AB名tmpImporterObj.assetBundleName = strABName;// 根据拓展名设置AB后缀if (fileInfoObj.Extension == ".unity"){tmpImporterObj.assetBundleVariant = "u3d";} else{tmpImporterObj.assetBundleVariant = "ab";}}/// <summary>/// 获取AB包的名称/// </summary>/// <param name="fileInfoObj"></param>/// <param name="scenesName"></param>/// <returns></returns>private static string GetABName(FileInfo fileInfoObj, string scenesName){string tmpWinPath = fileInfoObj.FullName;string tmpUnityPath = tmpWinPath.Replace("\\", "/");// 场景名称后面的字符数int tmpSceneNameposition = tmpUnityPath.IndexOf(scenesName) + scenesName.Length;// 拓展名区域string strABFileNameArea = tmpUnityPath.Substring(tmpSceneNameposition + 1);string strABName;if (strABFileNameArea.Contains("/")){string[] tmpStrArray = strABFileNameArea.Split('/');strABName = scenesName + "/" + tmpStrArray[0];}else{strABName = scenesName + "/" + scenesName;}return strABName;}}
}
  • 根据label进行打包
using System.IO;
using UnityEditor;
using UnityEngine;namespace ABFW
{public class BuildAssetsBundle{[MenuItem("AssetBundleTools/Build All AB")]public static void BuildAllAB(){// 创建目录string strABOutPathDIR = ABPath.GetABOutPath();if (!Directory.Exists(strABOutPathDIR)){Directory.CreateDirectory(strABOutPathDIR);}// 调用内置API打包BuildPipeline.BuildAssetBundles(strABOutPathDIR, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);}}}
  • 删除所有的AB包
using System.IO;
using UnityEditor;
using UnityEngine;namespace ABFW
{public class DeleteAssetsBundle : MonoBehaviour{[MenuItem("AssetBundleTools/Delete All AB")]public static void DeleteAllBundle(){string strNeedDeleteDIR = ABPath.GetABOutPath();if (!string.IsNullOrEmpty(strNeedDeleteDIR)){Directory.Delete(strNeedDeleteDIR, true);File.Delete(strNeedDeleteDIR + ".meta ");AssetDatabase.Refresh();} else{Debug.LogError("无可删除的AB文件");}}}
}

生成MD5校验文件

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using ABFW;namespace HotUpdateModel
{public class CreateVerifyFiles{[MenuItem("AssetBundleTools/Create Verify Files")]public static void CreateFileMethod(){string abOutPath = ABPath.GetABOutPath();string verifyOutPath = abOutPath + "/ProjectVerifyFile.txt";List<string> fileList = new List<string>();if (File.Exists(verifyOutPath)){File.Delete(verifyOutPath);}ListFiles(new DirectoryInfo(abOutPath), ref fileList);WriteVerifyFile(verifyOutPath, fileList);}private static void ListFiles(FileSystemInfo fileSystemInfo, ref List<string> fileList){DirectoryInfo dirInfo = fileSystemInfo as DirectoryInfo;FileSystemInfo[] fileSysInfo = dirInfo.GetFileSystemInfos();foreach (FileSystemInfo item in fileSysInfo){FileInfo fileInfo = item as FileInfo;if (fileInfo != null){// 文件类型string strFileFullName = fileInfo.FullName.Replace("\\", "/");string fileExt = Path.GetExtension(strFileFullName);if (fileExt.EndsWith(".meta") || fileExt.EndsWith(".bak")){continue;}fileList.Add(strFileFullName);}else{// 目录类型,继续递归ListFiles(item, ref fileList);}}}/// <summary>/// 把文件名称+对应的MD5写入文件/// </summary>/// <param name="verifyFileOutPath">验证文件的路径</param>/// <param name="fileLists">所有合法文件的相对路径集合</param>private static void WriteVerifyFile(string verifyFileOutPath, List<string> fileLists){Debug.Log("verifyFileOutPath" + verifyFileOutPath);using (FileStream fs = new FileStream(verifyFileOutPath, FileMode.CreateNew)){using (StreamWriter sw = new StreamWriter(fs)){for (int i = 0; i < fileLists.Count; i++){string strFile = fileLists[i];string strFileMD5 = Helps.GetMD5Value(strFile);string strTrueFileName = strFile.Replace(ABPath.GetABOutPath() + "/", string.Empty);sw.WriteLine(strTrueFileName + "|" + strFileMD5);}}}AssetDatabase.Refresh();}}
}

拷贝Lua脚本至指定文件夹

using UnityEngine;
using UnityEditor;
using System.IO;
using ABFW;public class CopyLuaFileToStreamAssets
{private static string _LuaIRPath = Application.dataPath + "/" + ABPath.LUA_RESOURCE_PATH;private static string _CopyTargetIR = ABPath.GetABOutPath() + "/" + ABPath.LUA_DEPLOY_PATH;[MenuItem("AssetBundleTools/Copy LuaFile To StreamAssets")]public static void CopyLuaTo(){DirectoryInfo dirInfo = new DirectoryInfo(_LuaIRPath);FileInfo[] files = dirInfo.GetFiles();if (!Directory.Exists(_CopyTargetIR)){Directory.CreateDirectory(_CopyTargetIR);}// 逐个拷贝foreach (FileInfo infoObj in files){File.Copy(infoObj.FullName, _CopyTargetIR + "/" + infoObj.Name, true);}Debug.Log("---------拷贝完成,Lua文件已拷贝至发布区--------");AssetDatabase.Refresh();}
}

贴一个工具 游戏/VR应用性能诊断与优化 UWA框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[读书笔记] 设计模式与游戏完美开发

最近在看《设计模式与游戏完美开发》&#xff0c;文章将记录一些要点和一些设计模式实现 GoF定义的23种设计模式及应用场景 系统设计可以采用的设计模式&#xff1a;单例、状态&#xff08;场景切换&#xff09;、外观&#xff08;保证高内聚&#xff09;、中介者&#xff08…

iOS开发——GPUImage源码解析

一、基本概念 GPUImage&#xff1a;一个开源的、基于openGL的图片或视频的处理框架&#xff0c;其本身内置了多达120多种常见的滤镜效果&#xff0c;并且支持照相机和摄像机的实时滤镜&#xff0c;并且能够自定义图像滤镜。同时也很方便在原有基础上加入自己的滤镜Filter&#…

[读书笔记] 敏捷软件开发:原则、模式与实践

关于面向对象编程的一些理解&#xff0c;这本书主要看六大原则的部分&#xff0c;书中关于设计模式的内容由于之前的那本《设计模式与游戏完美开发》已经很好的讲解了游戏开发领域的应用&#xff0c;所以不多关注。 面向对象的六大原则 单一职责原则SRP&#xff1a;一个类应该…

Caffe-SSD相关源码说明和调试记录

1 对Blob的理解及其操作&#xff1a; Blob是一个四维的数组。维度从高到低分别是: (num_&#xff0c;channels_&#xff0c;height_&#xff0c;width_) 对于图像数据来说就是&#xff1a;图片个数&#xff0c;彩色通道个数&#xff0c;宽&#xff0c;高 Blob中数据是row-…

[游戏策划] 读书笔记

交互式媒体最有趣的地方在于&#xff0c;它让玩家直面问题&#xff0c;思考、尝试各种解决方案&#xff0c;并体验各种解决方案的结果。然后玩家可以回到思考阶段&#xff0c;规划下一步行动。这种反复试错的过程中&#xff0c;玩家的脑海里就会构建出一个互动的世界。 [读书笔…

ECS框架学习

DOTS Unity DOTS是Unity官方基于ECS架构开发的一套包含Burst编辑器和JobSystem的技术栈&#xff0c;它旨在充分利用多核处理器的特点&#xff0c;充分发挥ECS的优势。 安装 Entities、Burst、Jobs、Hybrid Renderer&#xff08;必选&#xff0c;用于DOTS的渲染相关&#xf…

辅助排序和Mapreduce整体流程

一、辅助排序 需求&#xff1a;先有一个订单数据文件&#xff0c;包含了订单id、商品id、商品价格&#xff0c;要求将订单id正序&#xff0c;商品价格倒序&#xff0c;且生成结果文件个数为订单id的数量&#xff0c;每个结果文件中只要一条该订单最贵商品的数据。 思路&#xf…

[读书笔记] 史玉柱自述:我的营销心得

与下属的关系 从玩家角度设定目标 目标感的设计 论随机性 在前15分钟留住玩家 实际观察玩家对于游戏的翻译反应 好游戏是改出来的 注重细节 决策民主、责任人制度 论简单与复杂的关系 游戏经济中的投放与回收 避免进入降低压力的怪圈 创业初期的股份分配 单个行业…

记一次面试腾讯的奇葩经历

阅读本文大概需要 2.8 分钟。 作者&#xff1a;黄小斜 文章来源&#xff1a;微信公众号【程序员江湖】 ​ 上回说到&#xff0c;我腾讯面试出师不利&#xff0c;简历随即进入备胎池&#xff0c;不过没过多久&#xff0c;转机还是来了。 大概是一周之后&#xff0c;我的电话响起…

foot

码云链接&#xff1a;https://gitee.com/zyyyyyyyyyyy/codes/rcfdzmin4a82v975pl1ko47 效果图&#xff1a; 原网站截图&#xff1a; 源代码&#xff1a; <!DOCTYPE html><html><head><meta charset"UTF-8"><title></title><s…

Taro项目遇到的问题

1. https://taro-ui.aotu.io/#/docs/questions 请在Taro项目根目录找到 config/index.js 文件中的h5项&#xff0c;添加如下&#xff1a; h5: {...esnextModules: [taro-ui] } 2. 原则&#xff1a;少什么就装什么 少了 babel-plugin-transform-decorators-legacy &#xff0c;那…

严重: StandardServer.await: create[localhost:8005]

①看看任务管理器&#xff0c;是否打开了多个Tomcat程序 如果是&#xff0c;关闭其中一个 ②可能是端口冲突 1、将tomcat安装目录下的conf/server.xml中的8005端口号改为其它的端口号。&#xff08;不建议&#xff0c;因为会衍生出其他错误&#xff09; 2、将正在使用的8005端…

java里short,int,long,float,double范围及可写位数

一、取值范围 1、int二进制位数&#xff1a;32 包装类&#xff1a;java.lang.Integer最小值&#xff1a;Integer.MIN_VALUE -2147483648 &#xff08;-2的31次方&#xff09;最大值&#xff1a;Integer.MAX_VALUE 2147483647 &#xff08;2的31次方-1&#xff09;2、short 二…

第六周编程总结

6-1 求两数平方根之和 &#xff08;10 分) 函数fun的功能是&#xff1a;求两数平方根之和&#xff0c;作为函数值返回。例如&#xff1a;输入12和20&#xff0c;输出结果是&#xff1a;y 7.936238。 函数接口定义&#xff1a; double fun (double a, double b); 其中 a和 b是用…

【CH5105】Cookies

也是一道线型动态规划的好题…… 读入每个人的贪婪度之后&#xff0c;对其按照从大到小的顺序排序&#xff0c;定义状态f[i][j]为前i个人&#xff08;排序后&#xff09;分j个饼干的答案&#xff0c;那么答案为f[n][m],考虑状态转移方程。 1、若给第i个人的饼干数大于1 &#x…

sharing-jdbc实现读写分离及分库分表

需求&#xff1a; 分库&#xff1a;按业务线business_id将不同业务线的订单存储在不同的数据库上&#xff1b; 分表&#xff1a;按user_id字段将不同用户的订单存储在不同的表上&#xff0c;为方便直接用非分片字段order_id查询&#xff0c;可使用基因法&#xff1b; 读写分离&…

性能测试学习05_lr(根据接口文档写脚本+参数化)

1、根据接口文档写脚本&#xff0c;函数&#xff08;web_custom_request&#xff09;&#xff0c;完成get&#xff0c;post请求&#xff08;注册&#xff0c;登录&#xff09; 代码&#xff1a; Action() {lr_save_string("请填写你的IP", "IP");//注册/*w…

java 历届试题 合根植物

问题描述w星球的一个种植园&#xff0c;被分成 m * n 个小格子&#xff08;东西方向m行&#xff0c;南北方向n列&#xff09;。每个格子里种了一株合根植物。这种植物有个特点&#xff0c;它的根可能会沿着南北或东西方向伸展&#xff0c;从而与另一个格子的植物合成为一体。如…

(软件项目管理)项目会议纪要模板

备注&#xff1a; 七: 1、报送&#xff1a;把整理好的会议的内容报给上级的相关部门。2、主送&#xff1a;把整理好的会议的内容发放给下级相关部门。3、抄送&#xff1a;把整理好的会议的内容送给相关的同级单位或不相隶属的单位。