Unity 平台编译预定义

Platform dependent compilation

Unity’s Platform Dependent Compilation feature consists of some preprocessor directives that let you partition your scripts
 to compile and execute a section of code exclusively for one of the supported platforms.

You can run this code within the Unity Editor, so you can compile the code specifically for your target platform and test it in the Editor.

Platform #define directives

The platform #define directives that Unity supports for your scripts are as follows:

DefineFunction
UNITY_EDITOR#define directive to call Unity Editor scripts from your game code.
UNITY_EDITOR_WIN#define directive for Editor code on Windows.
UNITY_EDITOR_OSX#define directive for Editor code on Mac OS X.
UNITY_EDITOR_LINUX#define directive for Editor code on Linux.
UNITY_STANDALONE_OSX#define directive to compile or execute code specifically for Mac OS X (including Universal, PPC and Intel architectures).
UNITY_STANDALONE_WIN#define directive for compiling/executing code specifically for Windows standalone applications.
UNITY_STANDALONE_LINUX#define directive for compiling/executing code specifically for Linux standalone applications.
UNITY_STANDALONE#define directive for compiling/executing code for any standalone platform (Mac OS X, Windows or Linux).
UNITY_WII#define directive for compiling/executing code for the Wii console.
UNITY_IOS#define directive for compiling/executing code for the iOS platform.
UNITY_IPHONEDeprecated. Use UNITY_IOS instead.
UNITY_ANDROID#define directive for the Android platform.
UNITY_PS4#define directive for running PlayStation 4
 code.
UNITY_XBOXONE#define directive for executing Xbox One
 code.
PLATFORM_LUMIN#define directive for the Magic Leap OS platform.
UNITY_TIZEN#define directive for the Tizen platform.
UNITY_TVOS#define directive for the Apple TV platform.
UNITY_WSA#define directive for Universal Windows Platform
. Additionally, NETFX_CORE is defined when compiling C# files against .NET Core and using .NET scripting backend
.
UNITY_WSA_10_0#define directive for Universal Windows Platform. Additionally WINDOWS_UWP is defined when compiling C# files against .NET Core.
UNITY_WINRTSame as UNITY_WSA.
UNITY_WINRT_10_0Equivalent to UNITY_WSA_10_0
UNITY_WEBGL#define directive for WebGL
.
UNITY_FACEBOOK#define directive for the Facebook platform (WebGL or Windows standalone).
UNITY_FACEBOOK#define directive for the Facebook platform (WebGL or Windows standalone).
UNITY_ADS#define directive for calling Unity Ads methods from your game code. Version 5.2 and above.
UNITY_ANALYTICS#define directive for calling Unity Analytics
 methods from your game code. Version 5.2 and above.
UNITY_ASSERTIONS#define directive for assertions control process.

You can also compile code selectively. The options available depend on the version of the Editor that you are working on. Given a version number X.Y.Z (for example, 2.6.0), Unity exposes three global #define directives in the following formats: UNITY_XUNITY_X_Y and UNITY_X_Y_Z.

Here is an example of #define directives exposed in Unity 5.0.1:

DefineFunction
UNITY_5#define directive for the release version of Unity 5, exposed in every 5.X.Y release.
UNITY_5_0#define directive for the major version of Unity 5.0, exposed in every 5.0.Z release.
UNITY_5_0_1#define directive for the minor version of Unity 5.0.1.

Starting from Unity 5.3.4, you can compile code selectively based on the earliest version of Unity required to compile or execute a given portion of code. Given the same version format as above (X.Y.Z), Unity exposes one global #define in the format UNITY_X_Y_OR_NEWER, that can be used for this purpose.

The supported #define directives are:

DefineFunction
CSHARP_7_3_OR_NEWERDefined when building scripts with support for C# 7.3 or newer.
ENABLE_MONOScripting backend #define for Mono.
ENABLE_IL2CPPScripting backend #define for IL2CPP
.
NET_2_0Defined when building scripts against .NET 2.0 API compatibility level on Mono and IL2CPP.
NET_2_0_SUBSETDefined when building scripts against .NET 2.0 Subset API compatibility level on Mono and IL2CPP.
NET_LEGACYDefined when building scripts against .NET 2.0 or .NET 2.0 Subset API compatibility level on Mono and IL2CPP.
NET_4_6Defined when building scripts against .NET 4.x API compatibility level on Mono and IL2CPP.
NET_STANDARD_2_0Defined when building scripts against .NET Standard 2.0 API compatibility level on Mono and IL2CPP.
ENABLE_WINMD_SUPPORTDefined when Windows Runtime support is enabled on IL2CPP. See Windows Runtime Support for more details.
ENABLE_INPUT_SYSTEMDefined when the Input System package is enabled in Player Settings
.
ENABLE_LEGACY_INPUT_MANAGERDefined when the legacy Input Manager
 is enabled in Player Settings.

You use the DEVELOPMENT_BUILD #define to identify whether your script is running in a player which was built with the “Development Build
” option enabled.

You can also compile code selectively depending on the scripting back-end.

Testing precompiled code

Below is an example of how to use the precompiled code. It prints a message that depends on the platform you have selected for your target build.

First of all, select the platform you want to test your code against by going to File > Build Settings. This displays the Build Settings window; select your target platform from here.

 

Build Settings window with PC, Mac & Linux selected as the target platforms

Select the platform you want to test your precompiled code against and click Switch Platform to tell Unity which platform you are targeting.

Create a script and copy/paste the following code:

// C#
using UnityEngine;
using System.Collections;

public class PlatformDefines : MonoBehaviour {
  void Start () {

    #if UNITY_EDITOR
      Debug.Log("Unity Editor");
    #endif
    
    #if UNITY_IOS
      Debug.Log("Iphone");
    #endif

    #if UNITY_STANDALONE_OSX
    Debug.Log("Stand Alone OSX");
    #endif

    #if UNITY_STANDALONE_WIN
      Debug.Log("Stand Alone Windows");
    #endif

  }          
}

To test the code, click Play Mode. Confirm that the code works by checking for the relevant message in the Unity console, depending on which platform you selected - for example, if you choose iOS
, the message “Iphone” is set to appear in the console.

In C# you can use a CONDITIONAL attribute which is a more clean, less error-prone way of stripping out functions. See ConditionalAttribute Class for more information. Note that common Unity callbacks (ex. Start(), Update(), LateUpdate(), FixedUpdate(), Awake()) are not affected by this attribute because they are called directly from the engine and, for performance reasons, it does not take them into account.

In addition to the basic #if compiler directive, you can also use a multiway test in C#:


#if UNITY_EDITOR
    Debug.Log("Unity Editor");

#elif UNITY_IOS
    Debug.Log("Unity iPhone");

#else
    Debug.Log("Any other platform");

#endif


Platform custom #defines

It is also possible to add to the built-in selection of #define directives by supplying your own. Open the Other Settings panel of the Player settings and navigate to the Scripting Define Symbols text box.

 

Enter the names of the symbols you want to define for that particular platform, separated by semicolons. These symbols can then be used as the conditions for #if directives, just like the built-in ones.

Global custom #defines

You can define your own preprocessor directives to control which code gets included when compiling. To do this you must add a text file with the extra directives to the Assets
 folder. The name of the file depends on the language you are using. The extension is .rsp:

  
C# (player and editor scripts)<Project Path>/Assets/mcs.rsp

As an example, if you include the single line -define:UNITY_DEBUG in your mcs.rsp file, the #define directive UNITY_DEBUG exists as a global #define for C# scripts, except for Editor scripts.

Every time you make changes to .rsp files, you need to recompile in order for them to be effective. You can do this by updating or reimporting a single script (.js or .cs) file.

Note:__If you want to modify only global #define directives, use Scripting Define Symbols__ in Player settings, because this covers all the compilers. If you choose the .rsp files instead, you need to provide one file for every compiler Unity uses.

The use of .rsp files is described in the ‘Help’ section of the mcs application, which is included in the Editor installation folder. You can get more information by running mcs -help.

Note that the .rsp file needs to match the compiler being invoked. For example:

  • when targeting the .NET 3.5 Equivalent (deprecated) scripting runtime version, mcs is used with mcs.rsp, and
  • when targeting the .NET 4.x Eqivalent scripting runtime version compiler, csc is used with csc.rsp.
<think>首先,用户的问题是关于“buildoptions中预定义指令代码”,具体是“buildoptions预定义指令代码”。我需要回想上下文。用户提供了几个引用,但指令明确指出:这些引用仅供参考,并不是用户真正的需求,我应该尽可能多地参考用户上一次的问题和我的回答。 看一下对话历史: - 系统指令:关于数学表达式格式、中文回答等。 - 用户消息:用户引用了站内引用[1]到[4],这些是关于Unity编辑器指令、项目工程结构、CMAKE_BUILD_TYPE等。最后,用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。我想查找buildoptions中预定义指令代码 请问buildoptions预定义指令代码” 用户明确说这些引用不是真正的需求,我应该参考用户上一次的问题和我的回答。但在这个会话中,这是我的第一条消息之前的上下文吗?在给定的消息中,这是“用户可见层”的第一条消息,所以我需要检查之前的交互。 在系统指令后,用户发送了这条消息,其中包括引用和最后的问题。用户说“参考用户上一次的问题”,但在整个对话中,这是第一个用户消息(在系统指令后)。系统指令是一个通用指令,然后用户发送了这个。所以,可能没有上一次的问题。 用户的消息中以“参考站内引用:...”开头,然后指定这些引用仅供参考,不是真正需求,我应该参考用户上一次的问题和我的回答。但既然这是第一条消息,没有“上一次的问题”。我需要专注于当前问题。 当前问题是:“我想查找buildoptions中预定义指令代码 请问buildoptions预定义指令代码” 关键短语是“buildoptions预定义指令代码”。看起来用户在询问Build Options中的预定义指令代码。 在用户提供的引用中: - 引用[1]:关于Unity的预处理器指令,如 #if UNITY_EDITOR。 - 引用[2]:关于项目工程结构。 - 引用[3]:关于CMAKE_BUILD_TYPE。 - 引用[4]:关于SET_ATTITUDE_TARGET。 这些引用似乎与构建系统、CMake、Unity等相关。 用户提到“buildoptions”,这可能指的是构建选项,比如在CMake或类似构建系统中设置的选项。 从引用[3],它提到了CMAKE_BUILD_TYPE,这与构建类型配置相关。 或许用户在CMake上下文中询问预定义指令代码。 用户说“预定义指令代码”,这可能类似于预处理器指令或宏定义。 在C/C++编程中,预定义指令如 #define,或编译器特定的指令。 在构建系统中,如CMake,你可以定义变量或宏。 用户指定了“buildoptions”,所以我应该考虑构建选项中的预定义。 回想系统指令:我需要用中文回答,生成相关问题。 结构:回答应清晰,帮助用户逐步解决问题。 首先,我需要理解“buildoptions”。可能用户指的是构建系统如CMake中的选项设置。 在CMake中,你可以使用 add_definitions() 或 target_compile_definitions() 来添加预定义宏。 例如,在CMakeLists.txt 文件中,你可以添加 -DMY_MACRO 来定义宏。 类似地,在Unity或其他框架中,也有预定义指令。 用户提到了“UNITY_EDITOR”,这是一个预定义指令。 但用户的问题是关于“buildoptions”,所以我假设是在构建配置中。 可能的回答结构: 1. 解释什么是buildoptions中的预定义指令代码。 2. 提供如何在常见构建系统中设置它们。 3. 举例说明。 4. 生成相关问题。 系统指令要求添加引用标识,例如[^1],但我需要确保只在引用段落末尾添加。 在用户提供的引用中,有[^1]到[^4],但我应该只使用我回答中的相关信息。 用户说“参考站内引用”,但这些仅供参考,不是真正需求。所以,我可以忽略它们或仅作参考。 真正需求是“buildoptions预定义指令代码”。 在软件开发中,构建选项中的预定义指令通常指的是编译时宏定义。 例如: - 在CMake中:target_compile_definitions(my_target PUBLIC MY_DEFINE=1) - 在Makefile中:-DDEBUG - 在Unity中,使用 #if UNITY_EDITOR,但这是在代码中。 用户问题聚焦在“buildoptions”中,意思是构建配置部分。 所以,我应该提供一般指导。 用中文回答。 生成相关问题。 步骤: 1. 定义概念:解释什么是buildoptions中的预定义指令代码。 2. 如何设置:在常见的构建系统中。 3. 示例。 4. 相关问题。 引用:用户提供了引用,但我可以引用它们如果相关。 例如,引用[1]关于UNITY_EDITOR,引用[3]关于CMAKE_BUILD_TYPE。 在回答中,如果需要,添加 [^数字]。 现在,构建回答。 开头:直接回答问题。 例如:在构建系统中,预定义指令代码通常指的是在编译时定义的宏或预处理器指令,用于条件编译或配置。 然后,具体到不同系统。 常见构建系统:CMake、Make、 IDE如Visual Studio等。 用户提到了“buildoptions”,可能源于CMake或其他。 在引用[2]和[3]中,有CMakeLists.txt,所以或许CMake相关。 用户说“buildoptions”,可能是一个术语。 在CMake中,有选项或定义。 使用add_definitions或更现代的target_compile_definitions. 例如: 在CMake中添加预定义宏: target_compile_definitions(my_target PRIVATE MY_MACRO=1) 或使用配置变量。 在引用[3],CMAKE_BUILD_TYPE 可以用于设置构建类型,release或debug,并自动定义宏如NDEBUG。 CMAKE_BUILD_TYPE=Debug通常定义DEBUG宏。 在CMake中,你可以手动添加其他定义。 所以,回答内容: - 解释预定义指令。 - 如何在CMake中设置:使用target_compile_definitions或add_definitions. - 示例代码。 生成相关问题。 最后,添加引用标识如果引用任何参考。 例如,如果提到UNITY_EDITOR,可以引用[^1]。 但用户说这些仅供参考,所以不一定需要。 为了完整性,我可以参考。 现在,写出回答。 </think>### BuildOptions中的预定义指令代码解释 在软件开发中,“BuildOptions”(构建选项)通常指构建系统(如CMake、Make、Visual Studio等)中设置的编译时配置,用于定义预处理器指令(宏)。这些预定义指令允许在代码中通过 `#ifdef` 或 `#if` 进行条件编译,从而实现平台相关代码、调试开关或特性配置。以下是逐步解释和常见实现方式: #### 1. **什么是预定义指令代码?** - 预定义指令代码是指在构建过程中通过构建工具(如编译器或构建脚本)定义的宏(macros)。这些宏在编译代码前生效,可用于条件编译。 - 例如,在C/C++中,你可以使用 `#ifdef DEBUG` 来只在调试版本中包含代码片段。 - 这类指令通常在构建配置文件(如CMakeLists.txt或Makefile)中设置,而不是在源码中硬编码。 #### 2. **如何在常见构建系统中设置预定义指令?** - **CMake构建系统(最常用)**: - 使用 `target_compile_definitions()` 或 `add_definitions()` 命令来添加预定义宏。 - 示例:在CMakeLists.txt文件中定义宏 `MY_FEATURE`: ```cmake # 添加全局定义 add_definitions(-DMY_FEATURE=1) # 或针对特定目标(推荐) add_executable(my_target main.cc) target_compile_definitions(my_target PRIVATE ENABLE_DEBUG=1) ``` - 构建类型(如 `CMAKE_BUILD_TYPE`)也会自动定义宏: - `Debug` 模式通常定义 `DEBUG` 宏(部分编译器自动添加)。 - `Release` 模式定义 `NDEBUG` 宏(禁用断言)[^3]。 - 你可以自定义:`set(CMAKE_BUILD_TYPE "Debug")` 来启用调试宏。 - **Makefile构建系统**: - 在Makefile中使用编译器标志 `-D` 添加宏。 - 示例:定义 `VERSION=2`: ```makefile CFLAGS += -DVERSION=2 my_program: main.o gcc $(CFLAGS) -o my_program main.o ``` - **IDE构建工具(如Visual Studio)**: - 在项目属性中的“预处理器定义”设置宏。 - 例如,添加 `WIN32; _DEBUG;` 用于Windows调试版本。 - **Unity引擎(引用相关)**: - Unity在编辑器中自动定义 `UNITY_EDITOR` 宏,用于隔离编辑器专属代码(如工具脚本)。在独立构建中,该宏未定义,确保相关代码不编译到游戏中[^1]。 - 你可以通过Build Settings添加自定义宏(如Player Settings中的Scripting Define Symbols)。 #### 3. **示例代码和实际应用** - 假设在CMake项目中,你想定义一个宏 `USE_OPTIMIZED_MATH` 来切换数学函数: - **CMakeLists.txt**: ```cmake cmake_minimum_required(VERSION 3.10) project(MathProject) # 添加预定义宏 add_definitions(-DUSE_OPTIMIZED_MATH) # 或基于条件设置 if(${ENABLE_FEATURE}) target_compile_definitions(math_functions PUBLIC FEATURE_X=1) endif() add_subdirectory(math) # 引用子目录的CMakeLists.txt ``` - **代码中使用宏**(在MathFunctions.cc中): ```c #include "MathFunctions.h" double sqrt(double x) { #ifdef USE_OPTIMIZED_MATH // 优化版本代码 return fast_sqrt(x); #else // 标准版本代码 return standard_sqrt(x); #endif } ``` 这个示例中,`USE_OPTIMIZED_MATH` 宏在构建时定义,控制函数实现。项目工程结构如引用中提到的目录布局(根目录包含CMakeLists.txt,子目录math包含源码)[^2]。 #### 4. **注意事项** - **语法正确性**:预定义指令必须遵循编译器规则(如 `-DNAME` 或 `-DNAME=VALUE`)。在CMake中,变量名区分大小写。 - **性能影响**:合理使用预定义宏可减少运行时开销,但过度使用可能导致代码可读性降低。 - **兼容性**:确保宏定义在所有目标平台(如移动设备或独立应用)一致性测试,避免类似 `UNITY_EDITOR` 在非编辑器环境中未定义的问题[^1]。 如有具体构建系统或项目类型(如CMake、Unity),请提供更多细节,我可以进一步优化解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值