遵守既定标准和最佳实践来编写可维护的代码。在虚幻游戏引擎中,存在着一些既定的编码标准和约定 ,养成良好的编码规范是写好一份优雅代码的第一步,并且在虚幻官方也强调了,某些编码标准的遵循是强制性的。
编码规约对程序员来说意味着什么
- 在软件开发中,软件生命周期的80%的成本都在维护上,几乎没有任何软件是由原作者终身维护的,游戏开发也不例外。
- 代码规约提高了代码可读性、使得工程师可以快速、彻底的理解代码。
- 编码规约帮助确保团队中的每个成员都遵循相同的代码风格和标准。这种一致性让开发人员在阅读和修改他人代码时,能快速理解其结构和意图,而不需要花费额外的时间去适应不同的风格。
- 编码规约可以帮助避免不一致和混乱的代码风格,减少随之而来的技术债务(technical debt)。长时间的不规范编码会导致难以维护和扩展的代码,遵循编码规约有助于保持代码的整洁性。
- 当团队成员都遵循统一的编码规约时,协作变得更加顺畅。代码审查(code review)也会变得更加高效,因为开发人员不需要花费大量时间去检查代码风格的问题,而是能更多地专注于代码的功能和质量。
- 编码规约帮助确保代码结构清晰,逻辑一致,使得调试过程更加简便。如果代码中存在问题,开发人员可以快速定位和修复问题,而不会因为风格混乱而增加调试难度。
- 对新成员而言,遵循团队的编码规约可以加速其熟悉代码库和开发流程的速度。如果每个人的编码风格差异较大,新成员可能需要花费更多时间去适应不同的代码风格。
- 在某些情况下,编码规约还可能是为了符合特定的行业标准或规范,尤其是在涉及到游戏引擎、平台兼容性、性能优化等方面时。遵循这些标准可以避免潜在的兼容性或性能问题。
本文提到的编码标准以 C++ 为中心;然而,无论使用哪种语言,都应该遵循该标准。某个部分可能会在适用的情况下为特定语言提供等效规则或例外情况。
命名约定
使用命名约定时,所有的代码和注释都应该使用英语进行命名。
-
名称(例如类型名称或变量名称)中每个单词的首字母大写。单词之间通常没有下划线。例如,
Health
和UPrimitiveComponent
是正确的,但lastMouseCoordinates
或delta_coordinates
则不正确。 -
类型名称带有一个额外的大写字母作为前缀,以将其与变量名称区分开。例如,
FSkin
是类型名称,而Skin
是类型FSkin
的实例。 -
模版类一T为前缀
template <typename ObjectType> class TAttribute
-
从UObject继承的类以 U 为前缀。
class UActorComponent
-
继承自AActor的类以 A 为前缀。
class AActor
-
从SWidget继承的类以 S 为前缀。
class SCompoundWidget
-
作为抽象接口的类以 I 为前缀。
class IAnalyticsProvider
-
枚举以 E 为前缀。
enum class EColorBits {ECB_Red, ECB_Green, ECB_Blue };
-
布尔类型变量必须以b为前缀
bPendingDestruction bHasFadedIn
-
类型和变量名称由名称组成。
-
方法名称是动词,要么描述方法的效果,要么描述没有效果的方法的返回值。
-
宏名称应完全大写,单词之间用下划线分隔,并以
UE_
为前缀。#define UE_AUDIT_SPRITER_IMPORT
-
名称的范围越大,一个好的描述性名称就越重要。避免过度缩写。
-
所有返回 bool 的函数都应该询问 true/false 问题,例如
IsVisible()
或ShouldClearBuffer()
bool IsVisible(); // "IsVisible" 是一个明确的询问:对象是否可见? bool ShouldClearBuffer(); // "ShouldClearBuffer" 明确地表示:是否应该清空缓冲区?
代码格式化
-
始终在代码中包含完整大括号,例如:
if (bThing) {return; }
-
if-else 语句中的每个执行块都应该放在大括号中。这有助于防止编辑错误。当不使用大括号时,有人可能会无意中向 if 块添加另一行。
if (bHaveUnrealLicense) {InsertYourGameHere(); } else {CallMarkRein(); }
-
多路 if 语句应该与每个
else if
缩进量与第一个if
相同;这使得读者可以清楚地了解结构:if (TannicAcid < 10) {UE_LOG(LogCategory, Log, TEXT("Low Acid")); } else if (TannicAcid < 100) {UE_LOG(LogCategory, Log, TEXT("Medium Acid")); } else {UE_LOG(LogCategory, Log, TEXT("High Acid")); }
更多相关的详细内容可以前往官方文档进行查阅:https://dev.epicgames.com/documentation/en-us/unreal-engine/epic-cplusplus-coding-standard-for-unreal-engine?application_version=5.4