如何查看 Unity 工程中实际生效的宏定义
如何查看 Unity 工程中实际生效的宏定义
在 Unity 工程中, 经常会遇到这类条件编译代码:
1
2
3
#if UNITY_2022_1_OR_NEWER
// ...
#endif
如果需要确认当前工程、当前 Assembly 实际定义了哪些宏, 最直接的方法是查看 Unity 生成的 .csproj 文件中的 DefineConstants。
1. 在 Rider 中查看 DefineConstants
按:
1
Ctrl + Shift + F
搜索:
1
<DefineConstants>
搜索范围选择整个解决方案。
在对应的 .csproj 中可以看到类似内容:
1
2
3
4
5
6
7
8
9
10
<DefineConstants>
TRACE;
UNITY_2021_3;
UNITY_2021;
UNITY_2021_3_OR_NEWER;
UNITY_2021_2_OR_NEWER;
UNITY_EDITOR;
UNITY_EDITOR_WIN;
...
</DefineConstants>
这里列出的内容, 就是当前 Assembly 实际使用的条件编译符号。
例如存在:
1
UNITY_2021_3_OR_NEWER
那么:
1
2
3
#if UNITY_2021_3_OR_NEWER
Debug.Log("Unity 2021.3 or newer");
#endif
这段代码就会参与编译。
2. 一定要查看正确的 .csproj
Unity 工程通常会生成多个 .csproj, 例如:
1
2
3
4
Assembly-CSharp.csproj
Assembly-CSharp-Editor.csproj
Example.Render.Runtime.csproj
Example.Render.Editor.csproj
假设某段代码位于一个名为:
1
Example.Render.Editor
的 Assembly 中, 那么应优先查看:
1
Example.Render.Editor.csproj
而不是只看:
1
Assembly-CSharp.csproj
原因是不同 Assembly 的 DefineConstants 可能不同。
推荐排查顺序:
1
2
3
4
目标代码
→ 确认所属 .asmdef
→ 找到对应 .csproj
→ 查看 DefineConstants
3. 只想确认某一个宏是否生效
如果只是快速验证某个宏, 可以直接写:
1
2
3
4
5
#if UNITY_2022_1_OR_NEWER
Debug.Log("Unity 2022.1+");
#else
Debug.Log("Older Unity");
#endif
Rider 通常会将当前不会参与编译的分支显示为灰色。
这种方式适合验证单个宏; 如果需要查看完整宏列表, 仍建议查看 DefineConstants。
4. Unity 宏的主要来源
Unity 工程中的条件编译符号主要来自三类来源:
1
2
3
4
5
6
7
8
9
10
11
Unity 自动定义
├─ UNITY_EDITOR
├─ UNITY_ANDROID
├─ UNITY_2021_3_OR_NEWER
└─ ...
Project Settings
└─ Scripting Define Symbols
.asmdef
└─ Version Defines
项目级自定义宏可以在:
1
2
3
4
Project Settings
→ Player
→ Other Settings
→ Scripting Define Symbols
中配置。
例如项目中定义:
1
ENABLE_CUSTOM_RENDERING
就可以写:
1
2
3
#if ENABLE_CUSTOM_RENDERING
CustomRender();
#endif
.asmdef 还可以通过 Version Defines 根据 Package 版本定义只对特定 Assembly 生效的宏。
例如某个 Assembly 可以根据 Package 版本生成:
1
HAS_RENDER_PIPELINE_14
然后在代码中使用:
1
2
3
#if HAS_RENDER_PIPELINE_14
// Code for the corresponding package version.
#endif
5. UNITY_xxx_OR_NEWER 的含义
Unity 的版本宏通常具有类似形式:
1
2
3
4
UNITY_2021
UNITY_2021_3
UNITY_2021_3_OR_NEWER
UNITY_2022_1_OR_NEWER
例如:
1
UNITY_2022_1_OR_NEWER
表示当前 Unity 版本满足:
1
Unity >= 2022.1
因此常见的跨版本代码会写成:
1
2
3
4
5
#if UNITY_2022_1_OR_NEWER
UseNewApi();
#else
UseLegacyApi();
#endif
不过在实际排查兼容性问题时, 与其只根据 Unity 版本号推测, 更可靠的方法仍然是直接查看目标 Assembly 的 DefineConstants。
原理
Unity 会为不同 C# Assembly 生成对应的 .csproj, 并将当前编译环境中的条件编译符号写入:
1
<DefineConstants>...</DefineConstants>
因此, DefineConstants 可以看作当前 Assembly 编译环境中实际宏定义的一份直接结果。
需要注意, .csproj 通常由 Unity 自动生成, 不应直接修改其中的 DefineConstants。
如果需要添加自定义宏, 应通过以下正式入口配置:
1
2
3
Scripting Define Symbols
.asmdef Version Defines
其他 Unity 提供的正式编译配置