【Unity高级】一文了解Unity 中的条件编译(附所有指令)

在这里插入图片描述

一、Unity中的条件编译

Unity 对 C# 语言的支持包括使用指令,这些指令允许您根据是否定义了某些脚本符号,选择性地包含或排除代码的编译。有关这些指令在 C# 中如何工作的更多信息,请参阅微软关于 C# 预处理器指令 的文档。

(一)预定义符号

Unity 提供了一系列预定义的符号,您可以在脚本中使用它们,选择性地包含或排除代码段的编译。例如,在 Windows 独立平台的项目构建中定义的符号是 UNITY_STANDALONE_WIN。您可以使用一种特殊类型的 if 语句检查此符号是否已定义:

#if UNITY_STANDALONE_WINDebug.Log("Standalone Windows");
#endif

#if#endif 前的井号(#)表示这些语句是编译过程中处理的指令,而不是在运行时处理的指令。在上述示例中,Debug 行仅在项目的 Windows 独立构建中包含在编译中。在 Unity 编辑器或其他目标构建中编译时,它会被完全省略。这与使用常规的 if 语句不同,后者可能仅在运行时绕过某些代码段的执行。

(二)多条件检查

您可以使用 #elif#else 指令来检查多个条件:

#if UNITY_EDITORDebug.Log("Unity Editor");
#elif UNITY_IOSDebug.Log("Unity iOS");
#elseDebug.Log("Any other platform");
#endif

(三)预定义符号的作用范围

Unity 有多个预定义符号,允许您根据所选平台、编辑器版本和其他系统环境场景,选择性地编译或省略代码。

二、Unity 脚本符号参考

(一)平台符号

Unity 根据创作和构建目标平台自动定义某些符号,具体如下:

定义功能
UNITY_EDITOR用于在游戏代码中调用 Unity 编辑器脚本的脚本符号。
UNITY_EDITOR_WIN用于 Windows 上编辑器代码的脚本符号。
UNITY_EDITOR_OSX用于 macOS 上编辑器代码的脚本符号。
UNITY_EDITOR_LINUX用于 Linux 上编辑器代码的脚本符号。
UNITY_EMBEDDED_LINUX用于嵌入式 Linux 的脚本符号。
UNITY_QNX用于 QNX 的脚本符号。
UNITY_STANDALONE_OSX用于专门为 macOS(包括 Universal、PPC 和 Intel 架构)编译或执行代码的脚本符号。
UNITY_STANDALONE_WIN用于专门为 Windows 独立应用程序编译/执行代码的脚本符号。
UNITY_STANDALONE_LINUX用于专门为 Linux 独立应用程序编译/执行代码的脚本符号。
UNITY_STANDALONE用于为任何独立平台(Mac OS X、Windows 或 Linux)编译/执行代码的脚本符号。
UNITY_SERVER用于为专用服务器(macOS、Windows 或 Linux)编译/执行代码的脚本符号。
UNITY_IOS用于为 iOS 平台编译/执行代码的脚本符号。
UNITY_ANDROID用于 Android 平台的脚本符号。
UNITY_TVOS用于 Apple TV 平台的脚本符号。
UNITY_VISIONOS用于 VisionOS 平台的脚本符号。
UNITY_WSA用于通用 Windows 平台的脚本符号。
UNITY_WSA_10_0用于通用 Windows 平台的脚本符号。
UNITY_WEBGL用于 Web 的脚本符号。
UNITY_ANALYTICS用于在游戏代码中调用 Unity Analytics 方法的脚本符号。
UNITY_ASSERTIONS用于断言控制流程的脚本符号。
UNITY_64用于 64 位平台的脚本符号。 实际上不建议使用,因为它在所有 64 位架构上并不适用,且同一平台上的不同 CPU 架构可能共享相同的编译程序集。要基于架构条件执行代码,请使用标准的 if 语句检查 IntPtr.Size,在 32 位进程中为 4,64 位进程中为 8。示例请参阅“指令的替代方案”。

(二)Unity 编辑器版本符号

Unity 根据您当前使用的 Unity 编辑器版本自动定义某些脚本符号。

假设版本号为 X.Y.Z(例如 2019.4.14),Unity 以以下格式暴露三个全局脚本符号:UNITY_XUNITY_X_YUNITY_X_Y_Z

以下是 Unity 2019.4.14 中暴露的脚本符号示例:

定义功能
UNITY_2019用于 Unity 2019 发行版本的脚本符号,在每个 2019.Y.Z 版本中均可见。
UNITY_2019_4用于 Unity 2019.4 主要版本的脚本符号,在每个 2019.4.Z 版本中均可见。
UNITY_2019_4_14用于 Unity 2019.4.14 次要版本的脚本符号。

您还可以基于编译或执行代码段所需的最早 Unity 版本有选择地编译代码。按照上述相同的版本格式(X.Y),Unity 以 UNITY_X_Y_OR_NEWER 的格式暴露一个全局 #define,您可以使用它来实现此目的。

(三)其他符号

Unity 定义的其他符号包括:

定义功能
CSHARP_7_3_OR_NEWER当使用支持 C# 7.3 或更高版本的编译脚本时定义。
ENABLE_MONOMono 的脚本后端 #define
ENABLE_IL2CPPIL2CPP 的脚本后端 #define
ENABLE_VR当目标构建平台支持 VR 时定义。 注意:这并不意味着当前启用了 VR 或安装了支持 VR 所需的插件和包。
NET_2_0当在 Mono 和 IL2CPP 上针对 .NET 2.0 API 兼容级别构建脚本时定义。
NET_2_0_SUBSET当在 Mono 和 IL2CPP 上针对 .NET 2.0 子集 API 兼容级别构建脚本时定义。
NET_LEGACY当在 Mono 和 IL2CPP 上针对 .NET 2.0 或 .NET 2.0 子集 API 兼容级别构建脚本时定义。
NET_4_6当在 Mono 和 IL2CPP 上针对 .NET 4.x API 兼容级别构建脚本时定义。
NET_STANDARD_2_0当在 Mono 和 IL2CPP 上针对 .NET Standard 2.0 API 兼容级别构建脚本时定义。
NET_STANDARD_2_1当在 Mono 和 IL2CPP 上针对 .NET Standard 2.1 API 兼容级别构建脚本时定义。
NET_STANDARD当在 Mono 和 IL2CPP 上针对 .NET Standard 2.1 API 兼容级别构建脚本时定义。
NETSTANDARD2_1当在 Mono 和 IL2CPP 上针对 .NET Standard 2.1 API 兼容级别构建脚本时定义。
ENABLE_WINMD_SUPPORT当在 IL2CPP 上启用 Windows Runtime 支持时定义。有关详细信息,请参阅Windows Runtime 支持。
ENABLE_INPUT_SYSTEM当在播放器设置中启用输入系统包时定义。
ENABLE_LEGACY_INPUT_MANAGER当在播放器设置中启用传统输入管理器时定义。
DEVELOPMENT_BUILD当您的脚本在启用了开发构建选项的播放器中运行时定义。 注意:此定义仅反映构建时是否启用了开发构建选项。要确定您的脚本是否正在以开发构建模式运行,请使用 Debug.isDebugBuild__DEVELOPMENT_BUILD__ 并不足以确定当前是否正在以开发构建运行,因为大多数平台允许在不重新构建项目的情况下在开发和非开发构建之间切换。然而,在某些平台上,Unity 不支持在编辑器中切换开发和非开发构建,需要在构建完成后进行切换。例如,在 Windows 上,您可以选择“创建 Visual Studio 解决方案”选项,以选择是否在 Visual Studio 中进行开发或非开发构建。Visual Studio 中的切换不会重新编译您的脚本,因此不会重新评估脚本定义。您还可以通过将游戏构建中的 UnityPlayer.dll 与开发构建中的 UnityPlayer.dll 互换,来从最终的游戏构建切换到开发构建,以调试实时游戏构建。
UNITY_CLOUD_BUILD当项目使用 Unity 构建自动化构建时定义。

注意DEBUG 符号在 C# 和 Unity 中是预定义的,使用指令 #if DEBUG 等同于 #if UNITY_EDITOR || DEVELOPMENT_BUILD

三、自定义脚本符号

除了 Unity 内置的脚本符号外,您还可以定义自己的自定义脚本符号。定义自定义脚本符号的位置决定了它们的适用范围。您可以在以下位置定义自定义符号:

  • 资产文件,适用于项目中所有编辑器和播放器代码的符号,无论活动的构建配置文件是什么。
  • 平台配置,适用于当特定平台或其构建配置文件处于活动状态时的所有编辑器和播放器代码的符号。
  • 构建配置文件,适用于当特定构建配置文件处于活动状态时的所有编辑器和播放器代码的符号。
  • 代码中,适用于活动平台或单个播放器构建,具体取决于使用的 API。

(一)适用于整个项目的自定义符号

您可以通过响应文件资产为整个项目定义自定义脚本符号,方法如下:

  1. 将文件命名为 csc.rsp 并将其放置在项目的 Assets 文件夹根目录中。
  2. 在以 -define: 开头的行中定义脚本符号,后跟一个或多个用分号分隔的脚本符号。
  3. Unity 会在启动时读取此文件,并在编译任何代码之前应用它。例如,如果在 csc.rsp 文件中包含单行 -define:UNITY_DEBUG;UNITY_TEST,则符号 UNITY_DEBUGUNITY_TEST 将作为全局定义的脚本符号包含在项目中的所有 C# 脚本中。

注意:对 .rsp 文件的更改在 Unity 重新编译脚本之前不会生效。您可以通过更新或重新导入单个脚本文件来触发重新编译。

(二)适用于特定平台的自定义符号

您可以通过以下步骤为特定平台定义自定义脚本符号:

  1. 打开 Player Setting
  2. 导航到 Other Settings > Script Compilation 部分中的 Script Define Symbols
  3. 通过选择 + 按钮并在文本字段中输入符号名称,将新的脚本符号添加到列表中。使用 - 按钮删除现有列表项。
  4. 编辑完成后,选择 Apply 以应用更改。Unity 会使用新的符号重新编译项目中的脚本。

在这里插入图片描述

注意复制定义 按钮会将当前自定义脚本符号列表中的符号作为分号分隔的字符串复制到剪贴板。

(三)适用于构建配置文件的自定义符号

您可以通过以下步骤为构建配置文件定义自定义脚本符号:

  1. Build Profile 窗口中选择要为其定义符号的构建配置文件。
  2. 导航到 Build Data 部分中的 Scripting Defines。(只有在自定义的Build Profile中才能看到)。
  3. 通过选择 + 按钮并在文本字段中输入符号名称,将新的脚本符号添加到列表中。使用 - 按钮删除现有列表项。对列表的修改会自动保存和应用。

在这里插入图片描述

注意:您可以使用 -activeBuildProfile 命令行参数启动编辑器,以使指定的构建配置文件及其自定义脚本符号从启动时即生效。

(四)从代码中定义自定义符号

您可以使用以下 API 来定义脚本符号:

  • PlayerSettings.SetScriptingDefineSymbols
  • BuildPlayerOptions.extraScriptingDefines
  • Build.Player.ScriptCompilationSettings.extraScriptingDefines

BuildPlayerOptions.extraScriptingDefinesBuild.Player.ScriptCompilationSettings.extraScriptingDefines 仅适用于播放器构建,因此在定义适用于编辑器脚本的脚本符号时,请使用 PlayerSettings.SetScriptingDefineSymbols。这是配置播放器设置中平台特定脚本符号的代码等效方法。

重要:使用 SetScriptingDefineSymbols 从代码创建的符号在编辑器重新获得控制并重新编译脚本之前不会生效。例如,如果您在编辑器脚本中使用 SetScriptingDefineSymbols 创建脚本符号,然后在下一行调用 BuildPipeline.BuildPlayer,则前一行创建的新符号尚未生效。在这种情况下,作为 BuildPlayer 执行一部分运行的任何编辑器代码都将在没有新符号的情况下运行,播放器可能无法按预期构建。

(五)批处理模式下的自定义符号

当编辑器以批处理模式运行时,没有机制可以触发脚本的重新编译。如果您需要在以批处理模式运行的编辑器中定义特定的符号,它们必须通过 csc.rsp 资产文件在启动时就到位。

(六)脚本符号继承

如果您在多个位置定义了自定义脚本符号,Unity 会将所有适用于当前构建配置的符号加在一起。符号是从每个作用域继承的,而不是被覆盖,具体如下:

  • 项目范围符号(来自 csc.rsp
  • 平台特定符号(来自播放器设置)
  • 构建配置文件符号(来自构建数据)

仅当与活动构建配置文件匹配时,才会包含平台和构建配置文件符号。

例如,假设您的项目在以下位置定义了以下自定义脚本符号:

位置定义的符号
csc.rspSYMBOL_A
Windows Player SettingSYMBOL_B
WindowsBuildProfile1SYMBOL_C
WindowsBuildProfile2SYMBOL_D

在此示例配置中,当不同的构建配置文件处于活动状态时,以下表格显示了哪些符号适用于您的编辑器和播放器代码:

Active Build ProfileActive Symbols
AndroidSYMBOL_A
WindowsSYMBOL_A, SYMBOL_B
WindowsBuildProfile1SYMBOL_A, SYMBOL_B, SYMBOL_C
WindowsBuildProfile2SYMBOL_A, SYMBOL_B, SYMBOL_D

您可以使用代码中的 #if 指令来测试这种行为。有关更多信息,请参阅 测试条件编译。

三、测试条件编译

以下示例展示了如何测试您的条件编译代码。它还根据为目标构建选择的平台在控制台中打印一条消息。

(一)示例代码

using UnityEngine;
using System.Collections;public class PlatformDefines : MonoBehaviour {void Start () {#if UNITY_EDITORDebug.Log("Unity Editor");#endif#if UNITY_IOSDebug.Log("Unity iOS");#endif#if UNITY_STANDALONE_OSXDebug.Log("Standalone OSX");#endif#if UNITY_STANDALONE_WINDebug.Log("Standalone Windows");#endif}          
}

(二)测试步骤

  1. 打开 Build Profiles 窗口(菜单:File > Build Profiles)。
  2. 检查您要测试代码的平台是否为活动平台配置文件。如果不是,请选择您首选的平台并点击 Switch Profile
  3. 创建一个脚本并复制粘贴上述示例代码。
  4. Game View Toolbar,点击 Play 按钮进入播放模式。通过检查 Unity 控制台中与所选平台相关的消息,确认代码是否正常工作。例如,如果您选择 iOS,则控制台中会出现 Unity EditorUnity iOS 的消息。

参考:

  1. https://docs.unity3d.com/Manual/scripting-symbol-reference.html

  2. https://docs.unity3d.com/Manual/custom-scripting-symbols.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/1644.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主数据系统建设模式分析

很多企业在长期的信息化建设和使用过程中,或多或少的存在数据一致性问题,这类问题导致了大量的数据手工梳理、清洗的工作,对于系统的对接以及统计分析造成了极大的不便,因此信息化部门的管理者迫切的想通过主数据项目来解决目前的…

Redis是单线程还是多线程?

大家好,我是锋哥。今天分享关于【Redis是单线程还是多线程?】面试题。希望对大家有帮助; Redis是单线程还是多线程? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis是 单线程 的。 尽管Redis的处理是单线程的&a…

UML系列之Rational Rose笔记一:用例图

好久没有更新笔记了;最近想整理下近期掌握的UML软件建模的知识笔记; 包括但不限于Rational Rose;Drawio;EA;PowerDesigner;Visio;StarUML;Software等软件的使用;UML软件…

熵权法(变异系数法)

熵权法(变异系数法) 一种客观赋权方法,它根据指标的变异程度来确定指标的权重,变异程度越大,说明该指标所包含的信息量越大,相应的权重也就越大。以下是熵权法的详细介绍: 概率与信息量的关系 概率P(x)越小,信息量I(…

基于当前最前沿的前端(Vue3 + Vite + Antdv)和后台(Spring boot)实现的低代码开发平台

项目是一个基于当前最前沿的前端技术栈(Vue3 Vite Ant Design Vue,简称Antdv)和后台技术栈(Spring Boot)实现的低代码开发平台。以下是对该项目的详细介绍: 一、项目概述 项目名称:lowcode-s…

JAVA:利用 RabbitMQ 死信队列实现支付超时场景的技术指南

1、简述 在支付系统中,订单支付的超时自动撤销是一个非常常见的业务场景。通常用户未在规定时间内完成支付,系统会自动取消订单,释放相应的资源。本文将通过利用 RabbitMQ 的 死信队列(Dead Letter Queue, DLQ)来实现…

逻辑测试题

https://blog.csdn.net/qq_39081315/article/details/121393597 先生成一个点,每生成一个点判断距离,角度,满足加入存点的容器,直到容器大小为4。 随机生成点: 分区域:最大距离20,以20为正方形…

图解Git——分支开发工作流《Pro Git》

分支开发工作流 由于分支管理的便捷, 才衍生出这些典型的工作模式,你可以根据项目实际情况选择。 1. 长期分支 适用于持续开发和发布周期长的项目。常见的长期分支包括: master:只保留稳定的代码,通常用于生产环境。…

IOS界面传值-OC

1、页面跳转 由 ViewController 页面跳转至 NextViewController 页面 &#xff08;1&#xff09;ViewController ViewController.h #import <UIKit/UIKit.h>interface ViewController : UIViewControllerend ViewController.m #import "ViewController.h" …

【Spring Boot 应用开发】-04-01 自动配置-数据源-连接池

资源关闭 还记得上一节中的这段代码么&#xff1f; try {if (resultSet ! null) resultSet.close();if (preparedStatement ! null) preparedStatement.close();if (connection ! null) connection.close(); } catch (SQLException e) {e.printStackTrace(); }这是我们在查询…

BUUCTF:misc刷题记录4(会持续更新的)

目录 爱因斯坦 ningen 做题总结&#xff1a; 爱因斯坦 下载解压后&#xff0c;得到一张图片。 老套路&#xff0c;还是先查看一下图片基本属性。只看到这串信息&#xff0c;不知道有啥用。 然后用010进行查看 发现图片里面隐藏了一个压缩包&#xff0c;压缩包里面有个flag.t…

Open FPV VTX开源之嵌入式OSD配置

Open FPV VTX开源之嵌入式OSD配置 1. 源由2. 安装3. 配置步骤一&#xff1a;备份/etc/telemetry.conf步骤二&#xff1a;修改/etc/telemetry.conf步骤三&#xff1a;配置时区步骤四&#xff1a;重启摄像头 4. 实测5. 参考资料 1. 源由 穿越机模拟图传延迟通常在10ms左右。 最…

JavaScript动态渲染页面爬取之Splash

Splash是一个 JavaScript渲染服务,是一个含有 HTTP API的轻量级浏览器,它还对接了 Python 中的 Twisted 库和 OT库。利用它&#xff0c;同样可以爬取动态渲染的页面。 功能介绍 利用 Splash&#xff0c;可以实现如下功能&#xff1a; 异步处理多个网页的渲染过程:获取渲染后…

HTTP详解——HTTP基础

HTTP 基本概念 HTTP 是超文本传输协议 (HyperText Transfer Protocol) 超文本传输协议(HyperText Transfer Protocol) HTTP 是一个在计算机世界里专门在 两点 之间 传输 文字、图片、音视频等 超文本 数据的 约定和规范 1. 协议 约定和规范 2. 传输 两点之间传输&#xf…

云服务信息安全管理体系认证,守护云端安全

在数据驱动的时代&#xff0c;云计算已成为企业业务的超级引擎&#xff0c;推动着企业飞速发展。然而&#xff0c;随着云计算的广泛应用&#xff0c;信息安全问题也日益凸显&#xff0c;如同暗流涌动下的礁石&#xff0c;时刻威胁着企业的航行安全。这时&#xff0c;云服务信息…

nacos环境搭建以及SpringCloudAlibaba脚手架启动环境映射开发程序

1&#xff1a;下载nacos 地址&#xff1a;https://github.com/alibaba/nacos/tags 2:选择server的zip包下载 3:启动mysql服务&#xff0c;新建数据库&#xff1a;nacos_yh 4&#xff1a;解压下载的nacos_server 进入conf目录 5&#xff1a;mysql运行sql脚本变得到下面的表 6&a…

stable diffusion 量化学习笔记

文章目录 一、一些tensorRT背景及使用介绍1&#xff09;深度学习介绍2&#xff09;TensorRT优化策略介绍3&#xff09;TensorRT基础使用流程4&#xff09;dynamic shape 模式5&#xff09;TensorRT模型转换 二、TensorRT转onnx模型1&#xff09;onnx介绍2&#xff09;背景知识&…

设计模式 行为型 访问者模式(Visitor Pattern)与 常见技术框架应用 解析

访问者模式&#xff08;Visitor Pattern&#xff09;是一种行为设计模式&#xff0c;它允许你在不改变元素类的前提下定义作用于这些元素的新操作。这种模式将算法与对象结构分离&#xff0c;使得可以独立地变化那些保存在复杂对象结构中的元素的操作。 假设我们有一个复杂的对…

C++中引用参数与指针参数的区别与联系详解

在C++中,函数参数可以通过值传递、引用传递和指针传递。虽然指针传递在C和C++中都非常常见,但C++引入了引用类型,使得引用传递变得更加直接和易用。本文将详细介绍函数中引用参数和指针参数的区别与联系,并通过C++语言代码示例加以说明。 一、基本概念 值传递(Pass by Val…

初识JVM HotSopt 的发展历程

目录 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 各大 JVM look 看一下虚拟机 HotSopt 的发展历程 总结 导学 目前企业对程序员的基本要求 面向的对象 实战 学习目标 JVM 是什么 JVM 的三大核心功能 即时编译 主要是…