A22:Unity 项目开发规范

编码(Unity 引擎相关)

  • 规范等级 S
    禁止通过 new 的方式实例化 MonoBehaviour 的派生类, 否则无法得到引擎的有效管理.
    禁止在 Update/FixedUpdate/LateUpdate/OnGUI 等频繁调用的逻辑中使用协程.
    禁止使用 Resources.Load 加载资源, 个别情况除外.
    禁止使用 LINQ 表达式.

  • 规范等级 A
     禁止使用 Invoke("MethodA", 2) 来实现延时调用.
     禁止逐帧使用 Find/GetComponent 等引擎接口调用, 如有此类需求, 应该将结果缓存供后续使用.
    必须使用 GetInstanceID() 获得的 int 值代替 UnityEngine.Object应用进行比较或作为散列表数据类型.
    如 Dictionary 和 HashSet 的 key.
    当设置 GameObject 对象之间的父子关系时, 如果仅关注逻辑上的层次关系而无需保持子对象的空间方位, 则应该使用SetParent(parent, false) 避免空间转换的性能消耗.
    代码中需要访问到 Transform 组件的位置数据时, 尽可能使用 localPosition 代替对 position 属性的访问.
    尽可能避免使用协程. Unity 的协程是使用迭代器实现的会分配堆内存.
     尽可能避免使用 MeshCollider 组件. 如有此类需求也应尽可能减少网格碰撞体的面数. 或使用 Sphere/Box/Capsule 的组合来代替.
    使用网格导航时, 应尽可能避免使用 Obstacle 模拟动态障碍物, 否则对 CPU 性能冲击很大. 如有此类需求建议使用碰撞体代替.

  • 规范等级 B
    禁止使用接受字符串参数的 GetComponent 重载方法.
    禁止在 MonoBehaviour 的派生类中存在被引擎高频调用的空方法, 如 Update里没有方法内容就应该删掉.
    禁止在 MonoBehaviour 的派生类中存在 Awake/Start/OnEnable/OnDestory 等空方法.
     必须使用 CompareTag 接口比较 GameObject的Tag.
    尽可能减少 UnityEngine.Object null 比较.

  • 规范等级 C
    建议合理使用 OnBecameVisible/OnBecameInvisible/OnWillRenderObject 类似的引擎回调以避免不必要的渲染和计算.

编码(引擎无关)

  • 规范等级 S
    必须对可能造成功能失效, 影响流程的代码块添加异常捕获.
    禁止高频的字符串拼接. 如无法避免, 必须使用 StringBuilder 代替 "+" 操作符进行字符串拼接.

  • 规范等级 A
    尽可能将 CPU 占用高的逻辑代码分帧处理平摊 CPU 压力.
    尽可能将计算量较大的运算放到子线程中进行, 避免阻塞主线程(如寻路等算法).
    Delegate 回调方法必须适时的解除注册, 否则回调方法所属的对象会一直有引用计数, 继而引起该对象所引用的资源无法得到释放.

  • 规范等级 B
    尽量避免使用 Reflection(反射).
    尽量避免使用可变参数(param object[] args), 避免装箱拆箱.
    禁止没有计算需求的变量赋值或计算.
    简单条件判断尽量使用三目运算符: b?x:y.
    注意 List 等容器常用接口的复杂度, 尽量从尾部移除/批量移除(RemoveRange)等.
    在频繁查询数据列表时, 建议使用 HashSet/HashTable 查找时间复杂度低的数据结构, 避免使用 List.
    尽可能为快速产生和消灭的大量对象建立缓冲池.

  • 规范等级 C
    使用可变长容器时, 建议根据预估容量进行初始化.
    循环中寻找到符合条件后应该适时地使用 break 跳出循环.
    尽可能将一些内存占用低但为数众多/功能简单的小对象定义为 struct(结构体) 而非 class(类).
    尽可能减少函数调用栈, 如使用 x = (x > 0 ? x : -x); 代替 x = Mathf.Abs(x).
    尽可能将类或函数声明为 sealed, IL2CPP 会对 sealed 的类或函数进行优化, 变虚函数调用为直接函数调用.

UI

  • 规范等级 A
    禁止非图集贴图资源不合理的留白. 会影响 UGUI 运行时自动合批.
    资源设置 UI 的贴图资源禁止勾选 Generate Mip Maps.
    禁止使用修改 Alpha 值的方式来隐藏界面.
    尽可能降低 Release 版中图集留白, 提高贴图利用率.
    尽可能将图集中大的图片改为底图加载.

  • 规范等级 B
    建议同一 Canvas 中使用到的图集数量控制在三个以内.

  • 规范等级 C
    建立合理规划公共图集. 在内存占用/加载频度/引用复杂度之间确定合理的平衡点.

渲染

  • 规范等级 S
    禁止匿名 GrabPass. 如需使用到 GrabPass 必须命名并尽可能复用.

  • 规范等级 A
    Shader中尽可能减少多 Pass 渲染, 除非必须这么做.
    尽可能降低 Release 版中 Shader 中的 Keyword 数量.
    尽可能降低 SkinnedMeshRenderer 组件数量.

  • 规范等级 B
    禁止逐帧直接使用名称对 Shader Uniform 量进行更新.
    尽量避免在 Shader 中使用复杂的计算如: pow/sin/cos/tan/log 等.
    建议在 Shader 中采用预混合或实时混合纹理的方式代替实时地多次纹理采样.
    移动平台的 Shader 编码一定要考虑数据精度(float/half/fixed)的合理使用.
    应尽可能减少每帧 Material.GetXX/Material.SetXX的次数, 比如把多个 uniform half 变量合并为 uniform half4.

动画

  • 规范等级 B
    尽可能避免将 Animator 的 Culling Mode 属性设置为 Always, 对于不使用 RootMotion 的项目建议选择 CullCompletely.

物理

  • 规范等级 B
    尽可能避免使用物理引擎. 建议自行编码模拟物理效果.
    使用物理模块的游戏, 建议在 PhysicsManager 中设置矩阵, 会有较大的性能提升.

音频

  • 规范等级 A
    如使用第三方音频插件, 需禁用 FMOD 模块(Edit -> Project Settings -> Audio -> Disable -> UnityAudio).

  • 规范等级 B
    若不需要立体音效, 音频导入设置需勾选 Force to Mono(注: 制作音频时就应该制作单通道的.)

资源

  • 规范等级 A
    音频格式: iOS平台一般使用 mp3, Android平台一般使用 ogg.
    无需由逻辑代码访问的渲染资源禁止勾选 Read/Write Enabled, 如网格和图片.
    导入蒙皮网格模型时建议勾选 Optimize GameObject 优化选项, 可极大地降低骨骼层次复杂度, 优化 CPU 性能.
    无动作模型资源必须将 Animation Type 设置为 None, 否则会导致游戏对象挂在不必要的动画脚本, 大量的话会严重影响 CPU 性能.
    导入的模型如果无需用到法线和切线, 必须将导入设置的 Normals 和 Tangents 选项设置为 None.
    导入的模型如果无需参与Unity Lightmap 烘焙, 必须将导入设置的 Generate Lightmap UVs 选项设置为 None.

打包

  • 规范等级 S
    禁止在 Release 版中存在任何 OnGUI 相关代码.
    禁止在 Release 版中存在任何日常调试相关的 UnityEngine.DeBug 类日志输出.
    禁止在 Release 版中开启 "Development Build" 和 "Script Debugging" 选项.
    在发布时必须将游戏锁定至合适的帧率(建议 30/60 帧)

  • 规范等级 A
    禁止在 Release 版中使用引擎提供的 SendMessage 方法.

你可能感兴趣的:(A22:Unity 项目开发规范)