Unity技术支持团队经常会对有需求的客户公司项目进行游戏项目性能审查与优化,在我们碰到过的各种项目相关的问题中也有很多比较共同的方面,这里我们罗列了一些常见的问题并进行了归类,开发者朋友们可以参考下。

资源导入

<ignore_js_op>
  • 纹理没有压缩

在很多情况下,美术会觉得纹理压缩后效果不理想。我们建议的是:可以把原图的分辨率长宽都扩大一倍,保持原有压缩格式。这样压缩过后的文件还是比不压缩的文件要小,并且视觉效果可以得到较大的改善。

  • 纹理导入设置中的 Read/Write Enabled 处于勾选状态

开启纹理导入设置中 Read/Write Enabled,纹理在传到GPU之后,CPU端的数据也会一直保留在内存中。因为在移动端显存共享内存,会导致内存占用加倍。因此需要注意是否有需要在CPU端访问的纹理,比如:需要通过脚本获取纹理像素的情况下,就要开启纹理导入设置中的 Read/Write Enabled。

  • 模型文件导入设置中 Read/Write Enabled 处于勾选状态

除了需要脚本中访问的网格,作为网格碰撞器中的网格,脚本中用StaticBatchingUtility.Combine静态合批的网格,以及粒子系统发射的网格之外,其它模型建议不要勾选此项 ,否则会在内存也保留一份网格实例占用内存。

  • 模型导入设置[Rig]选项页中Optimize GameObject没有勾选

建议开启Optimize GameObject,这个选项可以把SceneManager中用于skinning的节点都去除,节省了场景节点树更新以及查询的CPU消耗,对于需要做挂点的节点可以添加到例外列表中。

  • 使用第三方音频插件时没有禁用Unity内置音频

不需要使用Unity内置音频模块的时候,建议Editor中通过勾选Edit->Project Settings->Audio->Disable Unity Audio来完全禁用FMOD模块,避免不必要的CPU消耗

CPU常见性能问题

<ignore_js_op>
  • 频繁调用的Camera.main

建议脚本做好Main Camera的Cache。Camera.main实际为GameObject.FindGameObjectsWithTag(“MainCamera”)调用,主要因为引擎无法得知用户通过脚本设置的MainCamera,CPU消耗较高。

  • 脚本中大量UnityEngine.Object的判等操作

建议改为用InstanceID来判断即Object. GetInstanceID,运行期间保证唯一。 因为Object的判等还有额外的耗时操作,而Int类型的判等就非常快速了。同理,使用Object作为key的数据结构也建议改用InstanceID做key。

  • 用于查询操作的数据使用list数据结构

List线性结构Contains的耗时非常高,建议改为hashset,hashtable之类的查询操作效率高的数据结构。

  • 加载资源时每帧从Assetbundle加载的Asset数量没有限制

在场景内每帧从Assetbundle加载的Asset数建议限制在2到5个,数量高时耗时过长容易造成卡顿。

内存常见问题

<ignore_js_op>
  • 加载场景的时候有 一段内存尖峰

常见的情况是有无索引的资源被加载进来,然后因为UnloadUnusedAssets被卸载掉。内存尖峰基本都是对游戏本身无用的内存,但是可能会因此造成游戏在内存紧张的机器上被强制关闭。

  • 静态索引导致的内存泄漏

一些内存占用较大的资源如纹理,因为有静态索引而无法在切换场景或者调用UnloadUnusedAssets时被卸载掉,因此内存的泄漏量会随着用户切换场景的次数而增加。

  • Mono内存池总大小与当前使用大小的差值较大

这个值越大说明有越多的不必要内存池扩展,比如说在同一帧内有加载大量资源,实例化大量对象等,可能让内存池瞬间膨胀的操作。

  • GC分配量较大

项目Review过程中,除了CPU时间占用和内存分配量,我们还会留意脚本函数的GC分配。GC分配越频繁,量越大,由于Mono内存池可用内存不足导致的GC.Collect(造成卡顿原因之一)调用就越频繁,并且可能引起mono内存池不必要的扩展,因此脚本函数的GC分配量是既影响CPU也影响内存的重要参数。对于GC分配量。

我们建议的参考数值为:
对于基本每帧都会分配GC的函数,GC分配量大于2KB的建议都确认下是否有可能把临时变量抽取出来。
对于偶尔分配GC的函数,GC分配量大于10KB的建议都确认下分配的数据结构是否有优化空间。

GPU常见性能问题

<ignore_js_op>
  • 特效渲染的Pass数量较多

一些特效的渲染可以合并到同一个Pass以节省GPU开销,另外RenderTexture在可以共用的情况下尽量共用

  • 同屏面数过多

同屏面数建议在20W以下,较优情况是控制在10W以内

  • UI元素在需要隐藏的时候使用了设置Alpha为0的方式

实际上GPU依然需要对UI mesh进行渲染,建议不要通过设置Alpha为0的方式来隐藏UI。

  • 当使用网格作为地形时,适当切分地形网格

在网格顶点数很高情况下需要依靠硬件裁剪来剔除顶点,比较消耗GPU性能,建议按照大概的同屏可见范围来切分地形网格。

  • UI元素过多依赖多层元素的混合来达到美术效果

这样会造成较多的Overdraw,建议尽量通过预制纹理来做到想要的效果。

Unity游戏项目常见性能问题的更多相关文章

  1. 用好lua+unity,让性能飞起来——关于《Unity项目常见Lua解决方案性能比较》的一些补充

    <Unity项目常见Lua解决方案性能比较>,这篇文章对比了现在主流几个lua+unity的方案 http://blog.uwa4d.com/archives/lua_perf.html ...

  2. 优化Unity游戏项目的脚本(下)

    金秋9月,我们祝所有的老师们:教师节快乐 ! 今天,我们继续分享来自捷克的开发工程师Ondřej Kofroň,分享C#脚本的一系列优化方法. 在优化Unity游戏项目的脚本(上)中,我们介绍了如何查 ...

  3. 用好lua+unity,让性能飞起来——luajit集成篇/平台相关篇

    luajit集成篇 大家都知道luajit比原生lua快,快在jit这三个字上. 但实际情况是,luajit的行为十分复杂.尤其jit并不是一个简单的把代码翻译成机器码的机制,背后有很多会影响性能的因 ...

  4. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  5. 常见性能优化策略的总结 good

    阅读目录 代码 数据库 缓存 异步 NoSQL JVM调优 多线程与分布式 度量系统(监控.报警.服务依赖管理) 案例一:商家与控制区关系的刷新job 案例二:POI缓存设计与实现 案例三:业务运营后 ...

  6. 优化Unity游戏项目的脚本(上)

    本文将由捷克独立游戏工作室Lonely Vertex的开发工程师Ondřej Kofroň,分享C#脚本的一系列优化方法,并提供改进Unity游戏性能的最佳实践. 在开发游戏时,我们遇到了游戏过程中偶 ...

  7. LINUX常见性能监控工具总结

    文章来源 工具功能概览 整理了一个关于监控工具及其功能的表.下面对这些工具单独详细介绍. Linux性能监控工具 top top命令会展示进程的实际活动.默认情况下,它会列出系统上所有cpu密集型任务 ...

  8. Javascript常见性能优化

    俗话说,时间就是生命,时间就是金钱,时间就是一切,人人都不想把时间白白浪费,一个网站,最重要的就是体验,而网站好不好最直观的感受就是这个网站打开速度快不快,卡不卡. 当打开一个购物网站卡出翔,慢的要死 ...

  9. ios 常见性能优化

    1. 用ARC管理内存 2. 在正确的地方使用reuseIdentifier 3. 尽可能使Views透明 4. 避免庞大的XIB 5. 不要block主线程 6. 在Image Views中调整图片 ...

随机推荐

  1. android studio中使用recyclerview小白篇(四)

    经过努力,我们的recyclerview终于可以使用了,但是装配上真实的数据后,发现左边的内容太长了,如果超过一行,左边内容和右边的内容竟然重叠在一起了,好是让人心塞啊,如下图 后来发现设置左边tex ...

  2. 以太坊系列之五: p2p的nat模块--以太坊源码学习

    p2p的nat模块 该模块相对比较简单,因为nat的真正实现并不在此模块,主要是使用了第三方的nat-upnp和nat-pmp来实现真正的穿透(端口映射). 对外公布的接口 ```go // An i ...

  3. linux------深入理解linux内核

    linux内核用到了很多数据结构,这些数据结构都是为了提高某些方面的效率. 内核分配给进程的虚拟地址空间由以下内存区组成: 程序的可执行代码 程序的初始化数据 程序的未初始化数据 初始程序栈(即用户态 ...

  4. C# 接口(2)

    接口的实现方式. 接口的实现分两种: 1 显示实现接口 2 实现接口. 我们前面所得的接口的实现均为实现接口.也就是第二种方式.那么我们来来看第第一种实现方式: interface IHuman { ...

  5. ios app提交之前需要哪几个证书

    1.遇到的问题 一款App在别人的机器上开发和发布,现在迭代更新和开发需要在一台新mac机上开发和发布. (使用同一个开发者账号)问题: 1.在新mac机器上开发并导入真机测试,是不是需要从别人的机器 ...

  6. [agc008f] Black Radius 树形dp

    Description ​ 给你一棵有NN个节点的树,节点编号为11到NN,所有边的长度都为11 ​ "全"对某些节点情有独钟,这些他喜欢的节点的信息会以一个长度为NN的字符串ss ...

  7. P3615 如厕计划

    $ \color{#0066ff}{ 题目描述 }$ 竞赛比完之后,水箱里充满水的选手们鱼贯而出.凡华中学的厕所规划的很糟,只有两个厕位,于是厕所门前排起了长长的队伍. 厕所有两个,一个是女生专用厕所 ...

  8. 关于NPOIExcel导出excel

    1.支持导出多个sheet文件 /// <summary> /// 导出到Excel并下载(html) /// </summary> /// <param name=&q ...

  9. vi vim 查找替换

    #查找# / 光标向下查找 ?光标向上查找 按键盘n,继续查找 #替换# :s/hello/test/ 替换光标所在行第一个hello为test :s/hello/test/g  替换光标所在行所有h ...

  10. POJ_3414 Pots 【复杂BFS】

    一.题面 You are given two pots, having the volume of A and B liters respectively. The following operati ...