版本: 2022.3
语言: 英语
升级至Unity 2021 LTS
升级至Unity 2021.1

升级至Unity 2021.2

注意:按照发布顺序遵循本节中的建议。例如,如果您需要将项目从2020升级到2022,请先阅读2021升级指南,查看是否有在进行2022升级指南之前您需要做出的更改。

本页列出了从2021.1 beta版本升级到2021.2版本时可能影响现有项目的Unity 2021.2版本的更改。

环境光照:现在环境探测器和天空盒反射探测器将自动烘焙

Unity的渐进式 光照贴图器Unity中的一项工具,根据场景中灯光和几何形状的布局自动烘焙光照贴图。更多信息
参见术语表
现在会自动生成环境探测器和每个 场景包含游戏的环境和菜单。将每个独特的场景文件视为一个独特的关卡。在场景中,您放置环境、障碍物和装饰,实际上是在零散地设计和构建游戏。更多信息
参见术语表
的默认情况下自动烘焙天空盒反射探测器。这意味着场景将根据“光照”设置面板中“环境”标签中的设置自动接收环境光照。当环境光照变化时,编辑器会更新环境探测器和天空盒反射探测器,直到您生成光照。当使用“生成光照”控制烘焙时,编辑器停止更新探测器,直到下一个烘焙。当启用“自动生成”选项时,编辑器会在环境光照每次变化时继续更新探测器。如果您生成光照然后删除此光照数据(从项目中删除光照数据资产),编辑器将再次自动生成环境探测器和天空盒反射探测器。

在升级项目时,有一种情况需要您采取行动。这是当您不希望项目中有任何环境光照贡献时,这个项目

  • 没有光照数据资产。
  • 没有启用 自动生成
  • 将环境贡献设置为除黑色之外的颜色。

在这种情况下,导航到 窗口 > 渲染 > 光照设置 > 环境,并通过以下更改之一禁用自动生成的环境探测器和天空盒反射探测器的环境贡献

  • 选项1:将 强度乘数 设置为0。
  • 选项2:使用黑色 天空盒Material
  • 选项3:为 中的 颜色渐变 模式使用黑色颜色。

粒子系统力场

以前,一些力场属性在不同帧率下表现不同(或者在时间管理器设置中使用了时间缩放功能)

粒子系统模拟液体、云和火焰等流体实体的组件。通过在场景中生成和动画大量小2D图像来模拟。 更多信息
参见术语表
现在使用30fps作为参考帧率以作为模拟的基础。如果您的应用程序在不同的帧率下运行,以下设置可能与其在Unity早期版本中的行为不同

  • 重力
  • 旋转
  • 矢量场

如果这些设置受到影响,请调整受影响区域的力量以获得所需的外观。

粒子系统启动延迟 + 距离排放率

以前,距离排放率忽略了启动延迟设置。现在,如果定义了启动延迟设置,它将延迟根据距离的排放。

如果以前设置了该字段,可能需要调整它。

BuildReport - PackedAssets

PackedAssets.file已被标记为已过时,没有直接替换。以前这表示一个文件ID或BuildReport.files中的索引。要查找BuildReport文件,现在请使用PackedAssets.shortPath。

地形的API已退出实验状态(WIP)

实验性的地形场景中的景观。地形游戏对象添加一个大型平坦面到场景中,您可以使用地形的检查器窗口来创建详细的景观。 更多信息
参见术语表
API已移动到非实验名称空间。地形API还进行了一些其他小的更改。如果您使用了实验性的地形API,请使用以下API

  • UnityEngine.TerrainTools;
  • UnityEditor.TerrainTools;
  • UnityEngine.TerrainUtils;

以下是API更改的完整列表

  • 在大多数情况下,UnityEngine.Experimental.TerrainAPIUnityEditor.Experimental.TerrainAPI现在分别是UnityEngine.TerrainToolsUnityEditor.TerrainTools。一些运行时API已移动到新的UnityEngine.TerrainUtils名称空间。
  • TerrainPaintTool<T>类的GetDesc()已被重命名为GetDescription()
  • TerrainUtility类已从UnityEngine Experimental.TerrainAPI移动到UnityEngine.TerrainUtils
  • TerrainUtility.TerrainMap类不再是内部类,现在属于UnityEngine.TerrainUtils名称空间。
  • TerrainMap.TileCoord结构现在不再在TerrainMap类中,已重命名为TerrainTileCoord,并且现在也是UnityEngine.TerrainUtils名称空间的一部分。
  • UnityEditor.Experimental.TerrainAPI.BrushPreviewMode枚举已重命名为TerrainBrushPreviewMode,并已移动到UnityEditor.TerrainTools名称空间。
  • TerrainPaintUtilityEditor.BuiltinPaintMaterialPasses枚举已从TerrainPaintUtilityEditor类移动到UnityEditor.TerrainTools名称空间。它已重命名为TerrainBuiltinPaintMaterialPasses
  • IOnInspectorGUI中的三个ShowBrushGUI函数已合并为一个具有默认参数值的函数,而不是不同的重载函数。
  • TerrainFilter已被删除。请使用System.Predicate<Terrain>

Texture2D.Resize重命名为Reinitialize

Texture2D.Resize及其重载已被重命名为Texture2D.Reinitialize

API更新器应自动重命名此内容。如果不是,请将任何对Texture2D.Resize的使用更改为Texture2D.Reinitialize

Android更改

Android构建管道的大部分内容现在都是增量式的,Unity移除了之前构建管道中的以下功能

  • Unity不再将位于 Assets/Plugins/Android/[资源, 资产] 的项目资产复制到Gradle项目中。Gradle一个自动化的Android构建系统,它自动化了许多构建过程。这种自动化意味着许多常见的构建错误发生的可能性较小。更多信息
    参见术语表
    • 以前,您可以在此文件夹中放置Gradle资源,Unity会将其复制到Gradle项目中。现在,您应该使用AAR或androidlib插件将额外的Gradle资源传递给应用程序。
    • 如果您将项目资产放置在此文件夹中,Unity将显示构建错误消息。
  • Unity不再忽略包含 由Unity生成。删除此注释可防止在再次导出时覆盖 注释的文件。
    • 以前,如果您删除了此注释,Unity将不会覆盖文件。如果您没有删除注释,Unity总会重新生成build.gradle、manifest和UnityPlayerActivity文件。
    • 如果您想在新的构建管道中持久化更改,请使用模板。
  • 当您导出Android项目时,Unity不再创建符号zip包。符号现在可以在unityLibrary\symbols目录中找到,您可以将其压缩。这种变化的理由是在导出项目时,并非所有符号文件都可用;当Gradle构建应用程序时,它会生成libil2cpp.so符号。
  • Unity检查obb是否与apk兼容的方式已更改。apkUnity输出的Android包格式。当您选择“文件 > 构建 & 运行”时,APK会自动部署到您的设备。更多信息
    参见术语表
    现在apk和obb中都有一个unity_obb_guid文件,如果它们之间的内容匹配,Unity则将它们视为兼容。
  • 对于使用PatchPackage的定制构建脚本来讲,请注意现在修补/修补并运行与所有类型的资产一起工作,而无需进行仅脚本构建。

UI工具包 - Image的默认scaleMode已更改

Image的默认scaleMode已从ScaleAndCrop更改为ScaleToFit。

对于图像的期望行为是缩放到元素的大小,因此我们将Image.scaleMode的默认值更改为ScaleToFit。如果您没有覆盖Image缩放模式,一些裁剪的图像可能缩小以适配元素的大小。如果您期望图像的默认模式是ScaleAndCrop,您可以通过在您的UXML文件中添加以下内联样式来覆盖它们的样式:

-unity-background-scale-mode: scale-and-crop;

您还可以创建一个具有覆盖的样式类并将其应用到需要ScaleAndCrop的图像上。

Mono升级行为更改

最新版本中的基础C#运行时Mono已升级。这包括来自Mono上游版本的大量修复以及一些明显的功能变化。

  • Directory.GetFiles不再保证返回排序列表。
    • 以前,它总是返回一个按字母顺序排序的项的列表。如果您的项目需要在每次都返回相同顺序的项,请对返回的列表进行排序。例如:var files = Directory.GetFiles(dir).OrderBy(f => f);
  • Object.GetHashCode现在返回不同的值,不应作为操作系统之间的确定性哈希算法依赖。
    • 通常,您不应该将GetHashCode的结果用于当前进程之外,也就是说不要对其进行序列化或期望它在下次以新的进程运行代码时相同。Unity建议使用MD5之类的确定性哈希算法。
  • 一些错误修复导致了新的异常被抛出。此外,某些异常消息的内容已更改。
    • 这种新的行为在自动测试场景中尤其明显,如果测试正在解析日志以获取特定的异常消息,可能需要更改预期的行为。

自适应性能

现在可使用自适应性能包的3.0版。有关升级到3.0版的信息,请参阅自适应性能升级指南

RenderTexture 深度模板格式

之前,如果您将 RenderTexture.depth 属性设置为32位,您可能会根据平台得到D24_S8。现在如果您将其设置为32位,如果您当前平台支持此格式,则得到D32_S8,其中深度组件为32位。然而,这将使该 深度缓冲区一个内存存储器,用于存储图像中每个像素的z值深度,其中z值是从投影面到每个渲染像素的深度。 更多信息
查看术语表
的内存使用量加倍。

新的 RenderTexture.depthStencilFormat 属性返回图形API用于在视频内存中创建资源的格式。您还可以使用此属性请求特定格式。但是,并非所有平台都支持所有深度模板格式。当您将 DepthStencilFormat 属性设置为一个不受支持的格式时,Unity会自动选择一个具有等于或更多深度和模板组件位的兼容格式。

升级

现在,RenderTexture 资产将序列化您所选择的深度模板格式。如果您使用的是接受位数而不是格式的API,这些位数将被映射到一个格式,并且这个格式将被序列化。之前版本中设置深度大于16位的RenderTexture资产将自动升级为使用D24_S8。

在某些平台(例如Windows)上,这些平台使用DirectX图形API,由于图形后端在您设置位>16时内部选择D32_S8格式,这导致格式具有更少的深度位。为确保所有平台的升级一致性,所有平台在自动升级器中均使用D24_S8。但是,这可能会在项目的渲染输出中引入视觉伪影。如果您的项目中包含RenderTexture资产,请查看这些资产,并在必要时将其深度模板格式更改为D32_S8。可能会出现以下问题

  • 您使用的RenderTextures的内存大小可能会增加。但是,现在报告的内存现在是正确的。
  • 现在,将深度属性设置为32位将为您提供32位深度组件,这将增加内存使用量。为了避免这种情况,请将位数设置为24,并在平台支持的情况下使用D24_S8。
  • 如果平台不支持D24_S8,Unity将默认回退到兼容的格式D32_S8。为了防止这种情况,在检查器一个Unity窗口,显示有关当前选择的GameObject、资产或项目设置的信息,允许您检查和编辑值。更多信息
    查看术语
    窗口中,禁用资产上的启用兼容格式属性。如果Unity不支持D32_S8格式且无法回退,您将看到错误消息“RenderTexture.Create失败:深度/模板格式不支持。在这个平台或导入检查器中未启用兼容格式的回退。”。在大多数情况下,要解决问题,您可以打开启用兼容格式

图形格式DepthAuto、ShadowAuto和VideoAuto已废弃

以下图形格式现已废弃

  • DepthAuto
  • ShadowAuto
  • VideoAuto

这些“自动”格式关于使用的确切格式不明确,可能因平台而异。

移除使用这些已废弃格式的步骤取决于格式和用例。

对于VideoAuto

要获取当前平台的自动视频格式,请使用SystemInfo.GetGraphicsFormat(DefaultFormat.Video)

对于DepthAuto/ShadowAuto,以前用来指示只包含深度渲染纹理。

GraphicsFormat API常用DepthAuto或ShadowAuto创建只有深度渲染的渲染纹理一种在运行时创建和更新的特殊类型的Texture。为了使用它,首先创建一个新的Render Texture,并将您的某个相机构造设置为渲染到其中。然后您可以在Material中使用渲染纹理,就像使用常规Texture一样。更多信息
查看术语
,没有颜色缓冲区。此用例的示例包括

  • renderTextureDescriptor.graphicsFormat = GraphicsFormat.ShadowAuto
  • RenderTexture.GetTemporary(width, height, bits, GraphicsFormat.ShadowAuto)

要指示只进行深度(非颜色)渲染,使用GraphicsFormat.None作为新颜色格式。renderTextureDescriptor.graphicsFormat = GraphicsFormat.None;

如果使用了ShadowAuto,将RenderTextureDescriptor中的shadowSamplingMode设置为ShadowSamplingMode.CompareDepths以在深度纹理上启用深度比较采样,并使用接受RenderTextureDescriptor的重载来更改代码。renderTextureDescriptor.shadowSamplingMode = ShadowSamplingMode.CompareDepths;

DepthAuto/ShadowAuto在其他情况下的使用

在某些情况下,DepthAuto/ShadowAuto格式代表“适合当前平台的自动选择深度格式”。在这种情况下,要用废弃的值替换它,请使用SystemInfo.GetGraphicsFormat(DefaultFormat.Depth/Shadow)

WebGL:已更新Emscripten到2.0.19

曾经提供给高级用户的asm.js链接器目标不再可用。

  • 在Unity 2021.2中,平台使用的底层Emscripten编译器已升级到版本2.0.19。这次升级改进了本地代码对象文件格式,因此需要重新编译项目中的所有本地代码插件(C/C++代码插件)。如果您正在使用Unity Asset Store由Unity和社区成员创建的免费和商业资产库。提供各种资源,包括纹理、模型、动画到整个项目示例、教程和编辑器扩展。 更多信息
    词汇表中查看
    中的闭源第三方插件,例如,请记得向作者索要Unity 2021.2的更新版本。
  • Emscripten运行时JavaScript函数Pointer_stringify()现已弃用。请改为调用函数UTF8ToString()将UTF8编码的空终止C字符串从WebAssembly堆传输到JavaScript字符串。

Progressive GPU Lightmapper已停止支持CPU OpenCL设备

Progressive GPU Lightmapper不再支持CPU OpenCL设备。如果在找不到支持GPU但检测到CPU OpenCL设备时,将显示警告消息,告知您该设备被跳过并回退到Progressive CPU Lightmapper。Progressive CPU Lightmapper为基于CPU的光图预先渲染的纹理,包含光源对场景中静态对象的照射效果。光图叠加到场景几何图形上以产生光照效果。 更多信息
词汇表中查看
计算提供了更好的性能。这种行为变化将会自动发生,光图应该按预期计算。

OnPostprocessAllAssets行为变化

当Unity在资产导入过程中调用InitializeOnLoad方法时,资产加载可能会失败。在资产导入过程中,资产数据库处于更新状态,Unity无法确定哪些资产已被导入。InitializeOnLoad方法无法加载尚未导入的资产。

为了改善资产导入过程,OnPostprocessAllAssets回调得到了增强。特别是,OnPostprocessAllAssets回调

  • 在域重新加载后,在资产数据库保证为就绪状态时,可以进行初始化。
  • 包含参数didDomainReload,当域已重新加载时,将其设置为true。
  • 支持资产操作。这包括资产加载,其行为与通过菜单项加载资产相同。
  • 已从资产数据库导入循环中移除。回调处理将被推迟到资产导入完成后。

将任何需要资产操作的域相关的初始化逻辑移至OnPostprocessAllAsset回调;不要在InitializeOnLoad方法内部执行资产操作。

以下行为变化代码示例显示了资产操作之前是如何被推迟的。

例子1

public class AssetPostprocessorTester1 : AssetPostprocessor
{
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        var assetPath = "Assets/hello.txt";

        if (File.Exists(assetPath))
        {
            var txtObj = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/hello.txt");
            AssetDatabase.DeleteAsset("Assets/hello.txt");

            if (txtObj == null)
                Debug.Log("New Behaviour: Asset object is unloaded");
            else
                Debug.Log("Old Behaviour: Asset is loaded for deleted asset!!");
        }
    }
}

例子2

 public class AssetPostprocessorTester2 : AssetPostprocessor
{
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        var assetPath = "Assets/SomeText.txt";
        if (!File.Exists(assetPath))
        {
            File.WriteAllText(assetPath, "hello world");

            AssetDatabase.ImportAsset(assetPath);
            var txtObj = AssetDatabase.LoadAssetAtPath<TextAsset>(assetPath);

            if (txtObj == null)
                Debug.Log("Old Behaviour: Asset hasn't been imported yet");
            else
                Debug.Log("New Behaviour: Asset is imported and loaded");
        }
    }
}

以下示例显示了具有didDomainReload参数的新OnPostprocessAllAssets变体

static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
{
    if (didDomainReload)
        Debug.Log("Domain has been reloaded");
    else
        Debug.Log("Domain did not reload during import");
}

现在所有域重新加载都在资产数据库内部处理。

OnPostprocessAllAssets现在在资产操作方面表现得更好,但此回调中的任何处理都会增加资产数据库刷新和域重新加载时间。InitializeOnLoad方法也会增加域重新加载时间。最佳做法是将这些回调中的处理最小化,以改善在迭代之间编辑器响应。

着色器关键词系统改进

着色器关键词系统现在允许每个着色器或计算着色器最多有65534个局部关键词和每个项目232-2个全局关键词。在着色器或计算着色器中声明的所有关键词现在都是本地的。带有_local后缀的指令中声明的关键词不受全局关键词状态的影响。

示例

着色器中的一个过程声明了以下关键词

  • #pragma shader_feature FOO BAR
  • #pragma shader_feature_local BOO BAZ

在使用此过程时,如果FOO和BAR在全球范围内或在材质上启用,则它们被启用。只有当BOO和BAZ在材质上启用时,它们才被启用。

Unity支持.NET Standard 2.1 API

Unity现在支持.NET基础类库中的许多其他API,包括.NET Standard 2.1 API中的所有API。如果您代码中的任何部分与新的API冲突,则项目可能无法编译。

为了避免在升级旧版本的Unity项目中出现的错误,检查并更新您的代码,以确保没有与现在在.NET Standard 2.1中可用的类型和方法发生冲突。

冲突的来源包括以下

  • 模糊引用
  • 扩展方法
  • 预编译的程序集

解决模糊引用

如果您的代码实现了与.NET Standard 2.1添加的类型或方法名称冲突的类型或方法,则代码无法编译。名称冲突可能导致由于模糊引用而导致的C#编译器错误。

例如,如果您将类型名MyCompany.MyCode.Range添加到项目代码中,这可能与现有的System.Range类型冲突。同时包含using System;using MyCompany;语句的代码无法编译。

为防止错误,在C#代码中对具有冲突名称的任何类型完全指定名称空间。

解决冲突的扩展方法

如果您的现有代码有一个扩展方法,而.NET Standard 2.1现在已经在该类型上直接实现了这个方法,您可以选择重命名您的扩展方法或使用基础类库实现的方法。

例如,项目中的代码可能在ArraySegment类型上实现一个名为CopyTo的扩展方法。在.NET Standard 2.1中,ArraySegment有一个内建的CopyTo方法。您可以选择重命名您的CopyTo扩展方法,或者完全消除它并使用内建的方法。

解决冲突的程序集

如果您的项目使用实现了现在属于基础类库的类型和方法的预编译的程序集(即管理的插件),则从您的项目中删除这些程序集并使用内置的实现。

例如,在Unity的早期版本中,您需要从NuGet使用System.Memory.dll程序集来访问System.Span值类型。现在,.NET Standard 2.1在基础类库中提供了System.Span。如果尝试在Unity 2021.2中使用System.Memory.dll管理插件,则项目无法构建。

Windows XR插件已移除

微软已弃用Windows XR涵盖了虚拟现实(VR)、增强现实(AR)和混合现实(MR)应用的统称。支持这些互动应用的设备可以被称为XR设备。 更多信息
词汇表中查看
插件,并现在通过OpenXR插件支持Windows 混合现实混合现实(MR)将虚拟环境与用户的真实世界环境结合在一起,并允许它们相互交互。
词汇表中查看
(WMR) 特性和设备。

  • 自Unity 2021.2起已移除Windows XR插件。
  • 当你在Unity 2021.2中打开现有项目时,更新过程会移除(如果存在)的Windows XR插件。
  • 要继续使用Windows混合现实项目,您必须启用Unity OpenXR插件。
  • 根据您使用哪些功能,您还必须安装微软的混合现实OpenXR支持插件,并可能需要从微软混合现实工具包中安装其他工具。

升级到Unity OpenXR插件

  1. 打开项目设置一组广泛的设置,允许您配置项目中的物理、音频、网络、图形、输入和其他许多方面的行为。 更多信息
    词汇表中查看
    窗口。
  2. XR 插件管理在Unity外部创建的代码集,用于在Unity中创建功能。您可以在Unity中使用的插件有两种:托管插件(使用Visual Studio等工具创建的托管.NET程序集)和原生插件(特定平台的原生代码库)。 更多信息
    词汇表中查看
    部分中,在插件提供者在Unity中使用的一组插件,用于扩展或修改游戏功能。 更多信息
    词汇表中查看
    列表中启用 OpenXR。如果需要,Unity将下载并安装OpenXR插件。

一旦启用了OpenXR插件,您可以使用微软提供的 混合现实功能工具 安装必要的支持包。

安装或更新WMR功能、工具和示例

  1. 下载并运行混合现实功能工具
  2. 选择要更新的Unity项目,然后单击“发现功能”。
  3. 在“平台支持”下,选择混合现实OpenXR插件用于Unity的混合现实开发的一个插件,提供对混合现实功能的支持。 更多信息
    词汇表中查看
  4. 选择您希望添加的任何其他附加功能。
  5. 单击“获取功能”。
  6. 单击“导入”然后单击“批准”以完成此过程。
  7. 返回到Unity项目设置的XR插件管理部分,启用并配置添加的功能。

有关设置新项目和更新项目以使用Windows混合现实的信息,请参阅微软文档网站上的设置您的XR配置

升级至Unity 2021 LTS
升级至Unity 2021.1