当前位置: 首页 > news >正文

技术分享连载(二十四)

资源管理

Q1:字体作为多个资源的依赖包,会在游戏中被加载多次。我们现在有个问题,AssetBundle A资源依赖于这个字体,加载A的时候加载了一份字体,然后B资源也依赖这字体,而后加载B的时候我们没有去重复加载字体,这时候发现B资源上出现了字体丢失的现象。

请问加载资源的时候,Unity会自动去识别内存里是否有它的资源依赖包吗?如果有的话,为什么B加载的时候找不到已经存在内存中的字体?这里需要手动去做些什么处理吗?

同时我发现依赖包资源如果进行了bundle.m_AssetBundle.Unload(false)以后,其他依赖于这个包的资源就引用不到了。我们流程上对于每个读进来的AssetBundle,都会加载完后马上进行Unload(false),请问如果是依赖包的话,是不是不能对其进行这步操作?

Unity引擎是会自动根据依赖关系去搜寻依赖的资源的,但需要注意的是,依赖的AssetBundle文件必须存在。也就是说,依赖关系包如果后续还会使用的话,是不应该被Unload的,否则后续AssetBundle加载上来后,被依赖的资源是无法找到的。对于Unity 5.3之前的版本,出于内存的考虑,开发团队可以通过CreateFromFile或LoadFromCacheorDownload来加载AssetBundle,既可以保留AssetBundle之间的依赖关系,同时又不会产生Webstream。

开发团队可以参考你应该了解的AssetBundle管理机制,进一步了解相关API。


性能优化

Q2: 我在用Profiler真机查看iPhone App时,发现第一次打开某些UI时,Font.CacheFontForText占用时间超过2s,这块主要是由什么影响的?若iPhone5在这个接口消耗2s多,是不是问题很大?这个消耗和已经生成的RenderTexture的大小有关吗?

Font.CacheFontForText主要是指生成动态字体Font Texture的开销, 一次性打开UI界面中的文字越多,其开销越大。如果该项占用时间超过2s,那么确实是挺大的,这个消耗也与已经生成的Font Texture有关系。简单来说,它主要是看目前Font Texture中是否有地方可以容下接下来的文字,如果容不下才会进行一步扩大Font Texture,从而造成了性能开销。


资源管理

Q3:SkinnedMeshRenderer.BakeMesh这个函数一般是什么时候调用呢?在Instantiate后调用么?

SkinnedMeshRenderer.BakeMesh 的作用在于:将一个蒙皮动画的某个时间点上的动作,Bake成一个不带蒙皮的Mesh,从而可以通过自定义的采样间隔,将一段动画转成一组Mesh序列帧。而后在播放动画时只需选择最近的采样点(即一个Mesh)进行赋值即可,从而省去了骨骼更新与蒙皮计算的时间。

该方法的优点是用内存换计算时间,在场景中大量出现同一个带动画的模型时,效果会非常明显。该方法的缺点是内存的占用极大地受到模型顶点数、动画总时长及采样间隔的限制。因此,该方法只适用于顶点数较少,且动画总时长较短的模型。同时,Bake的时间较长,因此需要在加载场景时完成。

比较经典的适用场景为MOBA游戏中的小兵。


性能优化

Q4:我用Profiler.BeginSample统计到的数据与直接看Memory下的不一样,前者比后者的数据更大,这是为何? 用Profiler的API获取到的这一帧的内存消耗是85.6MB,而堆内存中显示的是62.9MB,这怎么理解?

Profiler.BeginSample
请输入图片描述

Profiler中数据
请输入图片描述

这种情况确实也是经常会遇到的。一帧中分配如此高的内存是会触发GC.Collect的,而Mono中显示的数值则是GC之后的Mono内存数值。


资源管理

Q5:将Shader独立打包,如果我在启动游戏的时候加载一次,那么之后切换场景是不是就不用每次都加载了?

确切地说,要达到后续Shader都不出现加载开销,需要满足以下两个条件:
(1)包含Shader的AssetBundle文件常驻内存;
(2)Shader已经全Load加载好;

只要满足这两个条件,后续加载好的GameObject,但凡依赖于这些Shader的,都会直接拿来进行使用,而不会再有加载和解析开销。





原文出处:侑虎科技
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

相关文章:

  • 序列化Serializable和Parcelable的理解和区别
  • vue-router的history模式发布配置
  • HTML-坦克大战-完成子弹连发功能(三)
  • ES6 之关键字 const
  • [转] 学会fetch的用法
  • Excel导入功能测试用例整理
  • DAY9-python并发之多进程
  • 常用特殊符号的HTML代码(HTML字符实体)
  • Java开发Tips
  • CUDA学习(十九)
  • export和import的用法总结
  • Picasso源码阅读笔记九
  • 《Python编程快速上手》第8.9.2实践练习
  • Intel发布P4500、P4600 NVMe SSD:规格释疑
  • Gradle:Gradle入门
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【知识碎片】第三方登录弹窗效果
  • iOS | NSProxy
  • JavaScript服务器推送技术之 WebSocket
  • java第三方包学习之lombok
  • JS题目及答案整理
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • SQLServer之创建显式事务
  • Terraform入门 - 1. 安装Terraform
  • uva 10370 Above Average
  • Vue实战(四)登录/注册页的实现
  • webpack4 一点通
  • 从0实现一个tiny react(三)生命周期
  • 简单数学运算程序(不定期更新)
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 学习使用ExpressJS 4.0中的新Router
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #{}和${}的区别?
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • #NOIP 2014#Day.2 T3 解方程
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (翻译)terry crowley: 写给程序员
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (已解决)什么是vue导航守卫
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .net framework4与其client profile版本的区别
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • /run/containerd/containerd.sock connect: connection refused
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • [ 蓝桥杯Web真题 ]-布局切换
  • [04] Android逐帧动画(一)
  • [AIGC] Spring Interceptor 拦截器详解
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务