开发代码
-
编码(Unity 引擎相关)
-
规范等级 S
100. 禁止通过 new 的方式实例化 MonoBehaviour 的派生类, 否则无法得到引擎的有效管理.
101. 禁止在 Update/FixedUpdate/LateUpdate/OnGUI 等频繁调用的逻辑中使用协程.
102. 禁止使用 Resources.Load 加载资源, 个别情况除外.
103. 禁止使用 LINQ 表达式. -
规范等级 A
120. 禁止使用 Invoke("MethodA", 2) 来实现延时调用.
121. 禁止逐帧使用 Find/GetComponent 等引擎接口调用, 如有此类需求, 应该将结果缓存供后续使用.
122. 必须使用 GetInstanceID() 获得的 int 值代替 UnityEngine.Object应用进行比较或作为散列表数据类型.
如 Dictionary 和 HashSet 的 key.
123. 当设置 GameObject 对象之间的父子关系时, 如果仅关注逻辑上的层次关系而无需保持子对象的空间方位, 则应该使用SetParent(parent, false) 避免空间转换的性能消耗.
124. 代码中需要访问到 Transform 组件的位置数据时, 尽可能使用 localPosition 代替对 position 属性的访问.
125. 尽可能避免使用协程. Unity 的协程是使用迭代器实现的会分配堆内存.
126. 尽可能避免使用 MeshCollider 组件. 如有此类需求也应尽可能减少网格碰撞体的面数. 或使用 Sphere/Box/Capsule 的组合来代替.
127. 使用网格导航时, 应尽可能避免使用 Obstacle 模拟动态障碍物, 否则对 CPU 性能冲击很大. 如有此类需求建议使用碰撞体代替. -
规范等级 B
140. 禁止使用接受字符串参数的 GetComponent 重载方法.
141. 禁止在 MonoBehaviour 的派生类中存在被引擎高频调用的空方法, 如 Update里没有方法内容就应该删掉.
142. 禁止在 MonoBehaviour 的派生类中存在 Awake/Start/OnEnable/OnDestory 等空方法.
143. 必须使用 CompareTag 接口比较 GameObject的Tag.
144. 尽可能减少 UnityEngine.Object null 比较. -
规范等级 C
160. 建议合理使用 OnBecameVisible/OnBecameInvisible/OnWillRenderObject 类似的引擎回调以避免不必要的渲染和计算.
-
-
编码(引擎无关)
-
规范等级 S
200. 必须对可能造成功能失效, 影响流程的代码块添加异常捕获.
201. 禁止高频的字符串拼接. 如无法避免, 必须使用 StringBuilder 代替 "+" 操作符进行字符串拼接. -
规范等级 A
220. 尽可能将 CPU 占用高的逻辑代码分帧处理平摊 CPU 压力.
221. 尽可能将计算量较大的运算放到子线程中进行, 避免阻塞主线程(如寻路等算法).
222. Delegate 回调方法必须适时的解除注册, 否则回调方法所属的对象会一直有引用计数, 继而引起该对象所引用的资源无法得到释放. -
规范等级 B
240. 尽量避免使用 Reflection(反射).
241. 尽量避免使用可变参数(param object[] args), 避免装箱拆箱.
242. 禁止没有计算需求的变量赋值或计算.
243. 简单条件判断尽量使用三目运算符: b?x:y.
244. 注意 List 等容器常用接口的复杂度, 尽量从尾部移除/批量移除(RemoveRange)等.
245. 在频繁查询数据列表时, 建议使用 HashSet/HashTable 查找时间复杂度低的数据结构, 避免使用 List.
246. 尽可能为快速产生和消灭的大量对象建立缓冲池. -
规范等级 C
260. 使用可变长容器时, 建议根据预估容量进行初始化.
261. 循环中寻找到符合条件后应该适时地使用 break 跳出循环.
262. 尽可能将一些内存占用低但为数众多/功能简单的小对象定义为 struct(结构体) 而非 class(类).
263. 尽可能减少函数调用栈, 如使用 x = (x > 0 ? x : -x); 代替 x = Mathf.Abs(x).
264. 尽可能将类或函数声明为 sealed, IL2CPP 会对 sealed 的类或函数进行优化, 变虚函数调用为直接函数调用.
-
-
UI
-
规范等级 A
320. 禁止非图集贴图资源不合理的留白. 会影响 UGUI 运行时自动合批.
321. 资源设置 UI 的贴图资源禁止勾选 Generate Mip Maps.
322. 禁止使用修改 Alpha 值的方式来隐藏界面.
323. 尽可能降低 Release 版中图集留白, 提高贴图利用率.
324. 尽可能将图集中大的图片改为底图加载. -
规范等级 B
340. 建议同一 Canvas 中使用到的图集数量控制在三个以内. -
规范等级 C
360. 建立合理规划公共图集. 在内存占用/加载频度/引用复杂度之间确定合理的平衡点.
-
-
渲染
-
规范等级 S
400. 禁止匿名 GrabPass. 如需使用到 GrabPass 必须命名并尽可能复用. -
规范等级 A
420. Shader中尽可能减少多 Pass 渲染, 除非必须这么做.
421. 尽可能降低 Release 版中 Shader 中的 Keyword 数量.
422. 尽可能降低 SkinnedMeshRenderer 组件数量. -
规范等级 B
440. 禁止逐帧直接使用名称对 Shader Uniform 量进行更新.
441. 尽量避免在 Shader 中使用复杂的计算如: pow/sin/cos/tan/log 等.
442. 建议在 Shader 中采用预混合或实时混合纹理的方式代替实时地多次纹理采样.
443. 移动平台的 Shader 编码一定要考虑数据精度(float/half/fixed)的合理使用.
444. 应尽可能减少每帧 Material.GetXX/Material.SetXX的次数, 比如把多个 uniform half 变量合并为 uniform half4.
-
-
动画
- 规范等级 B
540. 尽可能避免将 Animator 的 Culling Mode 属性设置为 Always, 对于不使用 RootMotion 的项目建议选择 CullCompletely.
- 规范等级 B
-
物理
- 规范等级 B
640. 尽可能避免使用物理引擎. 建议自行编码模拟物理效果.
641. 使用物理模块的游戏, 建议在 PhysicsManager 中设置矩阵, 会有较大的性能提升.
- 规范等级 B
-
音频
-
规范等级 A
720. 如使用第三方音频插件, 需禁用 FMOD 模块(Edit -> Project Settings -> Audio -> Disable -> UnityAudio). -
规范等级 B
740. 若不需要立体音效, 音频导入设置需勾选 Force to Mono(注: 制作音频时就应该制作单通道的.)
-
-
资源
- 规范等级 A
820. 音频格式: iOS平台一般使用 mp3, Android平台一般使用 ogg.
821. 无需由逻辑代码访问的渲染资源禁止勾选 Read/Write Enabled, 如网格和图片.
822. 导入蒙皮网格模型时建议勾选 Optimize GameObject 优化选项, 可极大地降低骨骼层次复杂度, 优化 CPU 性能.
823. 无动作模型资源必须将 Animation Type 设置为 None, 否则会导致游戏对象挂在不必要的动画脚本, 大量的话会严重影响 CPU 性能.
824. 导入的模型如果无需用到法线和切线, 必须将导入设置的 Normals 和 Tangents 选项设置为 None.
825. 导入的模型如果无需参与Unity Lightmap 烘焙, 必须将导入设置的 Generate Lightmap UVs 选项设置为 None.
- 规范等级 A
-
发包
-
规范等级 S
900. 禁止在 Release 版中存在任何 OnGUI 相关代码.
901. 禁止在 Release 版中存在任何日常调试相关的 UnityEngine.DeBug 类日志输出.
902. 禁止在 Release 版中开启 "Development Build" 和 "Script Debugging" 选项.
903. 在发布时必须将游戏锁定至合适的帧率(建议 30/60 帧) -
规范等级 A
921. 禁止在 Release 版中使用引擎提供的 SendMessage 方法.
-