# Unity 中的条件编译

> An overview of how and when to use conditional compilation in your Unity scripts.

Unity 对 C# 语言的支持包括使用**指令**，这些指令允许您根据是否定义了某些**脚本符号**从而有选择性地在编译中包含或排除代码。有关这些指令如何在 C# 中工作的更多信息，请参阅 Microsoft 关于 [C# 预处理器指令](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives)的文档。

Unity 具有一系列预定义符号，可以在脚本中使用它们来有选择性地包含或排除编译中的代码部分。例如，在 Windows 独立平台的项目构建中定义的符号为 `UNITY_STANDALONE_WIN`。可以检查是否使用特殊类型的 `if` 语句对此符号进行了定义：

```
#if UNITY_STANDALONE_WIN

  Debug.Log("Standalone Windows");

#endif
```

`#if` 和 `#endif` 前面的哈希 (`#`) 字符表示这些语句是在编译过程中处理的指令，而不是在运行时处理的指令。在前面的示例中，调试行仅包含在项目的 Windows 独立构建中以供编译。在 Unity 编辑器或其他目标构建中编译时，它会被完全省略。这与使用常规 [if 语句](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/selection-statements)不同，后者可能仅会在运行时绕过某些代码段的执行。

可以使用 `#elif` 和 `#else` 指令来检查多个条件：

```
#if UNITY_EDITOR

    Debug.Log("Unity Editor");

#elif UNITY_IOS

    Debug.Log("Unity iOS");

#else

    Debug.Log("Any other platform");

#endif
```

有几个预定义符号可用于根据所选[平台](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md#Platform)、[编辑器版本](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md#Editor)和[其他](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md#Other)系统环境情况来有选择性地编译或省略代码。有关 Unity 预定义符号的完整列表，请参阅 [Unity 脚本符号参考](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md)。

此外，还可以使用编辑器、通过脚本或通过资源文件来定义专属的脚本符号。有关更多信息，请参阅[自定义脚本符号](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/custom-scripting-symbols.md)。

**注意：\*\*\*\*脚本符号**也称为“定义符号”、“预处理器定义”或简称为“定义”。

## 指令的替代方案##alternatives-to-directives

在有条件地包含或排除代码时，预处理器指令并非总是最合适或最可靠的方法。此处列出了其他方法。

### `Conditional` 属性##conditional-attribute

可使用 C# `Conditional` 属性，这是一种更简洁、更不容易出错的函数剥离方式。有关更多信息，请参阅 [ConditionalAttribute 类](https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute\(v=vs.110\).aspx)。`Start()`、`Update()`、`LateUpdate()`、`FixedUpdate()`、`Awake()` 等常见的 Unity 回调不受此属性的影响，因为它们是直接从引擎调用的，并且出于性能原因，此属性不会考虑它们。

### 程序集定义约束##assembly-definition-constraints

对于高级条件编译，建议的做法是将脚本组织到具有关联[程序集定义文件](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/assembly-definition-files.md)的程序集内。如果要有条件包含或排除的代码位于程序集内，则可以对程序集定义配置[定义约束 (Define Constraints)](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/assembly-definition-files.md#define-symbols)，例如，仅在项目中存在指定版本的包时编译代码。

### 条件执行##conditional-execution

可以使用标准 `if` 语句强制进行已编译代码的条件执行，而不是条件编译。例如，Unity 的 `UNITY_64` 脚本符号对于 64 位架构无法进行可靠的测试，因此最好执行以下操作：

```lang-csharp
if (IntPtr.Size == 4)
{
    // 32 bit code
}
else
{
    // 64-bit code
}
```

## 其他资源##additional-resources

* [如何在 Unity 中创建和使用脚本](/engine/6000.0/manual/scripting/get-started/creating-scripts.md)
* [Unity 脚本符号参考](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/symbol-reference.md)
* [测试条件编译代码](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/test.md)
* [自定义脚本符号](/engine/6000.0/manual/scripting/compilation-and-code-reload/script-compilation/conditional-compilation/custom-scripting-symbols.md)
