介绍

由于 Unity 2018.3 发布的嵌套 Prefab 对于改善工作流有着巨大的提升,因此早在 Unity 2018.3 Beta 测试的时候就已经尝试在单独的分支上将项目升级,见 Unity 2017.4 升级 2018.3 测试版 - 狂飙

上一篇文章 Unity 2018.3 正式发布 - 狂飙 中介绍了我认为较为重要的功能,没想到这个版本功能更新都非常强大,升级具有非常大的诱惑力。团队开发的产品还未正式上线,因此升级 Unity 版本的风险较小,权衡之后决定升级,体验新版本的 Prefab 能带来多少效率提升。

Unity 开发团队应该都是去过圣诞节了,Unity 2018.3.0f2 在 2018/12/13 发布之后应该是一周一个新版本的,因为过节都没有了,所以升级只能选择这个正式版本。不过好在 Beta 版本已经发布了 12 个,正式版本也发布了 2 个,经过这么多版本的测试应该比较稳定。

环境

  • Unity 2017.4.2f2
  • Unity 2018.3.0f2
  • macOS 10.13.6
  • Windows 10
  • Unity Cache Server 6.0.0

升级方法

参考 Unity 2017.4 升级 2018.3 测试版 - 狂飙 即可,上面已经列出了相关要注意的问题,Unity 2018.3.0f2 正式版发布之后脚本上需要改动的东西也都是之前记录的。

下面主要介绍这个正式版中遇到的问题。

问题

编译错误

编译时如果出现类似以下内容的报错,包含 Failed to resolve assembly 之类的错误,那么应该是 Unity 内置数据库出现问题

解决方法:

  1. 将 Unity 安装目录中 UnityExtensions 剪切到临时目录
  2. 打开项目出现报错后关闭项目
  3. 将 UnityExtensions 剪切回 Unity 安装目录中
  4. 打开项目,编译错误消失

当然,完全重新导入项目也可以,不过时间太长,没有必要。

未测试过的方法:做这些操作前将 Library/AssetDatabase 或其他相关文件删除后再打开项目试试。

此问题 Unity 各个版本都存在,非常难以复现,出现时最快最有效的方法就是上面写的那种。猜测可能的原因是打包被中断,Unity 进程被强制结束后导致内部数据库状态未正确写入。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
error CS0234: The type or namespace name `EventSystems' does not exist in the namespace `UnityEngine'. Are you missing an assembly reference?
error CS0246: The type or namespace name `UIBehaviour' could not be found. Are you missing an assembly reference?



Field 'System.Collections.Generic.List`1<UnityEngine.UI.Image> ButtonLock::_targetImages' from 'Library/ScriptAssemblies/Assembly-CSharp.dll', exception Failed to resolve assembly: 'UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:LogFormat(LogType, String, Object[])
UnityEngine.Debug:LogFormat(String, Object[])
UnityEditor.AssemblyTypeInfoGenerator:WillSerialize(FieldDefinition) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs:426)
UnityEditor.AssemblyTypeInfoGenerator:GetFieldInfo(TypeDefinition, FieldDefinition, Boolean, Dictionary`2) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs:384)
UnityEditor.AssemblyTypeInfoGenerator:GetFields(TypeDefinition, Boolean, Dictionary`2) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs:345)
UnityEditor.AssemblyTypeInfoGenerator:AddType(TypeReference, Dictionary`2) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs:261)
UnityEditor.AssemblyTypeInfoGenerator:GatherClassInfo() (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs:445)
UnityEditor.AssemblyHelper:ExtractAssemblyTypeInfo(BuildTarget, Boolean, String, String[]) (at /Users/builduser/buildslave/unity/build/Editor/Mono/AssemblyHelper.cs:342)
UnityEditor.BuildPipeline:BuildAssetBundlesWithInfoInternal(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTargetGroup, BuildTarget)
UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTargetGroup, BuildTarget) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline.bindings.cs:471)
UnityEditor.BuildPipeline:BuildAssetBundles(String, AssetBundleBuild[], BuildAssetBundleOptions, BuildTarget) (at /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline.bindings.cs:457)
...

(Filename: /Users/builduser/buildslave/unity/build/Editor/Mono/BuildPipeline/AssemblyTypeInfoGenerator.cs Line: 426)

Prefab 多个根结点

使用 Unity 2018.3 打开项目时会报以下错误:

1
2
3
4
5
Prefab "xxxxx" has multiple roots.
We've upgraded your prefab to work with the new nested prefab structure, but please verify that this is the behavior you intended to have.

Prefab Mode: Multiple roots detected. Combined under new generated root. Prefab 'Assets/xxxxx.prefab'
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at ?)

打开对应的 Prefab 发现的确很奇怪,正常的结构是

1
2
3
4
xxxxx
  a
  b
  c

现在打开却是

1
2
3
4
5
xxxxx
  xxxxx
    a
    b
    c

在 Prefab 编辑界面点击 Save 提示:

1
You are trying to replace or create a Prefab from the instance 'xxxxxxxxx' that references a missing script. This is not allowed.
  1. 使用文本编辑器打开 Prefab 文件,搜索提示的结点名字,将对应的 GameObject 整段删除,即 --- 开头到下一个 --- 为止。
  2. 然后使用 Unity 再次打开,Unity 有可能会崩溃几次。
  3. 使用 Unity 正常打开项目后,再次打开 Prefab 即能看见多余的结点,见下图,然后在 Unity 中再次删除无用结点,重新整理层次结构,去除 Unity 自动添加的父结点,保存即可。

第 3 步看到的层次结构如下,可以看到 x y z 是多余结点,仔细检查发现 x y z 结点是 UI 内部的结点,不知道因为什么原因被错误地当成根结点保存在 Prefab 中,有可能是因为保存 UI Prefab 工具未正确处理多选 GameObject 后保存导致。

1
2
3
4
5
6
7
8
xxxxx
  xxxxx
    a
    b
    c
  x
  y
  z

注意:由于 Prefab 的根结点无法删除,那么可以将子结点中的所有组件拷贝到根结点上,同时一定要注意更新组件上对子结点的引用。

问题产生的原因应该是之前版本的 Unity 未将不再使用的 GameObject 从 Prefab 中删除,而 Unity 2018.3 对这种情况识别为 Prefab 存在多个根结点。

Unity Cache Server 异常

发现导入资源的时间较长,而且在不同人的机器上 Unity Cache Server 居然连接不上。

查看服务的日志显示一切正常,但是在 Unity 客户端 Preferences/Cache Server/Check Connection 时发现问题,默认情况下会自动负载均衡到 5 个不同的进程中,反复多次点击 Check Connection 会发现会随机提示 Connection failed!

使用的 Unity Cache Server 6.0.0 版本,同时开启了 5 个进程。

应该是由于很多人一起升级 Unity,项目的资源需要重新从 Unity Cache Server 上下载,Unity Cache Server 部分工作进程出现了假死的情况。

最简单的解决方案就是直接重启服务。

当然这有可能是 Unity Cache Server 的 Bug,由于当前使用的版本是三月份发布的 6.0.0,因此直接升级到 6.2.3 最新版本。

构建依赖

由于 Unity 2018.3.0f2 开始使用自带的 Open JDK,而且使用的 Android NDK 版本也升级了,因此需要在构建时指定路径。

Specifying NDK Location on a headless buildserver - Unity Forum

建议写单独脚本控制 Android SDK、Android NDK、Java SDK 的路径,这样可以保证仓库的不同版本都可以正确打包,而不会出现依赖库的版本不正确问题。

其他问题

由于需要为整个团队升级,不要遗漏一些额外的事情:

打包机升级、Android iOS 测试、Unity Cache Server 升级。

升级时,一定要注意顺序:

  1. 通知所有人停止向主分支推送
  2. 合并 Unity 升级分支到主分支
  3. 通知所有人升级 Unity 并且在拉取仓库最新更新后才可以打开 Unity

已知 Bug

过小的 Sprite 无法在 UI 中正确显示

只出现在 Windows 编辑器上,测试时发现 UI 使用的背景图片是一个 Max Size 32 的图片,鼠标划过 Hierarchy 视图中的结点造成重绘,Game 视图与 Scene 视图会以极高频率的闪烁。

经过检查发现只要禁用主相机就没有问题,尝试将主相机的 viewport 设置为 0 0 0.5 0.5 左下角,发现主相机错误地显示在了 UI 相机前,但是主相机的 depth 要低于 UI 相机。 刚开始时怀疑是 UI 上使用了 Mask 之类的东西,修改了模板缓存引起的,但是大部分其他界面都没有这个问题。 尝试排查各种选项,相机上的所有设置,Image 控件上的所有设置,Image 所使用的纹理高级选项,都无效。 后来注意到 Android 平台设置中有一个 Max Size 是 32,尝试改为更高的值后问题消失!最终确认是 Unity 的 Bug。

解决方法也非常简单,将对应纹理的平台 Max Size 设置为 64 或以上即可。

尝试构建了一个最小复现工程,但是不是每一台 Windows 电脑都能复现,很奇怪。

工程地址:networm/Unity2018.3.0f2-UICamera-depth-incorrect-when-Sprite-32x32

Component 菜单警告

出现以下提示应该是因为 Unity 会将所有的脚本添加到 Component/Scripts 下面,我认为可以忽略

1
Unable to insert menu item into submenu since index exceeded limit of 1000, item's parent:Component

macOS 编辑器下切换窗口闪烁

Scene 视图与 Game 视图放在同一个 Tab 栏中,在这两个视图之间切换时视图显示区域会变白,然后马上恢复正常。

macOS 下无法打开新项目

应该是 Unity 的 Bug,Unity 如果已经打开了一个项目,使用菜单 File/Open Project 打开另外一个项目,当前项目关闭后另外一个项目并不会打开。

macOS 下菜单快捷键重叠

显示上的小 Bug,重启后就消失了,不确定是什么问题引起的。

升级后的体验

经过几天测试,已知 Bug 都已在上面列出,暂时未发现能导致降级的重大 Bug。如果有变化,会再次更新本文。