Unity C# 代码规范(Coding Style Guide)是保证团队协作、代码可维护性和可读性的基础。下面给出一份通用且实用的 Unity C# 代码规范,涵盖命名、格式、结构、注释、Unity 特有习惯等方面,适合团队或个人参考。
Unity C# 代码规范
1. 命名规范
1.1 类、结构、枚举
- 使用帕斯卡命名法(PascalCase)。
- 示例:
PlayerController
,GameManager
,EnemyType
1.2 方法、属性、事件
- 使用帕斯卡命名法(PascalCase)。
- 示例:
MoveToTarget()
,OnPlayerDeath
,Health
1.3 变量
- 私有字段:推荐下划线+小驼峰(
_camelCase
),或小驼峰(camelCase
)。 - 公有字段/属性:帕斯卡命名法。
- 示例:
private int _health;
、public int Health { get; set; }
1.4 常量、静态只读
- 全大写,单词间下划线。
- 示例:
private const int MAX_HEALTH = 100;
1.5 接口
- 以
I
开头,帕斯卡命名法。 - 示例:
IDamageable
1.6 Unity 组件引用
- 推荐加
xxxComponent
或xxxObj
后缀。 - 示例:
private Rigidbody _rigidbody;
、private GameObject _playerObj;
2. 代码格式
2.1 缩进
- 使用4个空格缩进,不用Tab。
2.2 大括号
- 大括号不换行,与C#官方一致。
- 示例:
void Start() { // ... }
2.3 空行
- 逻辑块之间适当空行,增强可读性。
2.4 每行长度
- 建议不超过120字符。
3. 文件与类结构
3.1 一个文件一个类
- 每个类/结构体/枚举单独一个文件,文件名与类名一致。
3.2 类成员顺序
推荐顺序:
- 常量、静态字段
- 公有字段/属性
- 序列化字段(
[SerializeField]
) - 私有字段
- Unity生命周期方法(Awake, Start, Update, OnEnable, OnDisable, OnDestroy等)
- 事件、回调
- 公有方法
- 私有方法
4. 注释规范
4.1 类/方法注释
- 用
///
三斜线注释,简要说明用途。 - 复杂逻辑用多行注释。
4.2 代码块注释
- 重要逻辑、难懂代码加行内注释。
4.3 TODO/FIXME
- 用
// TODO:
、// FIXME:
标记待办和需修复内容。
5. Unity 特有规范
5.1 MonoBehaviour 生命周期方法顺序
- 推荐顺序:
Awake
→OnEnable
→Start
→Update
→FixedUpdate
→LateUpdate
→OnDisable
→OnDestroy
5.2 序列化字段
- 用
[SerializeField] private
代替 public 字段,保护封装性。 - 示例:
[SerializeField] private float moveSpeed = 5f;
5.3 GetComponent 缓存
- 频繁使用的组件引用应缓存,避免在
Update
里反复调用GetComponent
。
5.4 魔法数字
- 禁止魔法数字,使用常量或序列化字段。
5.5 事件注册与注销
- 在
OnEnable
注册事件,在OnDisable
注销,防止内存泄漏。
6. 其它建议
6.1 访问修饰符
- 能用
private
就不用public
,优先保护封装性。
6.2 using 指令
- 只引用需要的命名空间,避免全局 using。
6.3 空检查
- 对外部引用、委托等要做 null 检查。
6.4 代码分层
- 逻辑与表现分离,UI、数据、控制器分层。
7. 代码示例
using UnityEngine;
/// <summary>
/// 控制玩家移动的组件
/// </summary>
public class PlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
private Rigidbody _rigidbody;
private void Awake() {
_rigidbody = GetComponent<Rigidbody>();
}
private void Update() {
Move();
}
/// <summary>
/// 玩家移动逻辑
/// </summary>
private void Move() {
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(h, 0, v);
_rigidbody.velocity = direction * moveSpeed;
}
}
8. 推荐工具
- EditorConfig:统一团队代码风格
- StyleCop:C#代码风格分析
- Rider/Resharper:自动格式化和风格检查
- Unity自带的代码格式化工具(如Rider、VS的C#格式化)
9. 参考资料
下面继续补充Unity C# 代码规范的进阶内容,包括团队协作建议、常见反例、注释模板、EditorConfig 示例、代码审查建议等,帮助你在实际项目中更好地落地和执行规范。
10. 团队协作与代码审查建议
10.1 代码审查(Code Review)
- 强制代码审查:所有合并到主分支的代码必须经过至少一名同事的审查。
- 审查内容:不仅关注功能实现,还要关注命名、结构、注释、性能、可扩展性和Unity最佳实践。
- 审查工具:可用 GitHub/GitLab/Bitbucket 的 Pull Request/Merge Request 功能。
10.2 代码提交规范
- 小步提交:每次提交只做一件事,便于回溯和定位问题。
- 提交信息:清晰描述本次变更内容,必要时附带 issue 编号。
10.3 代码风格自动化
- 配置EditorConfig或StyleCop,让IDE自动格式化和检查风格。
- 推荐团队统一使用 Rider、VS 或 VSCode,并共享格式化配置。
11. 常见反例与改进建议
11.1 命名不规范
反例:
public class player : MonoBehaviour { }
private int hp;
正例:
public class Player : MonoBehaviour { }
private int _health;
11.2 魔法数字
反例:
transform.position += Vector3.forward * 7.5f;
正例:
private const float MOVE_DISTANCE = 7.5f;
transform.position += Vector3.forward * MOVE_DISTANCE;
11.3 滥用 public 字段
反例:
public int score;
正例:
[SerializeField] private int _score;
public int Score => _score;
11.4 GetComponent 滥用
反例:
void Update() {
GetComponent<Rigidbody>().AddForce(Vector3.up);
}
正例:
private Rigidbody _rigidbody;
void Awake() {
_rigidbody = GetComponent<Rigidbody>();
}
void Update() {
_rigidbody.AddForce(Vector3.up);
}
12. 注释模板
12.1 类注释模板
/// <summary>
/// [简要说明类的作用]
/// </summary>
12.2 方法注释模板
/// <summary>
/// [方法功能说明]
/// </summary>
/// <param name="param1">[参数1说明]</param>
/// <returns>[返回值说明]</returns>
12.3 复杂逻辑注释
// [这里解释为什么要这样做,或者算法思路]
12.4 TODO/FIXME 示例
// TODO: 优化此处性能
// FIXME: 修复边界条件下的崩溃
13. EditorConfig 示例
在项目根目录下新建 .editorconfig
文件:
root = true
[*.cs]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8-bom
insert_final_newline = true
trim_trailing_whitespace = true
# C# specific rules
csharp_new_line_before_open_brace = all
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_space_after_cast = true
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_keywords_in_control_flow_statements = true
14. Unity 特有建议补充
14.1 ScriptableObject 用法
- ScriptableObject 类名以
xxxData
、xxxConfig
结尾。 - 不要在 ScriptableObject 里直接引用场景对象。
14.2 MonoBehaviour 禁止构造函数
- 不要在 MonoBehaviour 里写构造函数,初始化逻辑放在
Awake
或Start
。
14.3 资源路径硬编码
- 禁止硬编码资源路径,统一用常量或配置管理。
14.4 事件与委托
- 事件声明用
event
关键字,避免直接暴露委托。 - 事件命名以
On
开头,如OnPlayerDead
。
15. 代码分层与架构建议
- UI 层:只负责界面显示和用户交互。
- 逻辑层:处理游戏规则、数据、状态。
- 数据层:负责数据存储、加载、保存。
- 工具层:通用工具类、扩展方法等。
16. 参考开源项目
17. 规范落地建议
- 项目启动时,团队共同制定并认领规范。
- 规范文档放在项目根目录,定期回顾和更新。
- 新人入职时,安排规范培训。
- 代码审查时,规范问题必须整改。