此页面列出了 Unity 2021 LTS 版本中的更改,这些更改可能会在您从 2020 版本升级到 2021 LTS 时影响现有项目。
注意:2021 LTS 也称为 2021.3。
此升级指南描述了如何将 Unity 的内置渲染管线升级到 2021 版本。要将其他渲染管线升级到 2021 版本,请参阅
要升级其他包,请参阅您正在使用的包的文档。
设备模拟器 现在是编辑器的一部分,可以通过游戏窗口访问。要设置设备模拟器,请将 UnityEngine.Device
命名空间添加到 Screen、Application 和 SystemInfo 类:UnityEngine.Device.Screen;
UnityEngine.Device.Application;
UnityEngine.Device.SystemInfo;
要切换到 UnityEngine.Device
,请在您要与模拟器一起使用的每个脚本中添加以下逻辑: using Screen = UnityEngine.Device.Screen; using Application = UnityEngine.Device.Application; using SystemInfo = UnityEngine.Device.SystemInfo;
新的命名空间 UnityEngine.Device
会从模拟器(在编辑器中)平滑过渡到具有运行时构建的实际设备 API。
编辑器现在会自动烘焙默认的 天空盒一种特殊类型的材质,用于表示天空。通常是六面体。 更多信息
在 词汇表 中查看 探针和 环境探针,并保留该数据,直到您手动烘焙 场景场景包含游戏环境和菜单。将每个唯一的场景文件视为一个唯一的关卡。在每个场景中,您放置环境、障碍物和装饰物,本质上是设计和构建游戏的各个部分。 更多信息
在 词汇表 中查看。升级后,没有 环境光照不来自任何特定方向的光线,并向场景的所有方向提供相等的光线。 更多信息
在 词汇表 中查看 贡献的场景可能在视觉上发生变化。要恢复这些场景的原始外观,请将环境光照 强度乘数 设置为 0。或者,将天空盒设置为黑色,烘焙场景,然后将天空盒重置为您首选的天空颜色。
Unity 的渐进式 光照贴图器Unity 中的一种工具,根据场景中灯光和几何体的排列烘焙光照贴图。 更多信息
在 词汇表 中查看 现在默认会为每个场景自动生成环境探针和天空盒 反射探针一种渲染组件,它捕捉周围环境的球形视图,就像相机一样。然后捕获的图像将存储为立方体贴图,可供具有反射材质的物体使用。 更多信息
在 词汇表 中查看。这意味着场景会根据 **灯光** 设置面板中的 **环境** 选项卡中的设置自动接收环境光照。编辑器会在环境光照发生变化时更新环境探针和天空盒反射探针,直到您生成光照。当您使用 **生成光照** 控件进行烘焙时,编辑器将停止更新探针,并且仅在下次烘焙时再次更新探针。当您启用 **自动生成** 选项时,编辑器将继续在环境光照发生变化时更新探针。如果您生成了光照,然后通过从项目中删除光照数据资产来删除此光照数据,则编辑器会自动再次生成环境探针和天空盒反射探针。
升级项目时,有一种情况需要采取行动。当您不希望在项目中使用任何环境光照贡献,而该项目也
在这种情况下,导航到 **窗口** > **渲染** > **灯光设置** > **环境**,通过进行以下更改之一来禁用自动生成的环境探针和天空盒反射探针的环境贡献
用于管理代码覆盖率的用户界面已从常规首选项移动到 代码覆盖率包 中。
代码覆盖率包作为发布包,可通过 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;
}
}
以前,某些力场属性在不同的帧速率下(或如果使用时间管理器设置中的时间缩放)的行为有所不同
粒子系统一种组件,通过在场景中生成和动画大量小的 2D 图像来模拟液体、云和火焰等流体实体。 更多信息
在 词汇表 中查看 现在使用 30fps 的参考帧速率作为模拟的基础。如果您的应用程序以不同的帧速率运行,则以下设置与早期版本的 Unity 相比可能会有所不同
如果这些设置受到影响,请调整受影响区域的强度以获得所需的显示效果。
以前,距离发射速率会忽略开始延迟设置。现在,如果定义了开始延迟设置,它会延迟基于距离的发射开始。
如果此字段以前已设置,您可能需要调整它。
PackedAssets.file 已被标记为已弃用,没有直接替换。以前,它包含一个整数,表示 BuildReport.files 中的文件 ID 或索引。要查找 BuildReport 文件,请使用 PackedAssets.shortPath。
实验性的 地形场景中的地形。地形游戏对象将一个大型平面添加到您的场景中,您可以使用地形检查器窗口来创建详细的地形。 更多信息
在 词汇表 中查看 API 已移至非实验性命名空间。地形 API 还有一些其他细微的更改。如果您使用过实验性的地形 API,请改用以下 API
UnityEngine.TerrainTools
;UnityEditor.TerrainTools
;UnityEngine.TerrainUtils
;以下是 API 更改的完整列表
UnityEngine.Experimental.TerrainAPI
和 UnityEditor.Experimental.TerrainAPI
现在分别为 UnityEngine.TerrainTools
和 UnityEditor.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
及其重载已重命名为 Texture2D.Reinitialize
。
API 更新程序应自动重命名。如果没有,请将 Texture2D.Resize
的任何用法更改为 Texture2D.Reinitialize
。
Android 构建管线的大部分现在是增量的,Unity 删除了以前构建管线中的以下功能
默认的 mainTemplate.gradle 文件已更改。如果您使用自定义主模板,则必须重新生成它并在其上重新应用您的更改。否则,如果您的应用程序使用 Resources.Load,它可能会遇到性能下降。
默认的 Image.scaleMode 已从 ScaleAndCrop 更改为 ScaleToFit。
图像的预期行为是按元素的大小缩放,因此我们将 Image.scaleMode 的默认值更改为 ScaleToFit。如果您没有覆盖 Image 缩放模式,一些裁剪的图像可能会缩小以适应元素的大小。如果 ScaleAndCrop 是您的图像的预期模式,您可以通过在您的 UXML 文件内联样式中添加以下值来覆盖它们的样式
-unity-background-scale-mode: scale-and-crop;
您也可以创建一个包含覆盖的样式类,并将它应用于需要 ScaleAndCrop 的图像。
底层的 C# 运行时 Mono 在最新版本中已升级。这包括来自 Mono 上游版本的许多修复,以及一些值得注意的行为变化。
Directory.GetFiles
不再保证返回排序的列表。Directory.GetFiles(dir).OrderBy(f => f)
;Object.GetHashCode
现在返回不同的值,不应在操作系统之间作为确定性哈希算法使用。GetHashCode
的结果,即不要对其进行序列化或期望它在下次代码在新的进程中运行时保持一致。Unity 建议使用确定性哈希算法,例如 MD5。自适应性能包的 3.0 版现已推出。有关如何升级到 3.0 版的信息,请参阅 自适应性能升级指南。
以前,如果您将 RenderTexture.depth
属性设置为 32 位,您可能会根据平台获取 D24_S8。现在,如果您将其设置为 32 位,您将获得 D32_S8,如果当前平台支持,深度组件将为 32 位。但是,这将使该 深度缓冲区一个内存存储,它保存图像中每个像素的 z 值深度,其中 z 值是每个渲染像素从投影平面到深度的深度。 更多信息
查看 术语表 的内存使用量增加一倍。
新的 RenderTexture.depthStencilFormat
属性返回图形 API 用于在视频内存中创建资源的格式。您也可以使用此属性来请求特定格式。但是,并非所有平台都支持所有深度模板格式。当您将 DepthStencilFormat
属性设置为不受支持的格式时,Unity 会自动选择具有等于或大于深度和模板组件位的兼容格式。
RenderTexture 资源现在会序列化您选择的深度模板格式。如果您使用的是以位数而不是格式进行操作的 API,则这些位会被映射到格式,然后序列化该格式。深度设置为超过 16 位的先前版本的 RenderTexture 资源将自动升级为使用 D24_S8。
在使用 DirectX 图形 API 的某些平台(例如 Windows)上,这会导致格式的深度位数减少,因为如果您将位数设置为大于 16,则图形后端将在内部选择 D32_S8 格式。为了确保所有平台上的一致升级,D24_S8 用于所有平台上的自动升级程序。但是,如果您在项目中具有 RenderTexture 资源,这可能会在项目的渲染输出中引入视觉伪影。查看这些资源,并在需要时将深度模板格式更改为 D32_S8。可能会出现以下问题
以下图形格式现已弃用
这些 **Auto** 格式对使用的确切格式不明确,并且可能会因平台而异。
删除这些已弃用格式的使用步骤取决于格式和用例。
要获取当前平台的自动视频格式,请使用 SystemInfo.GetGraphicsFormat(DefaultFormat.Video)
。
GraphicsFormat API 通常使用 DepthAuto 或 ShadowAuto 来创建 渲染纹理一种特殊类型的纹理,在运行时创建和更新。要使用它们,首先创建一个新的渲染纹理,然后指定您的相机之一渲染到其中。然后,您可以在材质中使用渲染纹理,就像使用普通纹理一样。 更多信息
查看 术语表,只有深度渲染,没有颜色缓冲区。这种用例的示例是
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 格式表示自动选择的适合当前平台的深度格式。要替换此情况下的弃用值,请使用 SystemInfo.GetGraphicsFormat(DefaultFormat.Depth/Shadow)
高级用户可用的 asm.js 链接器目标不再可用。
Pointer_stringify()
现在已弃用。改为调用函数 UTF8ToString()
将 UTF8 编码的空终止 C 字符串从 WebAssembly 堆编组到 JavaScript 字符串。渐进式 GPU 光照贴图不再支持 CPU OpenCL 设备。如果未找到支持的 GPU 但检测到 CPU OpenCL 设备,则警告消息会通知您该设备被跳过,并回退到渐进式 CPU 光照贴图。渐进式 CPU 光照贴图为基于 CPU 的 光照贴图一个预渲染的纹理,它包含光源对场景中静态对象的影响。光照贴图叠加在场景几何体之上,以创建照明效果。 更多信息
查看 术语表 计算提供了更好的性能。这种行为更改将自动发生,并且光照贴图应按预期计算。
当 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");
}
}
}
以下示例具有新的 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
方法也会增加域重新加载时间。最佳实践是在这些回调中尽量减少处理,以提高迭代之间编辑器的响应能力。
混合模式 点光源和聚光灯现在在使用 减色照明模式 的场景中一致地贡献烘焙的直接光,无论其 阴影类型 设置如何。因此,受影响场景中静态 游戏对象Unity 场景中的基本对象,可以表示角色、道具、场景、摄像机、航路点等等。游戏对象的功能由附加到它的组件定义。 更多信息
参见 术语表 的镜面反射照明可能看起来缺失。要解决此问题,请将受影响的混合模式灯光替换为 实时模式灯光。或者,使用 烘焙间接光 或 阴影遮罩纹理,其 UV 布局和分辨率与其对应的光照贴图相同。 更多信息
参见 术语表 照明模式(与混合灯光一起使用)。
着色器在 GPU 上运行的程序。 更多信息
参见 术语表 关键字系统现在允许每个着色器或计算着色器最多 65534 个本地关键字,每个项目最多 232–2 个全局关键字。现在,你在着色器或计算着色器中声明的所有关键字都是此着色器特有的。你在带有 _local 后缀的指令中声明的关键字不受全局关键字状态的影响。
示例
着色器中的一个通道声明以下关键字
#pragma shader_feature FOO BAR
#pragma shader_feature_local BOO BAZ
使用此通道时,如果全局或材质上启用了关键字 FOO 和 BAR,则启用它们。仅当在材质上启用了关键字 BOO 和 BAZ 时,才会启用它们。
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
托管插件,则项目无法构建。
Microsoft 已弃用 Windows XR一个涵盖虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用程序的总称。支持这些形式的交互式应用程序的设备可以称为 XR 设备。 更多信息
参见 术语表 插件,现在通过 OpenXR 插件支持 Windows 混合现实混合现实 (MR) 将自己的虚拟环境与用户的真实世界环境相结合,并允许它们相互交互。
参见 术语表 (WMR) 功能和设备。
要升级到 Unity OpenXR 插件
启用 OpenXR 插件后,可以使用 Microsoft 提供的 混合现实功能工具 来安装所需的配套包。
要安装或更新 WMR 功能、工具和示例
有关将新旧 Unity 项目设置为使用 Windows 混合现实的更多信息,请参阅 Microsoft 文档网站上的 设置 XR 配置。