Unity底层资源加载机制和资源打包原理

news/2025/2/19 15:20:52/文章来源:https://www.cnblogs.com/chenxiayun/p/18717732

Unity的资源加载机制分为同步加载和异步加载两种方式。

同步加载

同步加载是在游戏运行时,资源直接从磁盘加载到内存中,直到加载完成才继续执行其他操作。可用的接口,例如Resources.Load()或者AssetBundle.LoadAsset()。

  • 优点:简单易用
  • 缺点:会阻塞主线程,导致卡顿

异步加载

异步加载则是在后台线程加载资源,同时不会阻塞主线程,通常使用 Resources.LoadAsync() 或 AssetBundle.LoadAssetAsync() 来进行异步加载。加载过程中可以通过回调函数进行监控和处理。

  • 优点:不阻塞主线程,避免卡顿
  • 缺点:需要我们严格注意加载的过程和资源的释放

资源打包原理

Unity的资源打包机制主要通过AssetBundle来实现,在2018年,Unity引入了Addressable,作为对AssetBundle的封装,它实现了自动化管理资源依赖,简化了资源管理的过程,不过这里不对Addresable做讨论。

AssetBundle

AssetBundle是Unity的传统资源打包方式,可以将多个资源打包到一个文件中,从而减少内存占用和提高资源加载速度。使用时,可以从本地或者远程加载AssetBundle文件。

打包策略

  1. 避免重复打包
    例如:避免在多个AssetBundle中重复打包相同的资源。重复的资源会增加内存占用和加载时间。比如多个预制体共享同一个纹理资源,可以将这个纹理打成一个专门的AssetBundle,进行资源共享。
  2. 使用多个AssetBundle文件,进行依赖管理
    例如:可以将一个大资源拆分成不同的AssetBundle文件,减少每次加载的资源量,做到按需加载。
  3. 选择合适的压缩策略
    例如:LZ4压缩,解压速度快,适合需要快速加载的场景资源;LZMA压缩,压缩比高,适合大文件的资源包,虽然解压慢;无压缩,适用于不在乎压缩时间但需要减少CPU负担的情况。
  4. 避免不合理的资源拆分
    例如:将所有资源都拆分为极小的AssetBundle,可能会导致加载时频繁的文件I/O操作,影响性能。但是把大量无关的资源放入同一个包,也会导致内存问题。
  5. 避免依赖循环
    依赖循环是指资源之前的互相依赖,导致加载出现死锁问题。所以要保证资源的依赖是线性的,不能是环形。

AssetBundle的生命周期

  • 加载AssetBundle:通过AssetBundle.LoadFromFile()或者AssetBundle.LoadFromMemory()来加载资源包。
  • 加载资源:通过AssetBundle.LoadAsset()或AssetBundle.LoadAllAssets()加载资源。
  • 使用资源:资源加载完成后,供场景、游戏逻辑等使用。
  • 卸载资源:资源不在使用后,即可卸载。
  • 卸载AssetBundle:释放整个AssetBundle资源。

在Unity中,调用AssetBundle.Unload()会卸载AssetBundle,并释放其中所有的资源。如果资源还在使用中,调用Unload()不会立即释放内存,直到资源被完全卸载。

AssetBundle.Unload()有2个版本:

  • AssetBundle.Unload(false):只卸载AssetBundle本身,但不卸载其中的资源。这意味着已经加载的资源会继续在内存中保留,直到它们被显式卸载。
  • AssetBundle.Unload(true):卸载AssetBundle并同时卸载其中的所有资源。如果资源不再使用,这个选项会释放内存。

所以,在卸载的时候,有个要注意的点是,当资源加载后,不再使用却仍然占据内存的情况下,会出现内存泄漏的问题。当然我们也有解决方法:

  1. 即在资源管理中加入对资源的引用计数,当资源不再使用时能够及时的卸载。
  2. 调用Resources.UnloadUnusedAssets(),它会检查所有未被引用的资源并将它们卸载。不过这个方法会造成卡顿,不宜频繁使用。

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

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

相关文章

容器

容器 mapfirst:代表键 second:代表值 遍历也可以使用迭代器来访问插入删除(erase)===> 返回删除元素的数量查找功能findupper_bound(返回的迭代器是指向键值大于所给定值的第一个元素) 找到所有价格小于等于 6.8 的商品lower_bound(返回的迭代器是指向键值不小于所给…

【Atcoder训练记录】AtCoder Beginner Contest 393

训练情况忙着处理训练数据,赛后打的,没有排名 赛后反思 这场太典了,感觉我能力范围内都是一眼题,剩下的真不会了 A题 显然有问题的就是 sick或fine补集,对应的交集,如果交集为空答案就是 4,我们直接大力分类讨论,fine fine是 4,sick fine是 2,fine sick是 3,sick si…

C#的GC垃圾回收

空间分配 在讨论垃圾回收之前,需要明白一个重要的事情,空间是怎么被分配出去的。在进程初始化时,CLR会保留一块连续的地址空间(托管堆),托管堆中维护着一个指针,称之为NextObjPtr,它指向下一个对象在堆中的分配位置。当我们在C#中调用new关键字的时候,编译器会自动生成…

ConcurrentHashMap(JDK1.8)put分析

一、ConcurrentHashMap整体结构 ConcurrentHashMap的数据结构与HashMap差不多,都是Node数组+红黑树+链表;ConcurrentHashMap中table的节点类型有 3 类:Node节点,是链表类型的节点;这类节点hash 大于 0 ;在扩容时ConcurrentHashMap会有一个特殊的标志对象:ForwardingNode…

如何接入sbus航模遥控器?

买了航模遥控器不会用sbus?快来快来我来教你呀(滑稽如何接入sbus航模遥控器? 最近队内大疆的遥控器短缺,故自行购买一款便宜好用的遥控器来替代,但是协议与dbus不同,研究了一阵子,所以诞生了这一篇文章来帮助大家少走弯路。 遥控器构成 一般都有发射端和接收端:发射端为…

2/15图论浅讲(知识点)

2/15图论浅讲(知识点) (后期会转移博客,所以排版不太好) 前置知识-vector 动态数组 操作1:创建一个动态数组 vector<数据类型> 数组名字操作2:插入元素 O(logn) 方式1:q.push_back(数据);在数组最后面塞数据 方式2:q.insert(q.begin()+i,a);i为下标,将a数据插入…

char**指针与const

1,char**char c = 0;char* p1 = &c; //p1是一个指针变量, 存放的是char类型变量的地址 *p1 = 1; const char* p2 = &c; //p1是一个指针变量, 存放的是char类型变量的地址, const修饰*, 表示指针内容(*p2)不可变char** p3; //p3是一个指针变量, 存放的是char*类型变量的…

升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框架: Vue3+Spring Boot3) ,界面功能t升级(四 )

升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框架: Vue3+Spring Boot3) ,界面功能t升级(四 ) 工作台 系统 商品 客户 门店 订单

(自适应手机端)英文外贸网站模板 日用百货网站源码下载

(自适应手机端)英文外贸网站模板 日用百货网站源码下载 PbootCMS内核开发的网站模板,该模板适用于外贸网站模板、日用百货网站源码等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可; 自适应移动端,同一个后台,数据即时同步,简单适用!附带测试数据!友好…

Markdown 语法学习

Markdown 语法学习 标题: # + 三级标题 四级标题 字体 hello,world! hello,world! hello,world! hello,world! 引用选择狂神说Java>这是引用分割线图片超链接 博客园 - 开发者的网上家园) 列表A B CA B C表格名字 性别 生日张三 男 1997.1.1李斯 女 1995.7.6代码hello

一级倒立摆平衡控制系统MATLAB仿真,可显示倒立摆平衡动画,对比极点配置,线性二次型,PID,PI及PD五种算法

1.算法仿真效果 本课题是针对博主原来写的文章《基于MATLAB的一级倒立摆控制仿真,带GUI界面操作显示倒立摆动画,控制器控制输出》的升级。升级内容包括如下几个方面:增加了PI控制器,PD控制器,同时对极点配置,线性二次型,PID,PI及PD五种算法的控制输出曲线进行对比。matlab2…

使用Spring Initializr方式构建Spring Boot项目

按教材 下例选用IntelliJ IDEA 2024.3.3付费版 创建项目JDK版本根据实际情况。启动类简析 package com.example.demo; // 这段代码位于 com.example.demo 这个包下import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBo…