【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.mzph.cn/diannao/66859.shtml

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

相关文章

苍穹外卖08——(涉及接收日期格式数据、ApachePOI导出报表、sql获取top10菜品数据)

营业额统计 service层 在需要处理空值、与数据库交互或使用集合时,Integer 、Double是更好的选择。 // 导入string工具类 import org.apache.commons.lang.StringUtils; Service // 标记该类为Spring的服务组件 Slf4j // 引入日志功能 public class Repor…

微信小程序订阅消息提醒-云函数

微信小程序消息订阅分2种: 1.一次性订阅:用户订阅一次就可以推送一次,如果需要多次提醒需要多次订阅。 2.长期订阅:只有公共服务领域,如政务、医疗、交通、金融和教育等。‌在用户订阅后,在很长一段时间内…

青少年编程与数学 02-006 前端开发框架VUE 22课题、状态管理

青少年编程与数学 02-006 前端开发框架VUE 22课题、状态管理 一、状态管理二、Vuex1. 安装Vuex2. 创建Vuex Store3. 在Vue应用中使用Store4. 在组件中使用状态5. 模块化Store 三、Vuex应用示例1. 创建项目2. 安装Vuex3. 设置Vuex Store4. 在主项目中使用Store5. 创建组件6. 更新…

代码随想录算法训练营第 4 天(链表 2)| 24. 两两交换链表中的节点19.删除链表的倒数第N个节点 -

一、24. 两两交换链表中的节点 题目:24. 两两交换链表中的节点 - 力扣(LeetCode) 视频:帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点_哔哩哔哩_bilibili 讲解:代码随想录 dummy-…

pycharm-pyspark 环境安装

1、环境准备:java、scala、pyspark、python-anaconda、pycharm vi ~/.bash_profile export SCALA_HOME/Users/xunyongsun/Documents/scala-2.13.0 export PATH P A T H : PATH: PATH:SCALA_HOME/bin export SPARK_HOME/Users/xunyongsun/Documents/spark-3.5.4-bin…

数据结构与算法之链表: LeetCode 146. LRU 缓存 (Ts版)

LRU 缓存 https://leetcode.cn/problems/lru-cache/description/ 描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 ke…

Three.js 渲染技术:打造逼真3D体验的幕后功臣

文章目录 前言一、着色器(Shaders)二、后处理(Post-processing)三、抗锯齿(Anti-aliasing)四、实时渲染与离线渲染五、光照模型与材质优化六、环境映射(Environment Mapping)七、纹理…

EFCore HasDefaultValueSql (续1 ValueGeneratedOnAdd)

前情:EFCore HasDefaultValueSql 小伙伴在使用 HasDefaultValueSql 时,对相关的 ValueGeneratedOnAdd 也有了疑问: ValueGeneratedOnAdd 和 HasDefaultValueSql 是 Entity Framework Core 中用于管理字段默认值的两种不同配置方式&#xff0…

通过Apache、Nginx限制直接访问public下的静态文件

一、Apache 在public目录下的.htaccess文件中添加如下规则&#xff0c;来拒绝除了指定文件类型之外的所有请求 <FilesMatch "\.(?!(jpg|jpeg|png|gif|css|js|ico)$)[^.]$">Order Allow,DenyDeny from all </FilesMatch> 上述配置表示仅允许访问.jpg …

远程和本地文件的互相同步

文章目录 1、rsync实现类似git push pull功能1. 基础概念2. 示例操作3. 定制化和进阶用法4. 定时同步&#xff08;类似自动化&#xff09; 2 命令简化1. 动态传参的脚本2. Shell 函数支持动态路径3. 结合环境变量和参数&#xff08;更简洁&#xff09;4. Makefile 支持动态路径…

AIOps 平台

AIOps&#xff08;Artificial Intelligence for IT Operations&#xff09;平台是一种结合人工智能&#xff08;AI&#xff09;技术和IT运营管理的解决方案&#xff0c;旨在通过自动化、智能化的手段优化企业IT系统的运行与管理。以下是AIOps平台的核心功能、优势以及常见的技术…

【大模型入门指南 07】量化技术浅析

【大模型入门指南】系列文章&#xff1a; 【大模型入门指南 01】深度学习入门【大模型入门指南 02】LLM大模型基础知识【大模型入门指南 03】提示词工程【大模型入门指南 04】Transformer结构【大模型入门指南 05】LLM技术选型【大模型入门指南 06】LLM数据预处理【大模型入门…

3DGabor滤波器实现人脸特征提取

import cv2 import numpy as np# 定义 Gabor 滤波器的参数 kSize 31 # 滤波器核的大小 g_sigma 3.0 # 高斯包络的标准差 g_theta np.pi / 4 # Gabor 函数的方向 g_lambda 10.0 # 正弦波的波长 g_gamma 0.5 # 空间纵横比 g_psi np.pi / 2 # 相位偏移# 生成 Gabor 滤…

【Linux】4.Linux常见指令以及权限理解(2)

文章目录 3. Linux指令3.1 ls指令和rm指令补充3.2 man指令&#xff08;重要&#xff09;3.3cp指令&#xff08;重要&#xff09;输出重定向3.3.1ubuntu20.04如何安装tree 3.4 mv指令&#xff08;重要&#xff09;mv指令更改文件名mv指令更改目录名 如何看待指令指令的重命名3.5…

Vue3初学之Element-plus

用于快速的上手开发&#xff0c;以做项目为导向&#xff0c;所以借用element-plus插件 发现淘宝的镜像有时候也是很慢的&#xff0c;还可以换个 npm config set registry https://registry.npmmirror.com 安装element-plus npm install element-plus --save 查看安装是否成…

vue2新增删除

&#xff08;只是页面实现&#xff0c;不涉及数据库&#xff09; list组件&#xff1a; <button click"onAdd">新增</button><el-table:header-cell-style"{ textAlign: center }" :cell-style"{ textAlign: center }":data&quo…

实用操作系统学习笔记

第1章 操作系统概述 操作系统基本概念 【基础知识】 操作系统&#xff1a;控制和管理整个计算机系统的硬件和软件资源&#xff0c;合理地组织、调度计算机的工作与资源的分配&#xff0c;进而为用户和其他软件提供方便接口与环境的程序集合。操作系统是计算机系统中最基本的…

k8s部署rocketmq踩坑笔记

给团队部署一个rocketmq4.8.0. k8s上部署的broker&#xff0c;注册到nameserver上是自己的pod ip&#xff0c;导致本机连接到的broker的pod ip&#xff0c;这个ip k8s集群外的机器是无法联通的。 nameserver上注册的是这个pod ipv4 尝试将broker的配置brokerIP1修改为注册到na…

【机器学习:八、逻辑回归】

逻辑回归&#xff08;Logistic Regression&#xff09; 1. 逻辑回归的引出 在现实世界中&#xff0c;许多问题都涉及到分类任务。例如&#xff1a; 判断一封邮件是否为垃圾邮件&#xff1b;预测某人是否会患某种疾病&#xff1b;确定图片中是否包含某种特定物体。 这些问题…

UI自动化测试保姆级教程①

欢迎来到阿妮莫的学习小屋慢也好&#xff0c;步子小也好&#xff0c;在往前走就好 目录 自动化测试 简介 作用 分类 优缺点 优点 缺点(误区) UI自动化测试 自动化测试使用场景 自动化测试实现时间 Selenium框架 特点 Web自动化测试环境部署 Selenium包安装 浏览…