Unity 2021 新特性

按发布顺序遵循本节中的建议。例如,如果需要将项目从 2019 升级到 2021,请阅读 2020 升级指南,在阅读 2021 年升级指南之前,查看是否需要进行任何更改。

本页列出了 Unity 2021 LTS 版本中的更改,这些更改可能会在从 2020 版本升级到 2021 LTS 时影响现有项目。

一、设备模拟器

设备模拟器现在是编辑器的一部分,可以从游戏窗口访问。 若要设置设备模拟器,请将命名空间添加到 Screen、Application 和 SystemInfo 类:UnityEngine.Device``UnityEngine.Device.Screen; UnityEngine.Device.Application; UnityEngine.Device.SystemInfo;

若要切换到 ,请将以下逻辑添加到要与模拟器一起使用的每个脚本: 新命名空间通过运行时构建从模拟器(在编辑器中)平稳过渡到实际设备 API。UnityEngine.Device`` using Screen = UnityEngine.Device.Screen; using Application = UnityEngine.Device.Application; using SystemInfo = UnityEngine.Device.SystemInfo; ``UnityEngine.Device

二、环境照明

编辑器现在会自动烘焙默认的天空盒 探头和环境探头,并保留该数据,直到您手动烘焙现场 .升级时,没有环境光 贡献可能会在视觉上发生变化。要恢复这些场景的原始外观,请将环境照明强度倍数设置为 0。或者,将天空盒设置为黑色,烘焙场景,然后将天空盒重置为您喜欢的天空颜色。

三、环境照明:环境探头和天空盒反射探头现在自动烘焙

Unity 的渐进式****光照贴图器** 现在自动生成环境探头和天空盒反射探头** 默认情况下,对于每个场景。这意味着场景会根据“照明设置”面板中“环境”选项卡中的设置自动接收环境****照明。每次环境光照发生变化时,编辑器都会更新环境光照和天空盒反射光照,直到生成光照。当您使用**“生成光照**”控件进行烘焙时,编辑器会停止更新探针,并且仅在下一次烘焙时再次更新它们。启用**“自动生成**”选项后,每次环境光照发生变化时,编辑器都会继续更新探针。如果生成光照,然后通过从项目中删除光照数据资源来删除此光照数据,则编辑器会再次自动生成环境探针和天空盒反射探针。

在升级项目时,有一种情况需要采取措施。这是当您不希望在项目中有任何环境照明贡献时,该项目还:

没有照明数据资产。未启用自动生成。将环境贡献设置为黑色以外的颜色。

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

选项 1:将强度倍数设置为 0。选项 2:使用黑色天空盒材质。选项 3:在“源”的**“颜色**”或**“渐变**”模式下使用黑色。

四、启用“代码覆盖率”首选项

用于管理代码覆盖率的用户界面已从“常规首选项”移至“代码覆盖率”包中。

在 Unity 2021 中,在“代码覆盖率”窗口中移动了“启用代码覆盖率”复选框。

Code Coverage 包通过 Unity 2019.3 及更高版本的包管理器作为已发布的包提供。最新版本为 1.0.0。

您可以使用以下方法之一来启用代码覆盖率:

安装“代码覆盖率”包,打开“代码覆盖率”窗口(“代码覆盖率>>分析”窗口),然后选择“启用代码覆盖率”。在批处理模式下使用命令行参数。-enableCodeCoverage使用 Coverage.enabled API。示例类:

// Create a new C# script called CodeCoverageMenuItem and place it

// under the Editor folder.

// This class creates a toggle menu item under Code Coverage > Enable

// Code Coverage. Use it to enable/disable Code Coverage.

using UnityEditor;

using UnityEngine.TestTools;

class CodeCoverageMenuItem

{

const string EnableCodeCoverageItemName = "Code Coverage/Enable Code Coverage";

[MenuItem(EnableCodeCoverageItemName, false)]

static void EnableCodeCoverage()

{

Coverage.enabled = !Coverage.enabled;

}

[MenuItem(EnableCodeCoverageItemName, true)]

static bool EnableCodeCoverageValidate()

{

Menu.SetChecked(EnableCodeCoverageItemName, Coverage.enabled);

return true;

}

}

五、粒子系统力场

以前,某些力场属性在不同的帧速率下会有不同的行为(或者如果使用“时间管理器”设置中的“时间刻度”)

这粒子系统 现在使用 30fps 的参考帧速率作为模拟的基础。如果应用以不同的帧速率运行,则与早期版本的 Unity 相比,以下设置的行为可能会有所不同:

重力旋转向量场

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

六、粒子系统启动延迟 + 远距离发射速率

以前,“远距离速率”(Rate over Distance) 发射会忽略“启动延迟”(Start Delay) 设置。现在,如果定义了“启动延迟”设置,则会延迟基于距离的发射的启动。

如果之前设置了此字段,则可能需要对其进行调整。

七、BuildReport - PackedAssets

PackedAssets.file 已被标记为已过时,没有直接替换。以前,它包含一个整数,表示 BuildReport.files 中的文件 ID 或索引 若要立即查找 BuildReport 文件,请使用 PackedAssets.shortPath。

八、实验性 (WIP) 之外的 Terrain API

实验地形 API 已移至非实验性命名空间。Terrain API 也有一些其他小的改动。如果您使用了实验性 Terrain API,请改用以下 API:

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

以下是 API 更改的完整列表:

在大多数情况下,分别是 now 和 。某些运行时 API 已移至新的命名空间。UnityEngine.Experimental.TerrainAPI``UnityEditor.Experimental.TerrainAPI``UnityEngine.TerrainTools``UnityEditor.TerrainTools``UnityEngine.TerrainUtils的类已重命名为 。GetDesc()``TerrainPaintTool``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中的三个函数已合并为一个具有默认参数值的函数,而不是不同的重载函数。ShowBrushGUI``IOnInspectorGUITerrainFilter已被删除。请改用。System.Predicate

九、Texture2D.Resize 重命名为 Reinitialize

Texture2D.Resize`其重载已重命名为 .`Texture2D.Reinitialize

API 更新程序应自动重命名此名称。如果没有,请将 的任何用法更改为 。Texture2D.Resize``Texture2D.Reinitialize

十、Android 更改

Android 构建管线的很大一部分现在是增量的,Unity 删除了之前构建管线中的以下功能:

Unity 不再复制 Gradle(格拉德尔) 位于 Assets/Plugins/Android/[res, assets] 中的项目资产添加到 Gradle 项目中。

以前,您可以将 Gradle 资源放在此文件夹中,Unity 会将它们复制到 Gradle 项目中。您现在应该使用 AAR 或 androidlib 插件将其他 Gradle 资源传递给应用。如果将项目资源放置在此文件夹中,Unity 会显示生成错误消息。 Unity 不再忽略 GENERATED BY UNITY 中的文件。删除此注释以防止在再次导出注释时覆盖。

以前,如果删除此注释,Unity 不会覆盖文件。如果未删除注释,Unity 将始终重新生成 build.gradle、manifest 和 UnityPlayerActivity 文件。如果希望使用新的生成管道保留更改,请使用模板。 导出 Android 项目时,Unity 不再创建 symbols zip 包。这些符号现在位于 unityLibrary\symbols 目录中,您可以压缩该目录。此更改的原因是,导出项目时,并非所有符号文件都可用;Gradle 在构建应用程序时会生成符号。libil2cpp.so 更改了 Unity 检查 obb 是否与apk文件 .apk 和 obb 现在都包含unity_obb_guid文件,如果它们之间的内容匹配,Unity 会将它们视为兼容。 对于自定义构建脚本 使用 PatchPackage,请注意 Patch**/Patch & Run** 现在适用于所有类型的资产,并且不需要仅脚本构建。

十一、UI 工具包 - 图像的默认 scaleMode 已更改

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

图像的预期行为是缩放到元素的大小,因此我们将 Image.scaleMode 的默认值更改为 ScaleToFit。 如果未覆盖“图像缩放”模式,则某些裁剪的图像可能会缩小以适合元素的大小。 如果 ScaleAndCrop 是图像的预期模式,则可以通过在 UXML 文件内联样式中添加以下值来覆盖其样式:

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

还可以创建具有重写的样式类,并将其应用于需要 ScaleAndCrop 的图像。

十二、Mono 升级行为更改

基础 C# 运行时 Mono 已在最新版本中升级。这包括来自 Mono 上游版本的许多修复,以及行为上的一些显着变化。

Directory.GetFiles

不再保证返回排序列表。

以前,这始终返回按字母顺序排序的项目列表。如果项目每次都需要以相同的顺序返回项,请对返回的列表进行排序。例如: var 文件 =Directory.GetFiles(dir).OrderBy(f => f); Object.GetHashCode

现在返回一个不同的值,不应将其作为操作系统之间的确定性哈希算法。

通常,不应在当前进程之外使用 的结果,即不要序列化它或期望下次代码在新进程中运行时相同。Unity 建议使用确定性哈希算法,例如 MD5。GetHashCode 某些 bug 修复导致引发新的异常。此外,某些异常消息的内容已更改。

这种新行为在自动测试方案中尤为明显,如果测试正在分析特定异常消息的日志,则可能需要更改预期行为。

十三、自适应性能

Adaptive Performance 软件包的 3.0 版现已推出。有关如何升级到版本 3.0 的信息,请参阅自适应性能升级指南。

十四、RenderTexture DepthStencilFormat

以前,如果将 RenderTexture.depth 属性设置为 32 位,则可能会获得D24_S8,具体取决于平台。现在,如果将其设置为 32 位,则如果当前平台支持该格式,则深度组件将D32_S8 32 位。但是,这会使内存使用量增加一倍深度缓冲区 .

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

升级

现在,RenderTexture 资源将序列化您选择的深度模具格式。如果使用的 API 采用多个位而不是格式,则这些位将映射到一种格式,并且该格式将被序列化。以前版本中深度设置为 16 位以上的 RenderTexture 资源会自动升级为使用 D24_S8。

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

您使用的 RenderTextures 的内存大小可能会增加。但是,报告的内存现在是正确的。现在,将 depth 属性设置为 32 位将获得 32 位深度组件,内存使用量会增加。为避免这种情况,请将位设置为 24,并使用 D24_S8(如果您的平台支持)。如果平台不支持 D24_S8,Unity 会默认回退到兼容格式D32_S8。为了防止这种情况,在检查员 窗口中,禁用资产的“启用兼容格式”属性。如果 Unity 不支持格式D32_S8,并且无法回退,则会看到错误消息:RenderTexture.Create failed: depth/stencil format unsupported。此平台上没有兼容的格式,或者在导入检查器中禁用了回退到兼容格式的设置。在大多数情况下,要解决此问题,您可以打开启用兼容格式。

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

以下图形格式现已弃用:

深度自动影子汽车视频自动

这些自动格式不清楚使用的确切格式,并且可能因平台而异。

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

十六、对于VideoAuto

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

十七、对于 DepthAuto/ShadowAuto,用于指示仅深度渲染纹理。

GraphicsFormat API 通常使用 DepthAuto 或 ShadowAuto 来创建渲染纹理 具有仅深度渲染,并且没有颜色缓冲区。此用例的示例包括:

renderTextureDescriptor.graphicsFormat = GraphicsFormat.ShadowAutoRenderTexture.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 编译器由WebGL的 平台已更新至版本 2.0.19。这升级了本机代码对象文件格式,因此需要重新编译项目中的所有本机代码插件(C/C++ 代码插件)。如果您使用的是 Unity 的闭源第三方插件资源商店 ,例如,请记住向作者索取 Unity 2021.2 的更新版本。Emscripten 运行时 JavaScript 函数现已弃用。相反,调用该函数将 UTF8 编码的以 null 结尾的 C 字符串从 WebAssembly 堆封送生成 JavaScript 字符串。Pointer_stringify()``UTF8ToString()

十九、渐进式 GPU 光照贴图器放弃了对 CPU OpenCL 设备的支持

渐进式 GPU 光照贴图不再支持 CPU OpenCL 设备。如果未找到受支持的 GPU,但检测到 CPU OpenCL 设备,则会显示一条警告消息,通知您该设备已被跳过并回退到渐进式 CPU 光照贴图。渐进式 CPU 光照贴图为基于 CPU 的计算提供了更好的性能光照贴图 . 这种行为更改将自动发生,光照贴图应按预期进行计算。

二十、OnPostprocessAllAssets 行为更改]

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

为了改进资源导入流程,增强了回调功能。具体而言,回调:OnPostprocessAllAssets``OnPostprocessAllAssets

当资产数据库保证处于就绪状态时,可以在域重新加载后执行初始化。包含参数,如果域已重新加载,则该参数设置为 true。didDomainReload支持资产运营。这包括资源加载,其行为方式与通过菜单项加载资源的方式相同。已移出资产数据库导入循环。回调处理将推迟到资产导入完成。

将任何需要资产操作的域相关初始化逻辑移动到回调中;不要在方法中执行资产操作。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("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(assetPath);

if (txtObj == null)

Debug.Log("Old Behaviour: Asset hasn't been imported yet");

else

Debug.Log("New Behaviour: Asset is imported and loaded");

}

}

}

以下示例包含带有参数的新变体:OnPostprocessAllAssets``didDomainReload

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

二十一、无阴影的混合点光源和聚光灯在减色照明模式下烘烤直射光

混合模式的点光源和聚光灯现在在使用减法照明模式的场景中始终如一地提供烘焙直射光,无论其阴影类型设置如何。因此,静态的镜面照明游戏对象 在受影响的场景中可能看起来缺失。要解决此问题,请将受影响的混合模式灯替换为实时模式灯。或者,使用 Baked Indirect 或阴影遮罩 混合灯的照明模式。

二十二、着色器关键字系统改进

这着色 关键字系统现在允许每个着色器或计算着色器最多有 65534 个本地关键字,每个项目最多允许 2 个32-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# 编译器错误。

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

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

解决冲突的扩展方法

如果现有代码具有 .NET Standard 2.1 现在直接在类型上实现的扩展方法,则可以选择重命名扩展方法或使用基类库实现的方法。

例如,项目中的代码可能会实现以类型命名的扩展方法。在 .NET Standard 2.1 中,具有内置方法。您可以选择重命名扩展方法,也可以完全消除它并使用内置方法。CopyTo``ArraySegment``ArraySegment``CopyTo``CopyTo

解决冲突的程序集

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

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

二十四、Windows XR 插件已删除

Microsoft 已弃用 Windows XR 插件,现在通过 OpenXR 插件支持 Windows Mixed Reality (WMR) 功能和设备。

自 Unity 2021.2 起,Windows XR 插件已被删除。在 Unity 2021.2 中打开现有项目时,更新过程会删除 Windows XR 插件(如果存在)。若要继续将项目用于 Windows Mixed Reality,必须启用 Unity OpenXR 插件。根据所使用的功能,还必须安装 Microsoft 的混合现实 OpenXR 支持插件,并可能安装 Microsoft 混合现实工具包中的其他工具。

要升级到 Unity OpenXR 插件,请执行以下操作:

打开****项目设置** **窗。在XR光谱仪*插件* 管理部分中,在**“插件提供程序**”列表中启用 OpenXR。 如果需要,Unity 会下载并安装 OpenXR 插件。

启用 OpenXR 插件后,可以使用 Microsoft 提供的混合现实功能工具安装所需的支持包。

若要安装或更新 WMR 功能、工具和示例,请执行以下操作:

下载并运行混合现实功能工具。选择要更新的 Unity 项目,然后单击 Discover Features。在“平台支持”下,选择“混合现实 OpenXR 插件”。选择要添加的任何其他功能。单击获取要素。单击“导入”,然后单击“批准”以完成该过程。返回到 Unity 项目设置的 XR 插件管理部分,然后启用和配置添加的功能。

件** 管理部分中,在“插件提供程序**”列表中启用 OpenXR。 如果需要,Unity 会下载并安装 OpenXR 插件。

启用 OpenXR 插件后,可以使用 Microsoft 提供的混合现实功能工具安装所需的支持包。

若要安装或更新 WMR 功能、工具和示例,请执行以下操作:

下载并运行混合现实功能工具。选择要更新的 Unity 项目,然后单击 Discover Features。在“平台支持”下,选择“混合现实 OpenXR 插件”。选择要添加的任何其他功能。单击获取要素。单击“导入”,然后单击“批准”以完成该过程。返回到 Unity 项目设置的 XR 插件管理部分,然后启用和配置添加的功能。

有关设置新的和更新的 Unity 项目以使用 Windows Mixed Reality 的详细信息,请参阅 Microsoft 文档站点上的设置 XR 配置。

参考链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。