Unity游戏中的一些规范和优化建议
一.代码规范和建议
避免Update LateUpdate等函数内频繁的GC Alloc,避免在Update和LateUpdate内有以下操作:
调用GetComponet()
调用FindObjectsOfType()
使用GameObject.Tag和GameObject.Name
等等其他有堆内存分配的操作
避免频繁调用ToString()分配内存
避免OnGUI的调用
禁止使用Debug.Log打印log,用框架中的LogManager统一管理
避免使用枚举或struct做key进行字典查找(除非使用定制的comparer)他们的GetHashCode都有装箱操作,每次调用TryGetValue查找都会有内存分配.
在使用协程时尽量复用WaitXXX对象,而不是每次分配
频繁创建和更新的字符串尽量缓存,比如CD时间等
尽量避免dict.Values操作,直接遍历取Values即可
使用CompareTag代替GameObject.Tag
用RayCastNoAlloc替换RayCastAll
用yield return null 代替 yield reture 0
如果文件中不需要Update或Start函数等,删掉对应的空函数
尽量少用lambda,创建带upvalue的lambda对象会产生124B的GC,禁止在Update或for循环中使用
使用数组的数组,而不是多维数组。如int[i][j]的数组的数代替int[i,j]的多维数组
尽可能避免使用携程
禁止使用接受字符串参数的GetComponent等类似函数的重载方法,使用泛型类型的
代码中需要访问到 Transform 组件的位置数据时, 尽可能使用 localPosition 代替对 position 属性的访问. localPosition存储在transform中,访问该值时,Unity会直接将其返回,而position在每次访问时都会重新计算,如果要经常获取position,可以将其缓存起来。
避免使用LINQ表达式,部分功能无法在某些平台上使用,会分配大量GC Alloc。
禁止高频的字符串拼接. 如无法避免, 必须使用 StringBuilder 代替 "+" 操作符进行字符串拼接.
Delegate 回调方法必须适时的解除注册, 否则回调方法所属的对象会一直有引用计数, 继而引起该对象所引用的资源无法得到释放.
尽量避免使用 Reflection(反射).
尽量避免使用可变参数(param object[] args), 避免装箱拆箱.
简单条件判断尽量使用三目运算符: b?x:y.
注意 List 等容器常用接口的复杂度, 尽量从尾部移除/批量移除(RemoveRange)等.
在频繁查询数据列表时, 建议使用 HashSet/HashTable 查找时间复杂度低的数据结构, 避免使用 List.
尽可能为快速产生和消灭的大量对象建立缓冲池.
尽可能将类或函数声明为 sealed, IL2CPP 会对 sealed 的类或函数进行优化, 变虚函数调用为直接函数调用.
尽量减少new的次数,预分配/成员变量替代临时new变量等.
最快的空串比较方法:最快的方法是str.Length == 0其次是str == String.Empty或str == "" 注:C#在编译时会将程序集中声明的所有字符串常量放到保留池中(intern pool),相同常量不会重复分配。(指的是这个"")
减少Find方法使用。Find()方法会遍历内存中的每个GameObject和组件,随着项目规模的扩张,它的开销将会越来越大。不要频繁的使用Find()和与其类似的方法,可以考虑在Inspector中设置对对象的引用,或者创建一个专门用于管理需要搜索的对象的引用的脚本。
避免使用Camera.main。 Camera.main 因此遭遇了和 Find() 一样的问题:在内存中搜索了所有的 GameObjects 和 Components,这个使用可能会消耗大。
尝试使用sqrMagnitude(即magnitude的平方)替代magnitude,减少开平方操作。
尽量少用模运算和除法运算,比如a/5f,要写成a*0.2f。
尽量避免在运行时为Transforms重新设置parent。Unity对于在同一个parent下的所有Transforms,内存排布是连续的类似动态数组,运行时重新设置parent可能会导致数组重新分配
变量和字段如果可以声明为const应该总是被声明为const,如果无法使用const,尝试使用readonly
二.其他规范和建议
禁止非图集贴图资源不合理的留白. 会影响 UGUI 运行时自动合批.
资源设置 UI 的贴图资源禁止勾选 Generate Mip Maps.
禁止使用修改 Alpha 值的方式来隐藏界面.
尽可能降低 Release 版中图集留白, 提高贴图利用率.
建议同一 Canvas 中使用到的图集数量控制在三个以内.
建立合理规划公共图集. 在内存占用/加载频度/引用复杂度之间确定合理的平衡点.
禁止匿名 GrabPass. 如需使用到 GrabPass 必须命名并尽可能复用.
Shader中尽可能减少多 Pass 渲染, 除非必须这么做.
尽可能降低 Release 版中 Shader 中的 Keyword 数量.
尽可能降低 SkinnedMeshRenderer 组件数量.
禁止逐帧直接使用名称对 Shader Uniform 量进行更新
尽量避免在 Shader 中使用复杂的计算如: pow/sin/cos/tan/log 等.
建议在 Shader 中采用预混合或实时混合纹理的方式代替实时地多次纹理采样
移动平台的 Shader 编码一定要考虑数据精度(float/half/fixed)的合理使用.
应尽可能减少每帧 Material.GetXX/Material.SetXX的次数, 比如把多个 uniform half 变量合并为 uniform half4.
尽可能避免将 Animator 的 Culling Mode 属性设置为 Always, 对于不使用 RootMotion 的项目建议选择 CullCompletely.
尽可能避免使用物理引擎. 建议自行编码模拟物理效果
使用物理模块的游戏, 建议在 PhysicsManager 中设置矩阵, 会有较大的性能提升
如使用第三方音频插件, 需禁用 FMOD 模块(Edit -> Project Settings -> Audio -> Disable -> UnityAudio).
若不需要立体音效, 音频导入设置需勾选 Force to Mono(注: 制作音频时就应该制作单通道的.)
音频格式: iOS平台一般使用 mp3, Android平台一般使用 ogg.
无需由逻辑代码访问的渲染资源禁止勾选 Read/Write Enabled, 如网格和图片.
导入蒙皮网格模型时建议勾选 Optimize GameObject 优化选项, 可极大地降低骨骼层次复杂度, 优化 CPU 性能.
无动作模型资源必须将 Animation Type 设置为 None, 否则会导致游戏对象挂在不必要的动画脚本, 大量的话会严重影响 CPU 性能.
导入的模型如果无需用到法线和切线, 必须将导入设置的 Normals 和 Tangents 选项设置为 None.
导入的模型如果无需参与Unity Lightmap 烘焙, 必须将导入设置的 Generate Lightmap UVs 选项设置为 None.
禁止在 Release 版中存在任何 OnGUI 相关代码
禁止在 Release 版中存在任何日常调试相关的 UnityEngine.DeBug 类日志输出
禁止在 Release 版中开启 "Development Build" 和 "Script Debugging" 选项
在发布时必须将游戏锁定至合适的帧率(建议 30/60 帧)
禁止在 Release 版中使用引擎提供的 SendMessage 方法.
Unity游戏中的一些规范和优化建议相关推荐
- Unity 3D中的内存管理与优化游戏运行性能的经验
Unity3D在内存占用上一直被人诟病,特别是对于面向移动设备的游戏开发,动辄内存占用飙上一两百兆,导致内存资源耗尽,从而被系统强退造成极差的体验.类似这种情况并不少见,但是绝大部分都是可以避免的.虽 ...
- unity游戏中的换装换色
游戏中经常遇到给角色换装染色的需求,通过换装换色可以使的资源不增加的基础上在本来的衣服套数翻倍,策划可在这上挖坑,废话不多说,进入正题 主要分为两部分 1.换装 一个角色每个需要更换的部位都是一个单独 ...
- unity游戏中提示信息如何实现_《游戏设计模式》(游戏编程模式)全书笔记+Unity实现...
Unity实现(Github地址): 笔记部分以下部分只包含笔记,具体实现及项目说明可查看Github 笔记中很多都是个人理解,目的是尽量让原本抽象的概念更易懂一些 关于书名--书名直译是<游戏 ...
- 利用OLAMI在unity游戏中加入中文语音控制(一)
(欢迎转载.本文源地址:http://blog.csdn.net/speeds3/article/details/76209152) 最近打算尝试一下OLAMI在游戏中应用的可能性,这里做一下记录. ...
- unity游戏中提示信息如何实现_RPG游戏中的剧情在Unity3D中如何实现呢?
原标题:RPG游戏中的剧情在Unity3D中如何实现呢? RPG游戏想必不用多介绍了,剧情系统是RPG游戏中必不可少的功能. 曾经听过一些朋友谈论:目前正在做一款RPG游戏,但是不知道如何实现RPG游 ...
- 在Unity游戏中使用Live2D
转载文章,原文链接地址 什么是Live2D Live2D是日本Cybernoids公司开发. Live2D现阶段有两个主要的版本是2.1的版本和3.0的版本. 国内2.1版本用的比较多(ps.此为自己 ...
- unity 游戏中的寻路与导航系统(5种寻路算法详解)
@了解游戏中常见的寻路方式 通常来讲一般是根据建模方式来决定寻路方式 常见的寻路方式--建模方式 这里提供一下三种建模方式的示意图,如下 ,分别对应着,原图.Grid.WayPoint.NavMesh ...
- unity游戏中提示信息如何实现_Unity编辑器操作面试题集锦(上)
1.请描述游戏动画有几种,以及其原理. 答案:主要有关节动画.单一网格模型动画(关键帧动画).骨骼动画. 关节动画把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整 体的动画,角 ...
- Unity 游戏中的战斗系统的架构与设计
前言 很多刚开始做游戏的小伙伴感觉战斗系统是一个比较麻烦的部分,不知道如何设计,角色很多,职业很多,技能有好几种,还有装备相关的东西.今天这篇文章详细的讲解一个战斗系统应该如何架构与设计,你看完并搞懂 ...
最新文章
- Python库os使用笔记
- java中JFrame去掉边框设置背景
- Maven 单元测试
- 手术步骤_近视飞秒激光手术和传统Lasik手术比较
- 集齐最后一块拼图,全栈Serverless时代正式开启
- pagehelper工具类_PageHelper最佳实践
- jdbctemplate 批量删除_10秒3步批量去除PDF水印
- 算法5-----三个数大小比较
- 关于 FROM tableA,tableB 和 tableA LEFT JOIN tableB on 的区别
- 课程设计 计算机公共基础,基于Moodle大学计算机公共基础课程设计.pdf
- EasyCamera中海康摄像头语音对讲和云台控制转发实现
- Rockchip平台cpu散热风扇随温度自动调速的配置方法
- 电脑鼠标右键没有新建选项怎么办?
- Ceres-Solver
- 【pandas】统计指标
- 区块链技术十周年—回眸与前瞻
- 150.网络安全渗透测试—[Cobalt Strike系列]—[DNS Beacon原理/实战测试]
- NYOJ 628 小媛在努力
- 如何自学维修计算机,怎样快速学习汽车电脑维修?从入门到精通
- EC20 TCP/IP AT指令(安卓串口通信开发)
热门文章
- vuecli3修改html,vue-cli3多页应用改造
- c ajax 上传图片,ajax +NodeJS 实现图片上传实例
- java drawstring字体大小,JAVA中,drawstring 方法的用法,格式是什么啊
- Linux C 串口属性设置
- 【计算机网络】整体体系结构
- 【计算机组成原理】乘法阵列器
- python怎么用matplotlib_Python-如何在matplotlib中更新图?
- linux下oracle 9204 soft only,linux 下oracle 9i的安装
- linux如何运行安卓程序,如何在Android系统上运行C语言的程序
- 图论--最短路--SPFA