UNITY 项目优化

1、CPU
1.1  DrawCall
1.1.1 什么是DrawCall
CPU与GPU并行工作,共同使用命令缓冲区。
CPU向缓冲区填充命令、GPU从其中取命令。DrawCall就是其中一种命令。
其他命令还有改变渲染状态等(例如改变使用的着色器,使用不同的纹理等)
1.1.2 为什么DrawCall多了会影响
在每次调用DrawCall之前,CPU会需要向GPU发送很多内容:数据、状态、命令等待。
这一阶段CPU需要完成很多工作:检查渲染状态等
GPU的渲染能力是很强的、因此选软速度往往快于CPU提交命令的速度。
如果DrawCall数量太多,CPU就会把大量的时间花费在提交DrawCall上,造成CPU过载


/*
如果创建1000个小文件,每个文件大小为1kb,然后把他们从一个文件夹复制到另一个文件夹,需要很长时间
如果创建1个10MB文件,把他从一个文件夹复制到另一个文件夹需要很少时间,
每一个复制动作需要很多额外的操作,分配动作,读写打开文件关闭文件,
如果文件过多会无限增加额外操作
*/
1.1.3 如何减少DrawCall,使用批处理batching
批处理 的2个物体的网络模型需要使用相同材质的目的在于其使用的纹理是相同的,
纹理打包成图集
1.1.3.1 静态批处理
物体不移动、拥有相同材质
在Inspector面板勾选Static 在运行游戏后可以查看 Batches 与 Saved by batching
1.1.3.2 动态批处理
引擎自动进行
动态批处理需要在每个顶点进行一定开销、所以动态批处理只支持小于900顶点的网格物体

如果Shader使用顶点位置、发现、uv值这三种属性,那么只能批处理300顶点一下的物体
如果Shader使用顶点位置、法线、uv0、uv1、和切向量,那么只能批处理180顶点一下的物体


不要使用缩放,缩放的两个物体不会使用批处理,统一缩放的物体不会与非统一缩放的物体进行批处理。
使用缩放尺度(1,1,1) 和 (1,2,1)的两个物体将不会进行批处理,
但是使用缩放尺度(1,2,1) 和(1,3,1)的两个物体将可以进行批处理。


使用不同材质的实例化物体(instance)将会导致批处理失败


拥有lightmap的物体含有额外的材质属性:lightmap的便宜和缩放系数等,所以拥有lightmap的物体将不会进行批处理


预制体的实例会自动的使用相同的网络模型和材质


使用Draw Call Batching,也就是描绘调用批处理。Unity在运行时可以将一些物体进行合并,从而用一个描绘调用来渲染他们。具体下面会介绍。
通过把纹理打包成图集来尽量减少材质的使用。
尽量少的使用反光啦,阴影啦之类的,因为那会使物体多次渲染。
尽量使用静态的批处理
1.2 物理组件
1.2.1 合适的 Fixed Timestep
Projectsetting -> Time -> Fixed Timestep
1.2.2 不使用网格碰撞器 应用原型碰撞器
1.3 处理内存 GC
GC可以释放内存,会加重CPU的负担
1.3.1 什么是GC
GC是Mono运行时的机制,不是游戏引擎的机制。
引用类型会被分配到托管堆上
1.3.2 GC什么时候触发
1、内存不足时自动调用GC
2、手动调用
1.3.3 GC注意事项
1、字符串连接处理。
两个字符串连接的过程是生成一个新的字符串,之前的字符串成为垃圾,会被GC当做垃圾回收
2、尽量不要使用foreach (Unity 使用C# Compiler的BUG)
foreach使用迭代器
每一次循环所产生的迭代器产生24Byte垃圾 (Unity 5.3.5p8已经修复)
3、不要直接访问gameobject的tag属性
go.tag == “test”
更改为 go.CompareTag("test")
4、使用对象池、杜绝大量重复创建
5、最好不用LINQ的命令,因为它们会分配临时的空间,同样也是GC收集的目标。而且我很讨厌LINQ的一点就是它有可能在某些情况下无法很好的进行AOT编译。比如“Ord erBy”会生成内部的泛型类“OrderedEnumerable”。这在AOT编译时是无法进行的,因为它只是在OrderBy的方法中才使用。所以如果你使用了OrderBy,那么在IOS 平台上也许会报错。(没用过。。不过这篇文章中提到了 http://blog.jobbole.com/84323/)
1.4 代码规范
1、经常使用组件用全局变量存储
Transform 的实验
GetComponent = 619ms
Monobehaviour = 60ms
CachedMB = 8ms && Manual Cache = 3ms 但是全局变量会占用内存
2、尽量使用内建数组
Vector3.zero 而不是 new Vector3(0, 0, 0)
3、方法参数优化 多使用ref
2、GPU
2.1 瓶颈
1、填充率,可以简单的理解为图形处理单元每秒渲染的像素数量
2、像素的复杂度:动态阴影、光照、复杂的Shader片段处理器
3、模型复杂度:顶点数量
4、GPU显存带宽
2.2 优化
2.2.1 减少绘制的数目
1、保证材质的数目尽可能的少,使Unity更容易进行批处理
2、使用纹理图集
3、如果使用了纹理图集和共享材质
使用Render.shaderdMaterial 来代替 Render.material
4、使用光照纹理(lightmap)而不是实时灯光
5、使用LOD
6、遮挡剔除:Occlusion culling
7、使用mobile的shader
2.2.2 优化显存带宽
1、压缩图片
2、使用mipmap
3、内存方面
3.1 内存资源
1、纹理、网格、音频、模型
2、Gameobject、组件
3、引擎内部逻辑需要内存: 渲染器、物理系统、粒子系统
3.2 Mono托管内存
值类型:int型啦,float型啦,结构体struct啦,bool啦之类的。它们都存放在堆栈上(注意额,不是堆所以不涉及GC)。
引用类型:其实可以狭义的理解为各种类的实例。比如游戏脚本中对游戏引擎各种控件的封装。
其实很好理解,C#中肯定要有对应的类去对应游戏引擎中的控件。
那么这部分就是C#中的封装。由于是在堆上分配,所以会涉及到GC。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值