本规范针对Unity项目涉及的所有文件。所有规则均严格按照<概述>-<要求>-<禁止>-<示例>的顺序编写。要求项使用:heavy_check_mark:标识,禁止项使用:heavy_multiplication_x:标识。示例使用引用表示如下:
示例块
所有命名基于以下两种命名规范:
- PascalCasing
- camelCasing
PascalCasing 约定每个单词的第一个字符大写(包括超过两个字母的首字母缩写),如以下示例所示:
PropertyDescriptor HtmlTag
这里有一种特殊情况,即遇到两个字母的首字母缩略词时,两个字母都要大写,如IOStream
camelCasing约定将除第一个单词之外的每个单词的第一个字符大写,如以下示例所示。 该示例还显示,以 camelCasing 标识符开始的双字母缩写词都是小写的。
propertyDescriptor ioStream htmlTag
[要求]:
✔️ 务必使用有意义的命名。
✔️ 务必在电子文档外,使用英文单词、英文缩写及数字组合命名所有项目文件夹、代码文件、资源文件、代码标识符。
✔️ 务必基于PascalCasing规范命名所有项目文件夹、代码文件。
✔️ 务必基于camelCasing规范命名所有非源码资源文件。
✔️ 务必仅使用下划线_分割多个单词组或数字。
✔️ 务必按照文件名_YYMMDD的格式命名电子文档,可使用中文。其中YYMMDD为6位数日期。同一文件在同一天内若存有多次修改的副本则务必按照文件名_YYMMDD_VERSION的格式命名,VERSION为两位数版本号,高位补零对齐。
[禁止]:
✖️ 禁止使用aaaa.cs,111.pptx等无意义的元素命名项目文件夹、电子文档、代码文件、资源文件、代码标识符。
✖️ 禁止使用空格 参与命名项目文件夹、电子文档、代码文件、资源文件、代码标识符。
✖️ 禁止使用中文字符或拼音命名除电子文档外的,所有项目文件夹、代码文件、资源文件、代码标识符。
✖️ 禁止使用数字后缀区分文件除电子文档外的,所有代码文件和资源文件。
对通用命名有以下正确示例:
xxx项目开题报告_190421.docx (无同一天内的多个副本则不使用数字后缀) xxx使用说明_190514_03.md (该文件在同一天内的第三份修改存档) /Assets/02_Motions/Animations (项目文件夹命名) KeyboardManager.cs (cs代码文件) ui_dateBar_background.png (资源文件) tree_small_trunk.fbx (资源文件)
以下为命名空间命名的一般规则:
SEUID.(ProjectName)[.<Feature>][.<Subnamespace>]
其中SEUID为固定名称,(ProjectName)为当前项目名称,方括号[]内为可选项。
[要求]:
✔️ 务必给所有项目代码分配明确的自定义命名空间。
✔️ 务必遵从PascalCasing规范给命名空间命名。
[禁止]:
✖️ 禁止使用下划线、连字符或任何其他非字母数字的字符。
✖️ 禁止在命名空间下定义与命名空间重名的类。
命名空间命名有以下正确示例:
SEUID.JTZKGesture (命名空间至少含有项目名) SEUID.JTZKGesture.HMM.Core (后续命名可选)
[要求]:
✔️ 务必遵从PascalCasing规范命名类、结构体、接口及成员。
✔️ 务必遵从camelCasing规范命名形参。
✔️ 考虑使用名词性单词命名类、结构体。
✔️ 务必以大写字母I作为前缀命名接口,并考虑使用描述性名词或形容词。
✔️ 考虑使用动词性短语或动宾短语命名成员方法。
✔️ 考虑使用名词短语或形容词命名属性。
✔️ 考虑使用动词短语命名事件。
✔️ 考虑使用Is、Can或Has等表示是否的前缀命名布尔类型的属性、字段。
✔️ 考虑使用下划线_做前缀,后跟属性名的方式命名属性所封装的私有字段。
✔️ 考虑使用On前缀或Has-Done的形式命名事件。
[禁止]:
✖️ 禁止为类名,结构体名添加前缀。
✖️ 禁止使用动词性短语命名字段。
命名有以下正确示例:
Person (类名) RadarData (结构体名) ILinkable (接口名) public void CountCentrePoint(int startPoint, int endPoint) (方法名,形参名) private int _Age (字段名) public int Age (属性名) protected bool IsActive (bool字段名) public bool CanTouch (bool字段名) public UnityEvent HasEnterProtectedZone (事件名) public UnityEvent OnTouchNode (事件名)
[要求]:
✔️ 务必遵从PascalCasing规范命名c#代码文件
✔️ 务必使用与类名一致的文件名。
[禁止]:
✖️ 禁止使用数字前缀或后缀区分源码文件。
.cs文件命名有以下正确示例:
KeyboardManager.cs PositionClipNode.cs
[要求]:
✔️ 务必保证一个文件夹下只包含一种文件,按照文件类型分类。
项目文件夹命名有以下正确示例:
+Textures (Textures文件夹下全为纹理文件夹或文件) |----Trees |----Rockets |----background_island_AO.png Models (Models文件夹下全为模型文件夹或文件) |----J20 |----Carrier |----player.fbx
[要求]:
✔️ 务必使用下划线_做分割,以形成大小类型的包含关系。
✔️ 务必保证文件名中单词顺序从大类向小类排列。
✔️ 务必使用形容词性或状态、动作描述性的后缀命名同一大类资源的不同文件。
✔️ 考虑在形容词性后缀不足以区分时,添加两位数字作为后缀,并在高位补零对齐。
[禁止]:
✖️ 禁止使用前缀区分同一大类下的不同文件,前缀区分会导致文件排序混乱。
非源码资源命名有以下正确示例:
+Models |----tree_small_trunk.fbx |----tree_small_leaves.fbx |----tree_small_roots.fbx (从大到小做分类命名) vehicle_truck_damaged.anim vehicle_truck_normal.anim (使用形容词性的后缀区分) vehicle_truck_run_01.anim vehicle_truck_run_02.anim (添加两位数字后缀区分)
[要求]:
✔️ 务必统一使用tab缩进,并在IDE中设置缩进为4个空格。
✔️ 务必保证所有花括号{}均独占一行。
✔️ 务必保证单行代码长度限制在100个字符,超长则换行。换行符不可在字符串中。参数过长则换行后逗号置行首,判断式过长则逻辑判断符置行首,以参数对齐或表达式对齐为目标。除此外换行缩进4个空格,第二次换行不缩进,与第一次缩进对齐。
[禁止]:
✖️ 禁止使用四个空格代替tab缩进。
✖️ 禁止在字符串中换行。
有以下正确的缩进及换行示例:
void function(int a , char b , short c , object k , string y) { //参数换行示意 } if( (expression01) && (expression02) && (expression03) || (expression04) ) { //表达式换行示意 }
为使代码结构清晰,不同类型及层级的代码块间必须用空行隔离。
[要求]:
✔️ 务必保证接口和类定义之间空两行。
✔️ 务必保证枚举和类定义之间空两行。
✔️ 务必保证类和类定义之间空两行。
✔️ 务必保证方法和方法,属性和方法, 字段和方法,字段和属性之间空一行。
✔️ 务必保证方法中变量声明和操作语句之间空一行。
✔️ 务必保证方法中不同逻辑块之间空一行。
✔️ 务必保证return语句与其他语句之间空一行。
✔️ 务必保证注释与被注释语句间不空行,但与其余所有语句间空一行。
[禁止]:
✖️ 禁止使用任意形式的注释行代替空行分割代码。
✖️ 禁止使用空行作为代码文件开头。
✖️ 禁止在代码文件结尾使用空行。
使用代码空行布局有以下正确示例:
interface IComputable { //... } //接口和类定义之间空两行 //<第二行> public class Person { private int _Age; private string _Name; //字段和属性之间 public int Age { get { return _Age; } } public string Name { //... } //属性和方法之间 public void FirstMethod() { } //方法和方法之间 public int SecondMethod() { //...逻辑代码 //return语句与其他语句之间空一行 return para; } }
[要求]:
✔️ 务必保证除了.以外,所有二元操作符左右需要使用空格分开。
✔️ 务必使用逗号分割多个参数,逗号后跟一个空格。
[禁止]:
✖️ 禁止省略花括号{},即使if、while、do、for等逻辑块内只有单行语句或为空。
对空格和括号的要求有以下正确示例:
int k = a + b; //二元操作符前后均需要使用一个空格 public string ClipStr(string str, int starIndex, int endIndex) //形参逗号后跟一个空格 if(index > 0) { //单行语句也不可省略花括号 str = null; }
[要求]:
✔️ 务必保证类的定义中按照字段->属性->事件->方法的顺序进行布局。
✔️ 务必保证各类成员内部按照private->protected->public的访问权限排序。
[禁止]:
✖️ 禁止方法先于字段申明。
类中布局有以下正确示例:
public class Person { private int _Age; protected string Name; public double height; public int Age { get { return _Age; } } public UnityEvent OnNameChange; private void Jump() { //... } protected int Count() { //... } public void SayHello() { //... } }
为方便团队合作,代码维护,所有源码文件均需要一定量的注释辅助说明。
[要求]:
✔️ 务必保证类定义之前使用XML注释描述该类的作用。
✔️ 务必保证重要的标志类属性后跟单行注释说明各个状态含义。
✔️ 务必保证方法定义之前使用XML注释描述该方法的作用、用法和形参列表,必要时指出参数含义。
✔️ 务必对方法中的重要逻辑选择使用单行或多行注释详细说明,若为多行注释,务必保证被注释的方法紧跟在注释行后。
[禁止]:
✖️ 禁止使用注释分割代码块,或使用注释排版代码。
有以下正确的注释示例:
///<summary> ///描述该类的作用 ///</summary> public class Person { private int ChoosenState; //用于表示被选中状态,1为xxx,2为xxx,3为xxx /// <summary> /// 按页面分类获取轮播列表; /// 当xxx情况时xxx,出现yyy情况时yyy /// </summary> /// <param name="call">接口响应</param> /// <param name="parentId">父id</param> /// <returns>DtoBanner,xxx情况下返回null</returns> public static DtoBanner ListByType(AppCall call, int parentId) { // 描述逻辑 // ... return null; } }
所有项目前两级目录使用统一标准,三级及以下目录不做要求,可自行命名,但务必遵从命名规范。
[要求]:
✔️ 务必保证新建项目后按照示例建立标准目录结构。
[禁止]:
✖️ 禁止在shader文件上右键创建material,这样材质文件会自动生成在shader文件夹下。
✖️ 禁止将资源直接放在Assets文件夹下。
目录结构严格按照以下示例建立:
Assets +---_Scenes # 使用下划线开头,保证场景文件夹在第一位 +---01_Prefabs +---02_Motions | +---Animations | +---Animators | +---Timeline # 存放timeline相关的playable等文件 +---03_Models +---04_Materials +---05_Textures # 材质、光照贴图 +---06_Effects | +---Videos | +---Sounds | +---VFX # 存放后处理等视觉效果文件 +---07_UI # 存放界面相关图素 | +---Sprites | +---Fonts | +---Mask +---08_Src | +---Scripts | +---Shaders # 包括Shader文件和Shadergraph \```
脚本文件夹下的三级目录结构不作要求,但应有第三级目录,按照脚本作用对象或功能做分类,并推荐将脚本命名空间与脚本目录结构联系起来。
Scripts文件夹下示例结构如下:
Scripts +---Enviroment +---Tools +---UI \```
[要求]:
✔️ 务必使用形如"-----Xxxx-----"的空物体分割Hierarchy结构。
✔️ 务必将所有对坐标和朝向无要求的GameObject的Transform组件设置为原始状态,如挂载体感脚本的物体。
✔️ 务必在需要添加Components的模型上层新建一个空GameObject父物体作为相关组件挂载点,即所有模型上套一层空GameObject作为逻辑层。
✔️ 考虑仅使用预制体作为运动或逻辑单元,例如,只在开发前期访问Models文件夹,后期只访问Prefabs文件夹。
[禁止]:
✖️ 禁止将组件直接挂载在mesh组件所在的GameObject上。
Scene Hierarchy及物体层级设计有以下正确示例:
-----Lights----- # 必须使用空物体构建Hierarchy中的结构 #此处放置场景中不随物体移动的静态光照,探针等# -----Managers----- InputManager # 挂载键盘,鼠标,手柄,手势,体感等管理脚本 SceneManager # 挂载管理场景的脚本,如切换场景 LogicManager # 挂载各种不依赖挂载点的逻辑处理脚本 -----ExternalUI----- #此处放置与第二显示器上UI相关的GameObject# -----Environments----- #此处放置环境模型,全局后处理等物体# -----Xxxxx------ \``````
[要求]:
✔️ 务必使用FBX格式将模型导入Unity项目。
✔️ 务必在建模软件中直接将模型中心设置在转轴交点处或方便操控移动的质心处,以方便控制模型在Unity中的转动,移动。
✔️ 务必保证模型使用左手坐标系,尺寸单位选择公制单位米,各轴缩放均归一化到1。
[禁止]:
✖️ 禁止为了实现转动,在Unity中使用脚本给出旋转轴的偏移量,旋转中心应在模型导出前设置标准。
模型标准参数有以下示例:
+Y up, +Z forward, +X right (左手坐标系) Metric Unit System (选择公制单位米) Scale: 1:1:1 (三轴缩放值必是1)
[要求]:
✔️ 务必保证贴图文件格式统一为PNG、TIFF、HDR。
✔️ 务必保证贴图文件为正方形,且边长为2的整数次幂,依次为128x128、256x256、512x512、1024x1024 ```。
✔️ 务必使用统一后缀区分材质贴图文件。
材质贴图后缀如下表:
Suffix | Textures |
---|---|
_AL | Albedo |
_SP | Specular |
_R | Roughness |
_MT | Metallic |
_GL | Glossiness |
_N | Normal |
_H | Height |
_DP | Displacement |
_EM | Emission |
_AO | Ambient Occlusion |
_M | Mask |