Unity 命名规范简述2025
第一部分:C# 脚本命名规范
核心原则:
这是在C#及C#相关代码中常用的命名规则:
PascalCase (帕斯卡命名法): 每个单词的首字母都大写。
//例如
PlayerController, GameManager
camelCase (驼峰命名法): 第一个单词的首字母小写,后续单词的首字母大写。
//例如
playerHealth, isGameOver。
驼峰式命名法存在一些拓展,比如_camelCase(以下划线开头的驼峰),此处不再举例
针对新手的一些特别提醒:
- 不到万不得已,不要使用拼音(不会英文可以使用翻译),就算不得不使用拼音,务必避免拼音首字母缩写开头。(GNAN,AN .etc)
- 除非你和你的项目组超越了一般人类,否则我们不建议使用中文作为变量名,虽然C#支持该行为。(很快就会遇到UTF-8,GBK等问题,此问题会在后面注释部分简述)
- 不要使用无意义命名符,此处额外提醒一下竞赛相关和计算机相关的同学,不要使用a,b,c命名。i和j不在此列,他们仅用于循环。
- 除特殊情况外,不要在变量的中间中加入空格和_
- 不要使用c#保留的关键字作为变量名,原因显而易见。在涉及到多语言交互时,可能不得不使用某个语言的关键字,此时可以使用@(@class,@namespace),但此处不做详述,也不建议使用。
- 从总体上看,一个可能被外界调用的,公开的东西通常使用PascalCase及其衍生,一个内部调用的,私有的东西通常使用camelCase及其衍生。
- 命名规范最重要的一点是统一,你的命名方法在整个项目中应该完全一致。因为部分命名存在可选配置,
1.命名空间 (Namespaces)
命名空间是一个避免命名冲突的逻辑容器,可以理解为一个巨大的文件夹。
使用 PascalCase,并用公司名、项目名或功能模块来组织,以避免类型冲突。
结构: CompanyName.ProjectName.ModuleName
(公司名,项目名,模块名称)
//例如
namespace MyCompany.AwesomeGame.UI
{
public class MainMenuController { }
}
意:Unity用户脚本默认在同一个命名空间中,所以通常不需要给你的脚本特意的写一个命名空间。
2.类、结构体、枚举、接口 (Classes, Structs, Enums, Interfaces)
规则: 全部使用 PascalCase。
接口 (Interfaces): 在名称前加前缀 I。
//例如
// Class 类
public class PlayerMovement { }
// Struct 结构体
public struct GameData { }
// Enum 枚举
public enum PlayerState
{
Idle,
Running,
Jumping
}
// Interface 接口
public interface IDamageable
{
void TakeDamage(float amount);
}
3.方法 (Methods)
方法,在别的语言中被称为“函数”,本质上是类似的,接受>=0个输入,给出>=0个输出,执行某种行为。
规则: 使用 PascalCase。方法名应为动词或动词短语,清晰地描述其功能。
//例如
//空返回值方法
public void MovePlayer() { }
private void CalculateFinalScore() { }
//布尔返回值方法
public bool IsPlayerAlive() {return true;}
4.字段和属性 (Fields and Properties)
这是最容易产生混淆的地方,建议遵守统一标准。
public 字段/属性: 使用 PascalCase
public 是访问限制修饰符,通常表明被修饰的对象在该命名空间中是公用的
在 Unity 中,public 字段会暴露在 Inspector 面板中。
//例如
public int Score; //字段
public string PlayerName { get; set; }//属性
private / protected 字段: 使用camelCase /_camelCase
(具体使用哪一种取决于你当前的项目)
//例如
private int currentHealth;
protected float _moveSpeed;
[SerializeField] 私有字段:
对于需要在 Inspector 中显示但又想保持 private 访问权限的字段,规则与 private 字段相同。
[SerializeField]
private GameObject playerPrefab;
private GameObject _cardPrefab;
常量 (Constants): 使用 PascalCase
public const int MaxPlayerCount = 4;
静态只读字段 (Static Readonly Fields): 使用 PascalCase
public static readonly Color DefaultColor = Color.white;
5.方法参数与局部变量 (Method Parameters and Local Variables)
规则: 使用 camelCase
public class Health
{
private int maxHealth = 100;
private int currentHealth;
public void TakeDamage(int damageAmount) // damageAmount 是参数
{
if (damageAmount < 0)
{
damageAmount = 0;
}
int finalDamage = CalculateDamageReduction(damageAmount); // finalDamage 是局部变量
currentHealth -= finalDamage;
}
private int CalculateDamageReduction(int baseDamage)
{
// ...
return baseDamage;
}
}
6.布尔值 (Booleans)
规则: 名称应具有肯定意义,并常使用 "is", "can", "has" 等前缀,使其读起来像一个问题。
示例:
bool isDead = false;
bool canJump = true;
bool hasKey = false;
避免使用 isNotDead这样的否定命名。
7.注释 (Comments)
代码本身应该清晰地表述它在“做什么”。如果你的代码需要注释来解释它在做什么,通常意味着代码本身写得不够清晰。注释主要应该解释“为什么”
C# 中主要有三种类型的注释:
1. 单行注释 (Single-line Comments)
使用 //,通常用于对单行或一小段代码块进行快速解释。
// 缓存主摄像机的引用以提升性能
private Camera _mainCamera;
void Start()
{
_mainCamera = Camera.main; // 在 Start 中获取
}
单行注释可以配合标准化标签使用,这些标签会被大部分IDE识别(比如Visual Studio)
(Task Tags)

上图为在VS中找到标准化标签的方法
常见的标准化标签有:
· // TODO:: 标记一个已知需要添加或完成的功能。
// TODO: 添加粒子效果和音效
private void PlayDeathEffects() { }
· // UNDONE:: 用于标记某个任务或功能尚未完成。与 TODO 类似,但语义上更强调“未完成”的状态。
// UNDONE: 当玩家速度过快时,此处的射线检测可能会穿透薄墙体
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, moveDistance))
{
// ...
}
· // HACK:: 标记一段不够优雅、临时的解决方案,未来可能需要重构。
// HACK: 暂时硬编码 Boss ID 为 3,等待后端配置表完成
if (bossId == 3) { /* ... */ }
2. 多行注释 (Multi-line Comments)
使用 /* ... */,用于较长的解释,或者临时禁用一大段代码。
/*
* 这个方法负责计算玩家的最终得分。
* 得分计算公式为:(基础分 + 连击奖励) * 难度系数。
* 需要确保在调用此方法前,所有相关的统计数据都已更新。
*/
private void CalculateFinalScore()
{
// ...
}
/*
// --- 临时禁用的旧逻辑 ---
if (player.IsInvincible)
{
player.TakeDamage(0);
}
*/
在vs中,我们通常不使用多行注释,因为

上图红框
vs存在一个快捷 注释-取消注释 的方法,只需要选中点击即可。
3. XML 文档注释 (XML Documentation Comments)
使用 /// (或 /** ... */),这是最重要、最专业的注释方式,尤其适用于所有非 private 的成员(类、方法、属性、接口等)当你将鼠标悬停在方法或类上时,Visual Studio (或其他 IDE) 会自动显示这些注释,提供智能提示 (IntelliSense)。同时该注释也可以利用工具(如 DocFX)自动生成项目的外部文档。
从规则上来说,所有 public 成员都应该有一个自己的 XML 文档注释,尤其是这个方法可能会被多个地方调用或者你在和他人进行合作。
这是专业开发中最强制性的规范之一。所有暴露给其他类的成员都应该有清晰的文档。
- <summary>: 描述该成员的功能
- <param name="name">: 描述方法的参数
- <returns>: 描述方法的返回值
- <remarks>: 提供更详细的说明(可选)
- <exception cref="type">: 描述可能抛出的异常(在 Unity 中不常用)
/// <summary>
/// 管理玩家生命值、护盾和死亡状态的系统。
/// </summary>
public class PlayerHealth : MonoBehaviour, IDamageable
{
/// <summary>
/// 玩家当前是否处于无敌状态。
/// </summary>
public bool IsInvincible { get; private set; }
/// <summary>
/// 对玩家施加伤害,会优先扣除护盾。
/// </summary>
/// <param name="damageAmount">要施加的伤害值,应为正数。</param>
/// <param name="damageSource">造成此次伤害的来源对象, </param>
/// <remarks>
/// 如果玩家处于无敌状态,此方法将不会产生任何效果。
/// </remarks>
/// <returns>返回实际对生命值造成的伤害量。</returns>
public float TakeDamage(float damageAmount, GameObject damageSource)
{
if (IsInvincible || damageAmount <= 0)
{
return 0f;
}
// ... 伤害计算逻辑 ...
return actualDamageDealt;
}
}
注意:
- 避免复述代码的注释
// bad
i++; // 将 i 增加1
// good(当然正常情况下i++不需要注释)
i++; // 增加计数器以匹配从1开始的数组索引
- 避免“段子式”或者不专业的注释
//bad
// 我也不知道这里为什么能跑,别动它!
//good
//HACK:此处逻辑存在问题
关于中文编码的一些问题:
常见的中文编码有两套系统:
GBK/GB2312: 兼容性差。一个以 GBK 编码保存的、含有中文注释的源文件,如果被一个默认使用 UTF-8 的编辑器(如 macOS/Linux 上的很多工具,或配置为 UTF-8 的 VS Code)打开,注释部分会立刻变成乱码。反之亦然。但是,Windows系统下的VS默认使用GBK编辑
UTF-8: 兼容性极高。几乎所有现代操作系统、编辑器、编译器和开发工具都默认支持甚至推荐使用 UTF-8。使用它可以在 Windows, macOS, Linux 之间无缝地交换文件而不会出现乱码。同时它也是Git 等工具的原生偏好。
不同编码的文字是无法兼容的,用另一种格式打开会直接变成乱码

一个使用UTF-8打开GBK的实例
因此我们建议使用UTF-8编码作为你的编码,VS的插件列表为该功能提供了插件

第二部分:Unity 项目与资源命名规范
(Project & Asset Conventions)
项目资源的命名规范对于团队协作和后期维护至关重要,能够让你通过文件名快速识别资源类型和用途。
规范的具体实施方案要根据你的项目和框架决定,下面给出的只是一个供参考的通用方案
1,项目文件夹结构 (Project Folder Structure)
Assets/
│ ── Scenes/
│
│ ── Scripts/
│ ├── Editor/
│ ├── Gameplay/
│ └── UI/
│
│ ── Prefabs/
│ ├── Characters/
│ └── Environment/
│
│ ── Art/
│ ├── Models/
│ ├── Textures/
│ ├── Materials/
│ └── Animations/
│
│ ── Resources/
│
│ ── Audio/
│ ├── SFX/
│ └── Music/
│
│ ── Shaders/
│
│ ──ThirdParty/
│ └── ...
│
│ ──ProjectSetting/
└── ...
关于Unity中一些特殊文件夹的介绍:
特殊文件夹的名称是有严格要求的,部分文件夹对其层次也有要求
1,Editor
这个文件夹里的所有脚本都属于编辑器脚本 (Editor Scripts),它们可以访问 UnityEditor API,这些脚本和资源不会被打包到最终发布的游戏版本中。
我们也会使用预编译指令来做到类似效果
#if UNITY_EDITOR
Debug.Log("这是在编辑器中运行!!");
#endif
Editor可以存在多个,没有严格的位置要求,但是要位于Assets之下
2,Resources
存放可以通过代码动态加载的资源。可以使用 Resources.Load("path/to/asset");方法在运行时按路径加载此文件夹内的任何资源。这里填写的是相对于Resources文件夹本身的路径。
不应该存在多个Resources文件夹。
要位于Assets之下
注意:在部分项目中,Prefabs文件夹会位于Resources文件夹下,这是方便代码进行中读取和更换prefab
3,Plugins
存放原生代码插件 (Native Code Plugins),Unity 会自动识别这些库并将其包含在相应的平台构建中,在往unity导入插件时便会放入该文件夹。
不需要手动读取
要位于Assets之下
4,StreamingAssets
存放需要以原始、未处理格式包含在游戏中的文件,此文件夹中的文件会被原封不动地复制到目标构建包的特定路径中,不会像普通资源那样被压缩或处理。非常适合存放需要按需读取的外部配置文件 (如 JSON, XML)、视频文件、或初始数据库。
在不同平台上的访问路径不同,需要通过 Application.streamingAssetsPath属性来获取。
要位于Assets之下
5,ProjectSettings
存放项目的所有配置信息,包括物理、标签与层 (Tags & Layers)、输入设置、图形质量、构建设置等。这个文件夹非常重要,在多人合作时必须纳入版本控制系统 (Git),以确保团队成员之间的项目设置保持一致。
不位于Assets下
2,资源命名 (Asset Naming)
部分情况下资源命名会使用下划线分割,部分情况不会,根据你的项目决定
|
资源类型 (Asset Type) |
常用前缀 (Prefix) |
常用后缀 (Suffix) |
示例 (Example) |
|
场景 (Scene) |
Scene_ |
Scene_MainMenu, Scene_Level_01 | |
|
预制体 (Prefab) |
PFB_ 或 P_ |
_Prefab |
PFB_Player, P_Rock_Large, Enemy_Grunt_Prefab |
|
材质 (Material) |
MAT_ 或 M_ |
_Mat |
MAT_Player_Body, M_Ground_Grass, Metal_Mat |
|
纹理 (Texture) |
T_ |
_Albedo, _N, _M, _AO |
T_Brick_Albedo, Player_Body_N (Normal), Metal_M (Metallic) |
|
模型 (Model/Mesh) |
SM_ (Static), SK_ (Skeletal) |
_Mesh |
SM_Rock_01, SK_Player_Hero |
|
脚本 (Script) |
PlayerController.cs, HealthSystem.cs (与类名一致) | ||
|
动画控制器 (Animator Controller) |
AC_ |
_AC |
AC_Player, Enemy_AC |
|
动画片段 (Animation Clip) |
Anim_ |
_Anim |
Anim_Player_Idle, Run_Fwd_Anim |
|
音频剪辑 (Audio Clip) |
SFX_, MUS_, VO_ |
SFX_Footstep_Grass, MUS_MainMenu, VO_Player_Hurt | |
|
音频混合器 (Audio Mixer) |
AM_ |
_Mixer |
AM_Master, Gameplay_Mixer |
|
物理材质 (Physic Material) |
PHYS_ |
_PhysMat |
PHYS_Ice, Bouncy_PhysMat |
|
渲染纹理 (Render Texture) |
RT_ |
RT_Minimap, RT_WaterReflection | |
|
着色器/着色器图 (Shader/Graph) |
SH_ |
_Shader |
SH_Water, Hologram_Shader |
|
ScriptableObject |
SO_ |
_Data, _Config |
SO_PlayerStats, Weapon_Rifle_Data |
|
Timeline |
TL_ |
TL_IntroCutscene |
重点不在于你用哪一种,重点在于你的整个项目规范应该保持一致
3,场景层级命名(Scene Hierarchy Conventions)
GameObject 命名
- 规则: 使用 PascalCase,名称应清晰描述该物体的功能或内容。
- 示例: Player, MainCamera, DirectionalLight, EnemySpawner
功能性分组 (Functional Grouping)
使用空的 GameObject 作为“文件夹”来组织场景,并使用特定前缀或符号来标识它们。
示例:
- [SYSTEMS]
- GameManager
- UIManager
- AudioManager
- [ENVIRONMENT]
- StaticProps
- Prop_Barrel_01
- Prop_Crate_Small
- DynamicProps
- [UI]
- Canvas
- TitleUI
- Text_Title
- [LIGHTING]
- DirectionalLight
- ReflectionProbes
常用的前缀包括 [], @, --- 等,例如 @Managers, ---UI---。
注意:
一致性是最重要的原则
你实际使用的规范和项目可能与本文略有不同,只要在整个项目和团队中保持严格一致,它就是一套可用的规范。

580

被折叠的 条评论
为什么被折叠?



