位置: 编程技术 - 正文

Unity中的资源加载方法(unity资源库)

发布时间:2024-02-27

推荐整理分享Unity中的资源加载方法(unity资源库),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:unity怎么把资源导入到场景中,unity中资源包扩展名为,unity的资源怎么用,unity资源库,unity资源库,unity资源文件,unity资源库,unity资源库,内容如对您有帮助,希望把文章链接给更多的朋友!

Unity 3D里有两种动态加载机制:

一是Resources.Load;

一是通过AssetBundle;

其实两者本质上没有什么区别。Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的。其实场景里所有静态的对象也有这么一个加载过程,只是Unity后台替你自动完成了。

1. AssetBundles是什么?

在一些大型的网络游戏,或者加载比较多的一些场景时,如果要等待所有模型,贴图等各种资源文件加载完毕才能执行游戏,对用户将会是一个很头大的事情。所以就需要用到动态加载,即AssetBundles。比如玩家在进入游戏时先加载一些周围的场景文件,这样不仅可以提高速度还可以减少内存资源的消耗。

AssetBundles是可以把unity3d中你所创建的文件或任何资源导出的一种文件&#;式,这些文件导出后使用的是一种特定的文件&#;式(.Unity3d),这些特定&#;式的文件能在需要的时候加载到场景中。而这些特定的文件&#;式可以是模型,贴图,声音文件甚至是场景文件,它们是先前就被设计好的文件,所以很容易就可以被下载到你所建立的游戏或场景中来

AssetBundles 可以是任意类型的文件只要是unity3d能识别的资源文件&#;式,识别主要是以文件扩展名为准,比如.prefab等等。当然如果你想包含自定义的二进制文件,需要命名这些文件为以".bytes"为后缀,Unity将会把这些文件导成TextAssets。

2. Creating AssetBundles 创建资源包

有三个类方法可以用来构建资源包:

BuildPipeline.BuildAssetBundle,

BuildPipeline.BuildStreamedSceneAssetBundle

BuildPipeline.BuildAssetBundleExplicitAssetNames.

BuildPipeline.BuildAssetBundle allows you to build AssetBundles of any type of asset. 可以构建任意类型资源的资源包。【创建一个压缩好的包含Assets下的所有资源文件.unity3d。可以包含是项目目录下的任意资源,而把所有的资源压缩成一个.unity3d的文件,这个文件包括所有的预置物体(prefabs),纹理贴图(textures),模型,动画。使用AssetBundle.mainAsset这个函数可以很方便的让你指定一个定义好的物体。被压缩的资源储存在pathName. Options,会自动的允许用户包含相关的或者需要用到的】BuildPipeline.BuildStreamedSceneAssetBundle is used when you want to include only scenes to be streamed and loaded as the data becomes available. 用来当你希望只包括流场景,使数据加载变为可用。【建立一个或多个场景,这些场景所需要的所有资源将被压缩入资源包,即asset bundle里面。资源包中的场景文件可以在任何平台上建立,而且这些文件往往是以一个单一的unity3d文件&#;式被用来创建。使用WWW类可以下载场景文件。当场景文件被下载好可以使用WWW.LoadFromCacheOrDownload来加载下载好的场景文件。】BuildPipeline.BuildAssetBundleExplicitAssetNames is the same as BuildPipeline.BuildAssetBundle but has an extra parameter to specify a custom string identifier (name) for each object. 和BuildPipeline.BuildAssetBundle类&#;,但是有额外的参数来指定每个物体的自定义的字符串(名字)。【建立一个自定义名字的资源包方法:创建一个包含所有资源的一个压缩好的unity3d文件。AssetBundle可以包括任何项目目录下的资源文件。在assetNames参数中提供一个与资源数目相同大小的字符串数组。在资源数组中存储的信息与资源文件名相同,可以传递AssetBundle.Load去加载一个指定的资源。使用BuildAssetBundle时,只需使用资源的路径名。压缩好的资源包文件将会被储存在pathName. Options,允许用户自动包含与之相关的或者总是包含完整的资源去代替确切的参照物体。】

当使用上面的三个函数做完准备工作,我们现在就需要去下载这些资源然后加载它们。

3. Downloading AssetBundles 下载资源包

推荐使用WWW.LoadFromCacheOrDownload方法用来下载资源。当下载完成你就可以重新得到该资源的相关属性,例如:

4. Loading and unloading objects from an AssetBundle从资源包加载和卸载对象

下载完以后,等于把硬盘或者网络的一个文件读到内存一个区域,这时候只是个AssetBundle内存镜像数据块,还没有Assets的概念。就可以使用这三个不同的函数来加载物体了:

AssetBundle.Load

AssetBundle.LoadAsync

AssetBundle.LoadAll

AssetBundle.Load会加载物体,使用该物体的名字作为识别的参数。名字可以在Unity3d中Project view看到。你可以自由选择去传递对象变量的类型来确认该加载对象是否是被指定的类型。AssetBundle.LoadAsync 与AssetBundle.Load 函数相类&#;,但是当资源加载时它不会阻碍主线程。如果同时要加载比较大的资源或者很多资源时,这个函数会比较有用,它可以避免程序的暂停,因为它会同步加载。AssetBundle.LoadAll 顾名思义这个函数是用来加载所有在你资源包中的对象。作为AssetBundle.Load这个函数,你可以随意用该对象的类型去过滤。

使用AssetBundle.Unload这个函数可以卸载加载好的资源,这个函数有一个布尔&#;的参数是用来告诉Unity是否要卸载所有的数据(包含加载的资源对象)或者只是已经下载过的被压缩好的资源数据。如果要在资源包中从你的应用程序要使用一些对象或者你想释放一些内存,可以传递false这个&#;来卸载已经压缩好了的文件从你的内存中(即.unity3d文件)。如果要完全卸载所有的资源数据,需要传递true这个&#;,这将会销毁所有的资源包器中加载的资源。

AssetBundle.Unload(flase)是释放AssetBundle文件的内存镜像,不包含Load创建的Asset内存对象。

AssetBundle.Unload(true)是释放那个AssetBundle文件内存镜像和并销毁所有用Load创建的Asset内存对象。

5. Instantiating objects from AssetBundles 从资源包实例化物体

下载了资源,也加载好了,那么就该在场景中使用Instantiate函数去实例化它了。

Instantiate一个Prefab,是一个对Assets进行Clone(复制)&#;引用结合的过程,GameObject transform 是Clone是新生成的。其他mesh / texture / material / shader 等,这其中些是纯引用的关系的,包括:Texture和TerrainData,还有引用和复制同时存在的,包括:Mesh/material/PhysicMaterial。引用的Asset对象不会被复制,只是一个简单的指针指向已经Load的Asset对象。

Unity里每个Script都是一个封闭的Class定义而已,并没有写调用代码,光Class的定义脚本是不会工作的。其实Unity引擎就是那个调用代码,Clone一个script asset等于new一个class实例,实例才会完成工作。把他挂到Unity主线程的调用链里去,Class实例里的OnUpdate OnStart等才会被执行。多个物体挂同一个脚本,其实就是在多个物体上挂了那个脚本类的多个实例而已,这样就好理解了。在new class这个过程中,数据区是复制的,代码区是共享的,算是一种特殊的复制&#;引用关系。

当你Destroy一个实例时,只是释放那些Clone对象,并不会释放引用对象和Clone的数据源对象,Destroy并不知道是否还有别的object在引用那些对象。等到没有任何游戏场景物体在用这些Assets以后,这些assets就成了没有引用的游离数据块了,是UnusedAssets了,这时候就可以通过Resources.UnloadUnusedAssets来释放,Destroy不能完成这个任务,AssetBundle.Unload(false)也不行,AssetBundle.Unload(true)可以但不安全,除非你很清楚没有任何对象在用这些Assets了。

Unity不提供自动的一个可以取回所有被下载资源的列表。所以需要我们在脚本中要建立这些资源对象的信息和它们的路径以便我们去查找。

6. Including scripts in AssetBundles 在资源包中包含脚本

资源包可以作为TextAssets包含脚本但是不会实际执行代码。如果想要在资源包包含用来执行应用程序的代码,需要预先编译,然后使用Mono Reflection class来加载(注意:Reflection在iOS平台不可用)。可以在任何版本的C#IDE编辑器(如:Monodevelop, Visual Studio)或者使用mono/.net 文档编辑器。

Unity中的资源加载方法(unity资源库)

一个常见的错误:

从某个AssetBundle里Load了一个prefab并克隆之:obj = Instantiate (AssetBundle1.Load('MyPrefab”);

这个prefab比如是个npc,然后你不需要他的时候你用了:Destroy(obj);你以为就释放干净了。其实这时候只是释放了Clone对象,通过Load加载的所有引用、非引用Assets对象全都静静静的躺在内存里。这种情况应该在Destroy以后用:AssetBundle1.Unload(true),彻底释放干净。如果这个AssetBundle1是要反复读取的 不方便Unload,那可以在Destroy以后用:Resources.UnloadUnusedAssets()把所有和这个npc有关的Asset都销毁。

当然如果这个NPC也是要频繁创建 销毁的那就应该让那些Assets呆在内存里以加速游戏体验。由此可以解释另一个之前有人提过的话题:为什么第一次Instantiate一个Prefab的时候都会卡一下,因为在你第一次Instantiate之前,相应的Asset对象还没有被创建,要加载系统内置的AssetBundle并创建Assets,第一次以后你虽然Destroy了,但Prefab的Assets对象都还在内存里,所以就很快了。

资源加载和释放例子:

从磁盘读取一个1.unity3d文件到内存并建立一个AssetBundle1对象

AssetBundle AssetBundle1 = AssetBundle.CreateFromFile("1.unity3d");

从AssetBundle1里读取并创建一个Texture Asset,把obj1的主贴图指向它

obj1.renderer.material.mainTexture = AssetBundle1.Load("wall") as Texture;

把obj2的主贴图也指向同一个Texture Asset

obj2.renderer.material.mainTexture =obj1.renderer.material.mainTexture;

Texture是引用对象,永远不会有自动复制的情况出现(除非你真需要,用代码自己实现copy),只会是创建和添加引用

继续:

AssetBundle1.Unload(true) 那obj1和obj2都变成黑的了,因为指向的Texture Asset没了

如果:

AssetBundle1.Unload(false) 那obj1和obj2不变,只是AssetBundle1的内存镜像释放了

继续:

Destroy(obj1),//obj1被释放,但并不会释放刚才Load的Texture

如果这时候:

Resources.UnloadUnusedAssets();

不会有任何内存释放 因为Texture asset还被obj2用着

如果:

Destroy(obj2)

obj2被释放,但也不会释放刚才Load的Texture

继续:

Resources.UnloadUnusedAssets();

这时候刚才load的Texture Asset释放了,因为没有任何引用了

最后CG.Collect();

强制立即释放内存。

如何加载一堆大图片轮流显示又不爆掉?

不考虑AssetBundle,直接用www读图片文件的话等于是直接创建了一个Texture Asset。

Unity5.0更新列表 Unity5.0isourbiggestandboldestreleaseever.PowerfulnewfeaturesinUnity5include:ThePhysically-basedStandardShadertomakeyourmaterialslookconsistentinanylightingenvironment,crossplatform.Real-timeGlobalIll

手游开发攻防——二、基础篇

Unity读取点云数据 在Unity商店找到一个免费插件PointCloudFreeViewer可以加载xyz、xyzrgba式的点云数据。收费版PointCloudViewerandTools

标签: unity资源库

本文链接地址:https://www.jiuchutong.com/biancheng/381485.html 转载请保留说明!

上一篇:“Unity”已拥有为“CommonServiceLocator”定义的依赖项。(unity已存在)

下一篇:Unity5.0更新列表(unity5.4.0)

  • 应纳税所得额100万以内,税负2.5%是什么意思
  • 商场购物卡的会员怎么用
  • 销售返利可以计入销售费用吗
  • 现金流量表年报中的上年金额是什么
  • 固定资产后续支出资本化条件是什么
  • 机动车发票申请流程
  • 会计凭证的内容中应包括会计分录
  • 商家促销怎么做
  • 残疾人就业保障金怎么计算
  • 自查补缴的企业怎么处理
  • 汽车折旧年份
  • 小规模增值税普通发票税率
  • 专家评审费如何报销费用
  • 物业管理提供的服务变化
  • 医疗器械技术服务合同
  • 所得税费用税率规定
  • 普通发票费用会计分录
  • 办公室设计费取费标准一览表
  • 固定资产小于500万一次性扣除政策
  • 小规模纳税人废品站卖废品发票开什么项目
  • 商业土地厂房办公房过户需要交什么税?
  • 支付应付账款的会计科目
  • 用友软件以前年度损益调整报表勾稽关系不对
  • 免抵退系统应调整免抵退额吗?
  • 1697510302
  • 合伙企业合伙人工资的账务处理
  • mac电脑command键快捷设置
  • 开具红字发票后如何在申报表中填写?
  • 优先股的发行主体
  • 分公司是小微企业总公司是一般纳税人,如何做合并报表
  • 一次性工伤医疗补偿金怎么算
  • 财务费用属于期间汇转账户吗
  • 企业所得税税款
  • 境外汇款所得税缴纳规定
  • 保险税前扣除比例是多少
  • 皮肤痒怎么回事
  • 员工内部罚款有没有上限和下限
  • 职工住院的护理费标准
  • 劳务所得税怎么计算公式
  • 分期收款销售账务处理及税务处理
  • 康沃尔郡的大学
  • 可视化大屏的几种模式
  • php的hashtable
  • 关于古老的jsp页面的知识汇总(超详细)
  • 什么是CHATGPT
  • 小程序设计制作
  • mysqlbinlog -vvv
  • index.php备份文件
  • 小规模纳税人收入超过500万怎么办
  • 契税计税依据是否包含耕地占用税
  • 视同销售的会计处理是指?
  • sql中循环语句怎么写
  • 自产产品用于职工福利
  • 小规模免税收入怎么做账
  • 土地增值税纳税申报期限
  • 外贸企业账务处理流程举例讲解
  • 本票汇票支票的区别表格
  • 员工报销的话费要缴纳个税吗?
  • 计提个人经营所得税怎么算
  • 年度所得税汇算清缴报告在哪打印
  • 增值税为负值时当年可抵扣的进项税
  • 可转债不卖会亏钱吗
  • 长期应收款是否计提坏账准备
  • 工程预算费用怎么做会计分录
  • 在建工程不做了发生的费用如何做账?
  • 清空数据库中所有表的数据
  • win10开机出现onekey ghost
  • 卡巴斯基2019
  • 电脑bios怎么分区
  • xp蓝屏事件
  • centos6.5配置ssh
  • Windows RT 8.1 Update3(KB3033055)开始菜单多图欣赏
  • win8休眠如何唤醒
  • win10系统右键菜单管理
  • linux ii
  • 从零基础到入门
  • ubuntu nfs配置
  • nodejs-websocket
  • 吉林省电子税务局操作手册
  • 农副产品批发价
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号