Unity 对 C# 语言的支持包括使用指令,这些指令允许您根据是否定义了某些脚本符号从而有选择性地在编译中包含或排除代码。有关这些指令如何在 C# 中工作的更多信息,请参阅 Microsoft 关于 C# 预处理器指令的文档。
Unity 具有一系列预定义符号,可以在脚本中使用它们来有选择性地包含或排除编译中的代码部分。例如,在 Windows 独立平台的项目构建中定义的符号为 UNITY_STANDALONE_WIN。可以检查是否使用特殊类型的 if 语句对此符号进行了定义:
#if UNITY_STANDALONE_WIN
Debug.Log("Standalone Windows");
#endif
#if 和 #endif 前面的哈希 (#) 字符表示这些语句是在编译过程中处理的指令,而不是在运行时处理的指令。在前面的示例中,调试行仅包含在项目的 Windows 独立构建中以供编译。在 Unity 编辑器或其他目标构建中编译时,它会被完全省略。这与使用常规 if 语句不同,后者可能仅会在运行时绕过某些代码段的执行。
可以使用 #elif 和 #else 指令来检查多个条件:
#if UNITY_EDITOR
Debug.Log("Unity Editor");
#elif UNITY_IOS
Debug.Log("Unity iOS");
#else
Debug.Log("Any other platform");
#endif
有几个预定义符号可用于根据所选平台、编辑器版本和其他系统环境情况来有选择性地编译或省略代码。有关 Unity 预定义符号的完整列表,请参阅 Unity 脚本符号参考。
此外,还可以使用编辑器、通过脚本或通过资源文件来定义专属的脚本符号。有关更多信息,请参阅自定义脚本符号。
注意:脚本符号也称为“定义符号”、“预处理器定义”或简称为“定义”。
在有条件地包含或排除代码时,预处理器指令并非总是最合适或最可靠的方法。此处列出了其他方法。
Conditional 属性可使用 C# Conditional 属性,这是一种更简洁、更不容易出错的函数剥离方式。有关更多信息,请参阅 ConditionalAttribute 类。Start()、Update()、LateUpdate()、FixedUpdate()、Awake() 等常见的 Unity 回调不受此属性的影响,因为它们是直接从引擎调用的,并且出于性能原因,此属性不会考虑它们。
对于高级条件编译,建议的做法是将脚本组织到具有关联程序集定义文件的程序集内。如果要有条件包含或排除的代码位于程序集内,则可以对程序集定义配置定义约束 (Define Constraints),例如,仅在项目中存在指定版本的包时编译代码。
可以使用标准 if 语句强制进行已编译代码的条件执行,而不是条件编译。例如,Unity 的 UNITY_64 脚本符号对于 64 位架构无法进行可靠的测试,因此最好执行以下操作:
if (IntPtr.Size == 4)
{
// 32 bit code
}
else
{
// 64-bit code
}