Version: Unity 6.0 (6000.0)
语言 : 中文
API 更新程序
升级到 Unity 2023.2

升级到 Unity 6

本页面列出了从 2022 LTS 版本升级到 Unity 6 时可能对现有项目造成影响的更改。

渲染管线

本升级指南介绍如何升级到 Unity 6 版本的 Unity 内置渲染管线。要升级其他渲染管线,请参阅:

要升级其他包,请参阅所使用包的文档。

现在 LightingSettings 中的高斯滤波器半径 (Gaussian Filter Radius) 属性为浮点值

渐进式光照贴图 (Progressive Lightmapper) 在其高级 (Advanced) 滤波选项(光照窗口 (Lighting Window) > 光照贴图设置 (Lightmapping Settings) > 滤波 (Filtering) > 直接滤波器 (Direct Filter) > 高斯 (Gaussian))中包含高斯 (Gaussian) 选项。用于高斯 (Gaussian) 滤波的半径 (Radius) 控件现在支持小数递增,例如 0.5。以前,此控件仅支持整数步长(1 到 5)。

由于此更改,现在这些属性在 C# API 中已弃用:

  • int LightingSettings.filteringGaussRadiusAO
  • int LightingSettings.filteringGaussRadiusDirect
  • int LightingSettings.filteringGaussRadiusIndirect

已弃用属性的浮点替换如下:

  • float LightingSettings.filteringGaussianRadiusAO
  • float LightingSettings.filteringGaussianRadiusDirect
  • float LightingSettings.filteringGaussianRadiusIndirect

您可以调用一个已弃用成员函数将高斯滤波器半径四舍五入到最接近的整数。

光照探针节能改进

光照探针现在与光照贴图一样明亮。以前,Unity 的光照探针的亮度仅为应有亮度的 94%。因此,使用光照探针光照的对象看起来比使用光照贴图光照的对象暗一些。由于这一变化非常细微,许多用户可能注意不到明显的差异。

如果您更喜欢旧外观,可以通过以下方式实现:

  1. 烘焙光照探针
  2. 使用 C# 获取数组 LightmapSettings.lightProbes.bakedProbes 的副本。
  3. 对于每个 SphericalHarmonicsL2 实例,将系数 0 乘以 16/17。
  4. 将数组副本写回 LightmapSettings.lightProbes.bakedProbes

Enlighten 烘焙全局光照不再可用

Enlighten 烘焙全局光照光照 (Enlighten Baked Global Illumination) 贴图后端不再可用。

将项目升级到此版本时,Unity 会从光照贴图选择下拉列表中删除__ Enlighten__Geomerics 出品的光照系统,在 Unity 中用于 Enlighten 实时全局光照。更多信息
See in Glossary
烘焙后端,并在已选择 Enlighten 烘焙后端的每个场景中替换渐进式光照贴图。

在 Apple 芯片设备上,Unity 用渐进式 GPU 光照贴图代替 Enlighten 烘焙后端。在所有其他设备上,Unity 选择 CPU 渐进式光照贴图。

Enlighten 预计算实时全局光照仍然可用,并且支持到 Unity 2024 LTS。

Android:Java 类 UnityPlayer 需要重命名为 UnityPlayerForActivityOrService

UnityPlayer Java 类已被两个新的桥类(UnityPlayerForActivityOrServiceUnityPlayerForGameActivity)取代。这些新类都派生自 UnityPlayer,但公共方法(例如 displayChangedwindowFocusChanged)已专门从 UnityPlayer 移至 UnityPlayerForActivityOrService

如果扩展默认 Unity 活动并使用 UnityPlayer 类,可能会遇到编译错误。在这种情况下,请将 UnityPlayer 重命名为 UnityPlayerForActivityOrService

Android:UnityPlayer java 类不再扩展 FrameLayout

UnityPlayer Java 类不再扩展 FrameLayout。如果需要访问 FrameLayout,请在 getFrameLayout 实例上调用 UnityPlayer 函数。

FetchFirstCompatibleTypeUsingScriptableRenderPipelineExtension 替换为 GetDerivedTypesSupportedOnCurrentPipeline

RenderPipelineEditorUtility.FetchFirstCompatibleTypeUsingScriptableRenderPipelineExtension 现已弃用。请改用 GetDerivedTypesSupportedOnCurrentPipeline。此方法的签名也不同;现在它返回所有派生类型,而不仅仅是遇到的第一个类型。这样可以防止不一致,因为 Unity 不保证类型顺序。

CustomEditorForRenderPipelineAttribute 和 VolumeComponentMenuForRenderPipelineAttribute 已弃用

CustomEditorForRenderPipelineAttribute 和 VolumeComponentMenuForRenderPipelineAttribute 现已弃用。请改用 CustomEditorVolumeComponentMenu。要在这些属性处于活动状态时限制管线的选择,请将属性与 SupportedOnRenderPipelineAttribute 组合并指定 RenderPipelineAsset 类型。如果要激活与内置渲染管线一起使用的 SRP 属性,请使用不带参数的 SupportedOnRenderPipelineAttribute。当需要在特定管线上激活这两个属性时,这会为这两个属性提供统一的工作流程。

Android Gradle 模板用法变更

引入了用于修改 Android__ Gradle__一套 Android 构建系统,可自动执行多种构建过程。这种自动化意味着能减少许多常见的构建错误。更多信息
See in Glossary
项目的新 API。API 可用于替换旧的 Android Gradle 模板工作流程。如果未使用新 API,模板仍将像以前一样工作。

要使用新 API,可使用模板升级程序 (Templates Upgrader)

  1. 打开 Android 播放器设置 (Android Player Settings)
  2. 前往发布设置 (Publishing Settings) > 构建 (Build)
  3. 选择升级模板到 C# (Upgrade templates to C#)

环境光照:默认情况下不再烘焙环境探针和天空盒反射探针

默认情况下,Unity 的渐进式光照贴图不再烘焙环境探针和天空盒反射探针,并且光照 (Lighting) 窗口中的重新计算环境光照 (Recalculate Environment Lighting) 设置已删除。

为了避免新建的场景没有环境光照,Unity 会分配一个默认的光照数据资产 (Lighting Data Asset),其中包含与默认天空盒材质匹配的环境光照。

在以下情况下,必须在光照 (Lighting) 窗口中选择生成光照 (Generate Lighting)

  • 修复依赖于先前自动烘焙行为的场景中的光源。
  • 查看更改环境光照设置时新场景中的光照变化。

如果依赖以前的自动烘焙行为,但使用默认环境光照设置,Unity 会升级场景以使用默认的光照数据资产。

自动生成光照已删除

光照 (Lighting) 窗口中的自动生成 (Auto Generate) 设置已删除,相关 API 现已弃用。

要为场景生成烘焙光照,可以执行以下任何操作:

  • 光照 (Lighting) 窗口中选择生成光照 (Generate Lighting)
  • 使用 Lightmapping.Bake API。
  • 使用 Lightmapping.BakeAsync API。

要在编辑时查看光照贴图,现在可以选择场景视图绘制模式 (Scene View Draw Mode),并将光照数据 (Lighting Data) 设置为预览 (Preview)。此时将显示烘焙光照的预览。预览光照贴图是无损的,您可以在烘焙场景后使用它们。

如果场景依赖于自动生成光照,则不再具有其烘焙光照。在光照 (Lighting) 窗口中选择生成光照 (Generate Lighting) 以手动重新烘焙光照。

如果使用脚本打开场景,现在必须使用 Lightmapping.BakeLightmapping.BakeAsync,而不是等待自动生成光照完成。

DepthAuto、ShadowAuto 和 VideoAuto 图形格式现已弃用

以下图形格式以前在 2022.1 版中已弃用,现在已过时,如果使用这些格式,会产生编译错误:

  • GraphicsFormat.DepthAuto
  • GraphicsFormat.ShadowAuto
  • GraphicsFormat.VideoAuto

GraphicsFormatUtility.GetGraphicsFormat API 不再返回过时格式。而是执行以下操作:

  • RenderTextureFormat.Depth 转换为 GraphicsFormat.None 而不是 GraphicsFormat.DepthAutoGraphicsFormat.None 表示仅深度渲染。
  • RenderTextureFormat.Shadowmap 转换为 GraphicsFormat.None 而不是 GraphicsFormat.ShadowAuto。如果使用 GraphicsFormat.None 格式创建渲染纹理,必须将 RenderTextureDescriptor.shadowSamplingMode 设置为 ShadowSamplingMode.CompareDepths 以启用深度比较采样。

由于 GraphicsFormat.DepthAutoGraphicsFormat.ShadowAuto 都被视为深度模板格式,但用作颜色格式,因此可能需要调整代码。

例如,在以下代码片段中,GraphicsFormatUtility.IsDepthFormat 返回 false 而不是 true

RenderTextureDescriptor desc = new RenderTextureDescriptor(256, 256, RenderTextureFormat.Depth, 32);
bool isDepthOnly = GraphicsFormatUtility.IsDepthFormat(desc.graphicsFormat);

要检查 RenderTextureRenderTextureDescriptor 是否仅限深度,请使用以下方法之一:

  • if (renderTexture.graphicsFormat == GraphicsFormat.None && renderTexture.depthStencilFormat != GraphicsFormat.None)
  • if (renderTexture.format == RenderTextureFormat.Depth || renderTexture.format == RenderTextureFormat.Shadowmap)

默认情况下,Mipmap Limits 不再影响运行时纹理

默认情况下,运行时创建的 2D 纹理将不再限制其 Mipmap 上传。以前,必须通过 Texture2D 构造函数显式禁用 Mipmap 限制(使用 TextureFormat 调用构造函数时提供 ignoreMipmapLimit 布尔参数,使用 GraphicsFormat 调用时提供 IgnoreMipmapLimit TextureCreationFlag),或者切换构造纹理的 tex.ignoreMipmapLimit。此行为已更改:对于运行时创建的 2D 纹理,Mipmap 限制现在可以选择加入

如果不进行项目更改,在以下情况下,用户会错过 GPU 带宽和内存优化,并且质量可能比预期更好,因为现在纹理以全分辨率上传:

  • 用户在不知情的情况下预期运行时纹理遵循质量设置。
  • 用户有意想要运行时纹理遵循质量设置并使用任何默认 Texture2D 构造函数实现此目的。

在以下情况下,用户不受此更改的影响:

  • 用户明确想要运行时纹理保持全分辨率。
  • 用户有意想要运行时纹理遵循质量设置并通过以下显示操作实现:
    • 使用具有 TextureFormat 的构造函数,false 设置为 ignoreMipmapLimit
    • 在构造后将 tex.ignoreMipmapLimit 设置为 false

如果使用已弃用的构造函数,这些用户可能希望升级其脚本。

要升级脚本,请使用带有 MipmapLimitDescriptor 的 Texture2D 构造函数来指示运行时纹理将受到质量设置的影响。

进行此更改是为了与 Texture2DArrays 的新 Mipmap 限制支持保持一致。我们选择一致性,并决定运行时纹理应显式启用 Mipmap 限制,而不是让每个纹理形状定义自己的默认 Mipmap 限制行为。此选择加入行为比选择退出更可取,因为运行时纹理通常以更通用的方式使用,意外上传的 Mip 数量少于预期可能比意外上传更多 Mip 更有害。

使用 UXML 增强自定义控件的创建

__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary
工具包中简化了使用 UXML 创建自定义控件的过程,从而加快工作流程并使其更直观。

一项关键的改进是引入了 UxmlElement 和 UxmlAttribute 属性。这些属性可简化属性创作,并自动从属性名称派生属性名称,从而无需 UxmlTraits 和 UxmlFactory 类。

现在可以为特定数据类型创建自定义属性转换器,确保值在 UXML 属性字符串之间无缝转换值。我们还增强了 UxmlObject,允许在视觉元素中定义自定义的非视觉元素。新系统利用 Unity 序列化并使用源生成器为每个自定义元素类的所有 UxmlAttribute 定义中的元素创建 UxmlSerializedData 类,从而支持自定义属性绘制器、装饰器和各种属性。

“属性覆盖”的引入允许您自定义 UXML 属性的行为,并在处理继承属性时提供灵活性。这些改进为在 Unity 2023.2 及更高版本中创建复杂的 UI 元素提供了更高效和友好的用户体验。

例如,以下代码示例是使用 UxmlFactoryUxmlTraits 创建的自定义控件:

public class HealthBar : VisualElement
{
   private const float k_LowValue = 0;
   private const float k_HighValue = 100;

   // Declare as usable with Uxml
   public new class UxmlFactory : UxmlFactory<HealthBar, UxmlTraits> { }
   // Define attributes (and connect with class properties) for Uxml 
   public new class UxmlTraits : BindableElement.UxmlTraits
   {
       UxmlColorAttributeDescription m_Color = new UxmlColorAttributeDescription { name = "color", defaultValue = Color.white };
       UxmlFloatAttributeDescription m_Value = new UxmlFloatAttributeDescription { name = "value", defaultValue = k_HighValue };

       public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
       {
           base.Init(ve, bag, cc);
           var bar = ve as HealthBar;
           bar.color = m_Color.GetValueFromBag(bag, cc);
           bar.value = m_Value.GetValueFromBag(bag, cc);
       }
   }

   public Color color { get; set; }

   [Range(k_LowValue, k_HighValue)]
   public float value { get; set; }
}

以下代码示例执行与先前代码示例相同的操作,但使用新的 UxmlElementUxmlAttributes 系统:

[UxmlElement]
public class HealthBar2 : VisualElement
{
   private const float k_LowValue = 0;
   private const float k_HighValue = 100;

   [UxmlAttribute]
   public Color color { get; set; } = Color.white;

   [UxmlAttribute]
   [Range(k_LowValue, k_HighValue)]
   public float value { get; set; } = k_HighValue;
}

有关更多示例和信息,请参阅 Unity UI 工具包文档,请继续关注今年秋季的深度博客文章。

资产/创建 (Assets/Create) 菜单和 ScriptTemplate 已重新组织

资产/创建 (Assets/Create) 菜单已重新组织和分类。作为这次大改的一部分,Unity 内置 ScriptTemplate 文件已重命名。

使用属性或自定义 ScriptTemplate 向资产/创建 (Assets/Create)CreateAssetMenuAttribute``, MenuItemAt 菜单添加元素的用户可能想要更改其菜单项的优先级,因为现在它相对于其他元素的位置有所不同。

通过使用 EditorApplication.ExecuteMenuItem API 执行这些菜单项来创建资产的用户必须验证菜单项的新路径。

以前覆盖过 Unity 内置 ScriptTemplate 的用户必须更新其覆盖文件的名称,以确保与内置模板的新名称匹配。

UI 工具包事件处理重新组织和简化

方法 ExecuteDefaultActionExecuteDefaultActionAtTarget 已弃用。这些方法最初来自 CallbackEventHandler,会影响 VisualElement 的子类。如果有可以覆盖或调用这些方法来处理事件传播的自定义 VisualElement 子类,请注意,不再建议使用这些方法来处理事件中的默认操作。由于继承自 VisualElement,此更改会影响大多数派生自 CallbackEventHandler 的用户。

添加了以下方法来替换 ExecuteDefaultActionExecuteDefaultActionAtTarget

  • HandleEventTrickleDown
  • HandleEventBubbleUp

Unity 会在事件调度路径中每个元素的 TrickleDown 回调之后和 BubbleUp 回调之前立即执行这些新方法。在这些方法中,调度阶段相应地设置为 TrickleDownBubbleUp,并且事件的 currentTarget 与执行该方法的元素一致。

AtTarget 调度阶段和 PreventDefault 方法已弃用。现在,调用 StopPropagationStopPropagationImmediately 会停止进一步执行 HandleEventTrickleDownHandleEventBubbleUp,同时停止进一步调用 TrickleDownBubbleUp 回调。

在大多数情况下,如果不升级到新方法,代码将不会显著改变其行为。UI 工具包仍然按照与以前相同的顺序调用过时方法,或进行小幅调整。但是,UI 工具包中的所有标准控件都已迁移到使用新方法,并相应地调整其逻辑执行顺序。与以前的 Unity 版本相比,将过时方法调用和升级控件使用混合在一起,可能会导致某些逻辑不同步。

要将现有代码升级到新方法,请按照以下步骤操作:

  • ExecuteDefaultActionExecuteDefaultActionAtTarget 替换为 HandleEventBubbleUp,将 PreventDefault 替换为 StopPropagation(如果已在同一代码块中调用 StopPropagation,则删除对 PreventDefault 的调用)。这涵盖了大多数情况)。
  • 如果因为在 PreventDefault 回调期间调用旧代码 BubbleUp(不再可行,并且无法由 StopPropagation 替换,因为事件已经达到目标)出现问题,请考虑在 TrickleDown 阶段添加回调来调用 StopPropagation。此步骤通常足以应对此类情形。
  • 在极少数情况下,如果上述更改不足以维持旧代码的功能,则需要进行全面的逐案例分析。在这些情况下,解决方案可能并非总是那么简单。

Metal 中的缓冲区布局变更

Unity 着色器到 Metal 着色器的交叉编译在缓冲区布局方面发生了变化。与 Unity 的先前版本相比,任何包含 min16float、half 或 real 类型的缓冲区现在都有不同的内存布局。

仅当您以 Metal 为目标并使用将原始数据直接写入缓冲区的 API 时才需要执行操作,例如:

如果仅使用 CommandBuffer.SetComputeFloatParamMaterial.SetFloat,则无需执行任何操作。

更具体地说,HLSL min16float、half 和 real 内部缓冲区始终转换为 32 位 MSL float,而在以前的 Unity 版本中,可以会转换为 16 位 MSL half,具体取决于目标平台。

如果仅在 Metal 平台上测试过着色器,请检查生成的 MSL 代码中的缓冲区,以确保布局与 C# 中访问的缓冲区数据匹配。您可以通过向着色器代码添加 #pragma metal_fxc_allow_float16_in_cpu_visible_buffers 并查看是否修复了任何视觉瑕疵来测试此更改是否影响着色器。如果您发现差异,请删除此 pragma 并调整着色器和 C# 代码,使其在没有 pragma 的情况下正常工作,以提高项目的跨平台兼容性。

要在缓冲区中使用原生 16 位浮点数,请考虑使用 DXC HLSL 编译器并向着色器添加 #pragma require Native16Bit。但是请注意,在 Unity 中使用 DXC 仍处于实验阶段。

不再使用全局包缓存中的 Packages 文件夹

全局包缓存包含多个子文件夹。包管理器不再使用其中一个子文件夹 packages

仅当自动化脚本或管线与全局包缓存的 packages 子文件夹直接交互时,例如,使用 UPM_CACHE_PATH 环境变量时,才需要执行此操作。如果是,则可以删除引用。Unity 不为 packages 提供直接替换子文件夹。现在包直接提取到项目缓存中。

如果您不再维护使用 Unity 2023.2 创建的项目,则可以从全局包缓存根目录安全地删除 packages 子目录。此操作为可选项。

不再支持 UPM_CACHE_PATH 环境变量

Unity 编辑器的早期版本支持使用 UPM_CACHE_PATH 环境变量来指定您想要包管理器存储包 tarball 未压缩内容的位置的绝对路径。

仅当具有在 UPM_CACHE_PATH 中设置路径值的自动化脚本或管线时,才需要执行此操作。UPM_CACHE_PATH 是不可替代的,因为现在包直接提取到项目缓存中。但是,如果您以前使用 UPM_CACHE_PATH,现在可以使用 UPM_CACHE_ROOT 环境变量,该变量可设置全局缓存的根。请注意,全局缓存根是以前与 UPM_CACHE_PATH 关联的子文件夹的父目录。

有关更多信息,请参阅自定义全局缓存

默认 Android 工具版本已更改

Unity 更新了 Android 使用的以下工具的默认版本。NDK、SDK 命令行工具和 SDK 工具的默认版本保持不变。更新的版本如下:

工具 版本
Gradle 8.4
Android Gradle 插件 8.3.0
SDK 构建工具 34.0.0
SDK 平台工具 34.0.5
Java 开发工具包 (JDK) 17

如果您的项目使用自定义 gradle 模板,请考虑重新创建这些模板,以避免更新的 Android Gradle 插件版本出现任何构建问题。有关更多信息,请参阅使用 Gradle 模板文件修改 Gradle 项目文件

Unity 编辑器附带的 7-Zip 版本不再支持 zstandard 压缩

以前的 Unity 编辑器版本包括一个支持 zstandard 压缩的 7-Zip 分叉:

Unity 6 包含适用于 Windows、macOS 和 Linux 编辑器的 7-Zip 常规上游版本 23.01。但是,此上游版本的 7-Zip 不支持用于 .zip 或 .7z 存档的 zstandard 压缩或解压缩。也不支持在 mcmilk/7-Zip-zstd 分叉中添加的其他压缩格式和哈希算法。

如果您的包使用 7za 或 7z.exe 二进制文件,并且使用 zstandard 压缩对存档进行操作,请使用以下选项之一:

  • 使用其他压缩格式,例如使用 Deflate 算法的 .zip 存档或使用 LZMA 或 LZMA2 的 .7z 存档。
  • 提供您自己的二进制文件,二进制文件支持所需的存档格式和压缩算法。
API 更新程序
升级到 Unity 2023.2