Unity C#命名规范全解析

该文章已生成可运行项目,

Unity 命名规范简述2025

第一部分:C# 脚本命名规范

核心原则:

这是在C#及C#相关代码中常用的命名规则:

PascalCase (帕斯卡命名法): 每个单词的首字母都大写。

//例如

PlayerController, GameManager

camelCase (驼峰命名法): 第一个单词的首字母小写,后续单词的首字母大写。

//例如

playerHealth, isGameOver

驼峰式命名法存在一些拓展,比如_camelCase(以下划线开头的驼峰),此处不再举例

针对新手的一些特别提醒:

  1. 不到万不得已,不要使用拼音(不会英文可以使用翻译),就算不得不使用拼音,务必避免拼音首字母缩写开头。(GNAN,AN  .etc)
  2. 除非你和你的项目组超越了一般人类,否则我们不建议使用中文作为变量名,虽然C#支持该行为。(很快就会遇到UTF-8,GBK等问题,此问题会在后面注释部分简述)
  3. 不要使用无意义命名符,此处额外提醒一下竞赛相关和计算机相关的同学,不要使用a,b,c命名。i和j不在此列,他们仅用于循环。
  4. 除特殊情况外,不要在变量的中间中加入空格和_
  5. 不要使用c#保留的关键字作为变量名,原因显而易见。在涉及到多语言交互时,可能不得不使用某个语言的关键字,此时可以使用@(@class,@namespace),但此处不做详述,也不建议使用。
  6. 从总体上看,一个可能被外界调用的,公开的东西通常使用PascalCase及其衍生,一个内部调用的,私有的东西通常使用camelCase及其衍生。
  7. 命名规范最重要的一点是统一,你的命名方法在整个项目中应该完全一致。因为部分命名存在可选配置,

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 { getset; }//属性

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 : MonoBehaviourIDamageable

{

    /// <summary>

    /// 玩家当前是否处于无敌状态。

    /// </summary>

public bool IsInvincible { getprivate 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;

    }

}

注意:

  1. 避免复述代码的注释

// bad

i++; //  i 增加1

// good(当然正常情况下i++不需要注释)

i++; // 增加计数器以匹配从1开始的数组索引

  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---。

注意:

一致性是最重要的原则

你实际使用的规范和项目可能与本文略有不同,只要在整个项目和团队中保持严格一致,它就是一套可用的规范。

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值