Version: 2022.1
旧版升级指南
升级到 Unity 2017.3

升级到 Unity 2018 LTS

注意:按照版本顺序遵循此部分中的建议。例如,如果需要将项目从 2018 升级到 2020,请在阅读 2020 升级指南之前阅读 2019 升级指南,了解是否需要进行任何更改。

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

请注意,2018 LTS 也称为 2018.4

页面大纲


改进了预制件

  • 预制件自动升级到新预制件系统
  • 预制件工作流程已更改,从而支持预制件嵌套。要编辑预制件,现在需要在预制件模式下将其打开。无法再在 Project Browser 中编辑预制件。
  • 还可以在预制件模式中进行结构更改,例如删除游戏对象、为游戏对象重设父子关系或将变换组件替换为 RectTransform。或者,如果希望完全移除预制件实例与预设件资源的链接,从而能够根据需要重建生成的普通游戏对象,则可以将预制件实例解压缩。无法再将预制件实例断开连接。
  • 用于创建游戏对象的 Editor 工具应该使用 ObjectFactory.CreateGameObject 来确保当前正在预制件模式下编辑预制件资源时,游戏对象最终位于预制件场景中。
  • 作为安全预防措施,具有 [ExecuteInEditMode] 属性的脚本使 Editor 在进入播放模式时退出预制件模式(如果打开的预制件上的任何脚本具有该属性)。有关如何使此类脚本与预制件模式兼容的详细信息,请参阅 ExecuteInEditMode 和新的 ExecuteAlways 属性的脚本参考页面。
  • 无法再通过脚本对预制件资源进行任意修改,因为预制件现在是导入的资源。现在需要使用 PrefabUtility.LoadPrefabContentsPrefabUtility.SaveAsPrefabAssetPrefabUtility.UnloadPrefabContents
  • 如果使用 AssetDatabase.AddObjectToAsset 将额外资源添加到预制件,现在必须在添加必备对象后调用 PrefabUtility.SavePrefabAsset

回到顶部

USS flex 简化扩展现在遵循 CSS 标准

  • USS flex 指令现在最多接受三个表示 flex-growflex-shrinkflex-basis 的参数。flex-shrink 和 flex-basis 参数是可选参数。如果省略,flex-basis 默认为 0,flex-shrink 默认为 1。
  • 在 2018.3 版之前,flex: N 等同于 flex N 0 auto。现在遵循 CSS 标准,等同于 flex: N 1 0。为了保留旧语义,您应该在 USS 文件中将所有 flex: N 指令替换为 flex: N 0 auto

回到顶部

支持记录托管用户线程中未处理的异常

  • 在 2018.3 版之前,Unity Editor 不会记录托管用户线程中抛出的未处理异常。在 2018.3 版之后,托管用户线程中抛出的未处理异常将记录在 Unity Editor 控制台中。
  • 因为日志记录现在包含所有托管用户线程,所以您可能会看到项目中始终已经抛出但直到现在还没有发送到控制台的异常。

回到顶部

现在已在 DirectX(11 和 12)中反转 VFACE 着色器变量

  • 以前渲染到立方体贴图时,DirectX 和其他图形 API 之间的 VFACE 着色器变量不一致。现在具有相同行为。
  • 如果在 DirectX 着色器中使用了 VFACE 布尔着色器变量来渲染立方体贴图,则必须在代码中翻转逻辑。
  • 请参阅问题 ID 1027670

回到顶部

将 PhysX 从 3.3.1 升级到 3.4.2

物理行为已改变,一些项目的行为可能会不同于新版本。特别是以下情况:

  • Persistent Contact Manifold 模式中,触点面片现在最多包含 6 个触点。在以前版本中,每个面片最多包含 5 个触点,因此现在有所增加。现在可以使用新代码将面片合并在复合体中,并可以使用新代码选择触点。碰撞看起来比以前精确得多。如果项目依赖于特定触点布局,可能需要对其进行处理以便与新代码兼容。凸面体与网格和图元碰撞时,最有可能注意到这一点。
  • 现在使用一种新算法来计算__与地形的触点。此算法在以前作为特殊情况,但现在与用于 MeshColliders 的网格图元代码相同。此算法稳健,更准确,性能也好。但不支持 TerrainData.thickness,这意味着现在有可能出现地形穿隧效应。要避免此问题,必须在快速移动的对象上启用连续碰撞检测。在此之前,如果发现一个物体的深度不超过地形下的 TerrainData.thickness,则会自动冒出,但法线一直不正确。为了保留以前这种行为,请取消选中 Physics 设置中的 Enable Unified Heightmaps__ 选项。
  • 负网格缩放在任何情况下都不再直接导致网格烘焙。不再烘焙凹面网格。然而,凸面网格仍然需要进行缩放才能烘焙。引入此变更后,负缩放将在 scale.x * scale.y * scale.z < 0 时反转网格法线。另外,就像以前一样,诸如倾斜和截断之类的非普通缩放仍然需要进行烘焙。
  • 已弃用__凸面网格膨胀__,因为新的凸面外壳计算算法 (Quickhull) 更能容忍输入网格中的各种缺陷,似乎不再需要该功能。

回到顶部

已将 AssetBundle.mainAsset 属性标记为“过时”

  • 在 5.0 版之前的 Unity 版本中,用户必须使用 AssetBundleBuildAssetBundle API 来构建 Asset Bundle,而这需要提供一个对象(在使用 AssetBundle 的 mainAsset 属性加载时返回该对象)。
  • AssetBundle.BuildAssetBundle API 在 Unity 5.0 中标记为过时,已被 AssetBundle.BuildAssetBundles 替代,后者改变了从 AssetBundle 获取资源的方式。
  • 现在需要通过 AssetBundle.LoadAsset API 来获取资源名称或者路径才能从 AssetBundle 获取内容。请参阅关于“构建 AssetBundles”、“本机使用 AssetBundles”以及 AssetBundle 脚本 API 的文档。

回到顶部

升级使用 NavMesh 组件的项目

  • 如果将项目从 2018.2 或更早版本转移到 2018.3b 且项目使用从 Unity 的 GitHub 代码仓库获取的 NavMesh 组件,则现在需要使用此分支

回到顶部

粒子系统错误修复

Unity 2018.3 包含一些粒子错误修复,这可能会影响在以前版本中创建的项目。

  • 对公告牌粒子采用非均匀变换缩放时,Y 轴和 Z 轴会发生反转。现在,此问题已得到修复。
  • 对网格粒子采用非均匀变换缩放时,在缩放后会应用旋转。这是 2017.x 中的回归问题。在 5.6 版和更低版本中的表现是正常的,但在 2017 版周期中遭到破坏。修复此问题可以更正 5.6 及更低版本中创建的内容,但会改变 2017.x 版中创建的内容。
  • 球形风区对粒子的影响与树相反。此问题已经得到修正,所以球形风区现在会排斥而不是吸引粒子。可以通过取消外力乘数 (External Forces Multiplier) 或风区 (Wind Zone) 强度来恢复先前行为。Unity 无法自动更改这一点,因为具有树或定向风区的场景可能会受到不当影响。

回到顶部

C# 编译器升级到 Roslyn

在 2018.3 版之前,Unity Editor 在编译项目中的 C# 文件时使用 Mono C# 编译器 (mcs)。从 2018.3 版开始,以新脚本运行时 (.NET 4.x Equivalent) 为目标的项目使用 Roslyn C# 编译器 (csc)。切换到 Roslyn 后可能会发现行为差异:

回到顶部

已移除 UnityScript 和 Boo 脚本编译器

在 Editor 中无法再编译 UnityScript (.js) 和 Boo (.boo) 脚本文件。

有关更多信息,请参阅发表于 2017 年 8 月的这篇博客文章;并可使用 unityscript2csharp 工具将 UnityScript 转换为 C#。

回到顶部

Animator 根运动 (Root Motion) 播放已更改

Animator 根运动播放功能已稍作更改,旨在纠正在 Animation 窗口中创作根运动动画 (Root Motion Animations) 时出现的某些不一致之处。

  • 不再需要为 AnimationClip(动画剪辑)生成根运动曲线。根运动的应用现在仅取决于 Animator.applyRootMotion

2018.2 到 2018.4 的等效情况

情况 生成根运动 Animator.applyRootMotion 2018.2 2018.3 和 2018.4 (LTS)
A 在根变换 (Root Transform) 上累计应用根运动。 与 2018.2 相同
B 应用 AnimationClip 中编写的位置 (Position)、旋转 (Rotation) 和缩放 (Scale) 曲线。 与 2018.2 相同
C* 无根变换运动 应用 AnimationClip 中编写的位置 (Position)、旋转 (Rotation) 和缩放 (Scale)。
D* 无根变换运动 在根 (Root) 上累计应用根运动。

对于情况 C 和 D,要在 2018.3 中获得相同的结果,您需要实现 OnAnimatorMove,然后在不想应用根运动的情况下放弃 Animator.deltaPositionAnimator.deltaRotation

如果项目使用 applyRootMotion 使根变换上的位置 (Position)、旋转 (Rotation) 和缩放动画 (Scale Animation) 进行“静音”,则需要手动覆盖根变换 (Root Transform) 属性。

回到顶部

UIElements.ContextualMenu 更改

UIElements.ContextualMenu 菜单操作回调现在接受 ContextualMenu.MenuAction 参数而不是 EventBase 参数。

ContextualMenu.InsertSeparator 接受一个额外的 string 参数。

回到顶部

Multiplayer:已弃用的旧版网络 API 已被删除(基于 RakNet)

此功能在 Unity 5.1 中已弃用,现已删除。在 Unity 2018.2 版的项目中不能再使用此功能。

请参阅多玩家和联网部分以了解与 Unity 网络功能相关的更多信息。

回到顶部

在使用透明度的情况下导入 Photoshop 数据文件 (PSD)

具有实际透明度时,Photoshop 会调整像素颜色以将像素颜色与哑光(背景)颜色混合。在我们的如何准备 Alpha 通道文档中介绍了正确准备 Alpha 通道的过程。

可以忽略此文档中介绍的扩张,重要的是文档中指出,您会希望拥有包含单独 Alpha 通道/遮罩的“不透明”图像(而不是拥有透明度)。Unity 以前会调整颜色来“移除”哑光,但从 2018.2 版开始已经停止了此功能。如果您的 PSD 具有透明度,则可能会开始看到边缘的白色。要解决此问题,请参阅上面的手册链接,并创建一个实际的 Alpha 通道(而不是透明度)。

回到顶部

在禁用或销毁游戏对象时,从 MonoBehaviour 返回的协程将不再启动。

在以前的版本中,禁用或销毁游戏对象后,将停止其子 MonoBehaviours 上所有正在运行的协程。但是,在某些情况下,从此期间内调用的方法(例如,OnBecameInvisible())进行启动的协程在以前是允许启动的。这种情况导致了与组件顺序相关的行为,在某些情况下会导致崩溃。

在 Unity 2018.1 版中,在禁用或销毁游戏对象期间返回的协程将不再启动。

回到顶部

BuildPipeline API 现在返回 BuildReport 对象,而不是字符串

BuildPipeline API(例如 BuildPipeline.BuildPlayerBuildPipeline.BuildAssetBundles)以前返回字符串。如果构建成功,返回结果为空;如果构建失败,则包含错误消息。

在 2018.1 版中,这种返回结果已被新的 BuildReport 对象(其中包含关于构建过程的更丰富信息)所取代。

要检查构建是否成功,请检索报告对象的 summary 属性,并检查其 result 属性:如果构建成功,该属性将为 BuildResult.Succeeded。例如:

var report = BuildPipeline.BuildPlayer(...);

if (report.summary.result != BuildResult.Succeeded)
{
    throw new Exception("Build failed");
}

回到顶部

播放器退出通知已从消息更改为事件

以前,为了在 Unity 独立平台播放器退出时收到通知,需要在 MonoBehaviour 上实现 OnApplicationQuit 方法,而为了使播放器中止退出,需要调用 Application.CancelQuit

现在引入了两个新事件。这两个事件是 Application.wantsToQuitApplication.quitting。通过监听这些事件,即可在 Unity 独立平台播放器退出时获得通知。播放器意图退出时调用 Application.wantsToQuitwantsToQuit 的监听器必须返回 true 或 false。如果希望播放器继续退出,则返回 true;如果希望播放器中止退出,则返回 false。播放器已确定退出而无法中止时调用 Application.quitting 事件。

已弃用 Application.CancelQuit,请改用 Application.wantsToQuit

using UnityEngine;

public class PlayerQuitExample

{

    static bool WantsToQuit()

    {

        // 是否希望 Editor 退出?

        return true;

    }

    static void Quit()

    {

        Debug.Log("Quitting the Player");

    }

    [RuntimeInitializeOnLoadMethod]

    static void RunOnStart()

    {

        Application.wantsToQuit += WantsToQuit;

        Application.quit += Quit;

    }

}

回到顶部

在 .NET 平台上已弃用 AvatarBuilder.BuildHumanAvatar

此变化影响以下运行时平台:WSAPlayerX86、WSAPlayerX64 和 WSAPlayerARM。

目前没有替代项。

回到顶部

已弃用 TouchScreenKeyboard.wasCanceled 和 TouchScreenKeyboard.done

可查询一个新的 TouchScreenKeyboard.status 来涵盖已弃用状态和更多其他状态。

回到顶部

已从 Unity 安装程序中移除 MonoDevelop 5.9.6,并且在 Unity 中已不再提供其支持。

在 macOS 上,已将 MonoDevelop 5.9.6 替换为 Visual Studio for Mac(作为 macOS 安装程序中的捆绑 C# 脚本编辑器)。在 Windows 上,Visual Studio 2017 Community 现在是与 Unity 一起安装的唯一 C# 脚本编辑器。

安装在 Unity 可执行文件旁边的默认位置时,Unity 在偏好设置中不再将 MonoDevelop 视为“MonoDevelop (built-in)”外部脚本编辑器。未安装且在偏好设置中未选择 C# 代码编辑器时,Unity 使用系统默认应用程序来打开 C# (.cs) 脚本。

回到顶部

BuildPipeline 回调接口现在接受 BuildReport 对象

BuildPipeline 回调接口 IPreprocessBuildIPostprocessBuildIProcessScene 已更改,现在要求传入 BuildReport 对象。这取代了以前的构建路径/目标平台参数;如果要实现这些接口,需要更改代码。

构建路径和目标平台都是可以通过 BuildReport 对象进行访问的。构建路径现在是 report.summary.outputPath,而目标平台是 report.summary.platform

回到顶部

以后不再通过专用导入器来导入位于插件文件夹中的资源

以前使用专用导入器来导入位于插件文件夹中的资源(例如,目录中扩展名为 .bundle、.plugin 或 .folder 的资源)。比如,通过纹理导入器导入纹理,通过音频导入器导入 AudioClips 等等。现在使用默认导入器来导入所有这些资源,这意味着您将不能像以前那样引用这些资源,因为它们不再具有专门的类型(纹理、AudioClip 等)。插件文件夹包含在资源包中,因此除非使用插件访问方法,否则无法从外部访问其中的资源。

要继续使用这些资源,必须将它们移出插件文件夹。

回到顶部

粒子系统网格粒子错误地应用了轴心偏移值

用于将轴心偏移应用于网格的数学公式以前不正确,与用于公告牌粒子的方式不一致。为了实现正确缩放,轴心偏移应该乘以粒子大小,因此轴心偏移 1 等于粒子的一个完整宽度。

对于网格,该大小以前被平方,这意味着轴心大小基于平方后的粒子大小。因此,在包含各种大小的粒子的系统中,无法获得一致结果。

对于使用相同大小的粒子的系统,可以对公式进行逆向工程来确定需要将轴心偏移值调整多少才能补偿此行为变化:

旧公式:__offset = size * size * pivot__

新公式:__offset = size * pivot__

因此,如果所有粒子的大小相同:

newOffset = pivot / size

在粒子大小不同的系统中,需要对相关系统进行可视化重估。

回到顶部

GPU 实例化支持全局光照

从 2018.1 版开始,Unity 中的 GPU 实例化渲染支持全局光照 (GI)。每个 GPU 实例可支持来自不同光照探针、一个光照贴图(但为图集的不同区域)或一个光照探针代理体组件(为包含所有实例的空间体积进行烘焙)的 GI。标准着色器和表面着色器自动随附这些更改,但是您需要更新自定义着色器代码才能启用这些功能。

回到顶部

手柄绘制和大小函数默认值

UnityEditor.IMGUI.Controls 命名空间中的复杂手柄(例如 BoxBoundsHandle、CapsuleBoundsHandle、SphereBoundsHandle、ArcHandle 和 JointAngularLimitHandle)具有可以分配值的委托,从而改变其控制点的外观。以前,将 null 值分配给这些委托将回退到默认行为。现在,为它们分配 null 值不会导致任何行为,因此更容易禁用特定控制手柄。如果需要将控制手柄重置为其默认行为,现在每个类分别有默认方法的公共 API 点。

回到顶部

在 Unity Editor 中编译不安全的 C# 代码现在需要启用一个选项。

现在,编译“不安全”的 C# 代码需要在预定义程序集(例如 Assembly-CSharp.dll)的 Player Settings 中以及程序集定义文件程序集的 Inspector 中启用 Allow ‘unsafe’ code 选项。启用此选项会让 Unity 在编译脚本时将 /unsafe 选项传递给 C# 编译器。

回到顶部

“UnityPackageManager”目录重命名为“Packages”

在 2017.2 和 2017.3 版中,Unity Package Manager 引入了 UnityPackageManager 目录,用于存储名为 manifest.json 的文件。可通过脚本使用以 Packages 开头的虚拟相对路径来访问包内容。

在 2018.1 版中,__UnityPackageManager__ 目录已重命名为 Packages__,使之与打包资源的虚拟相对路径一致。应该将 manifest.json__ 文件自动移到新目录。

因此:

  • 如果项目使用 Perforce 或 Git 之类的版本控制系统 (VCS),可能需要更新其配置来跟踪 Packages 目录,而不是 UnityPackageManager 目录。

  • 如果项目因使用 Nuget(或任何外部包管理器)而需要使用 Packages 目录,则应该更改其配置以使用其他目录。之所以建议执行此操作,是为了消除 Unity Package Manager 在很小的概率下获取包而可能导致编译错误或导入错误等难以调试的问题。

  • 在迁移到新目录后,可以安全删除 UnityPackageManager 目录。

旧版升级指南
升级到 Unity 2017.3