# 前言

之前不是有写过 『关于汉室复兴升级 Unity2021 的问题记录』 这文章么,当时是为了将项目越南版本从 Unity2017 升级为 Unity2021。

主要考虑有三点:

  • 越南版本拖了一年多不止,新版可以拉开与其它版本差异,除此之外增加了一些越南特有优化,没准有助于提审
  • 越南还未上线,先行升级可以先看相关兼容性
  • Hybridclr 若可以使用,只要提审成功一次,就可以像纯 xlua 项目一样更新,有助于运营

越南还未上线,升级 Unity2021 之后测试也测了两个月了,包括真机我们这边和对面运营都跑过不少次,该有的问题页改得差不多了,目前唯一的问题就是还没有大规模地测试兼容性。

不过对于兼容性这一点,我也反复跟我们这边运营对过,后期会上 TestBird (真的能过审的话)。

不过本周周会的时候,前几次主程例会都提到过升级这个事,这一次上级反对意见比较大,大概就是得不求有功,但求无过。于是只能再作降级操作,后续研究计划也暂且放弃了。

虽然从低版本升级上去资源没有太大问题,但是反而降级操作,会造成大量资源问题,这里特记录一下。

目前发现主要有几个点:

  • 分散后的 DLL 重替换,Unity2018 安装目录下也有分散 DLL,直接替换即可
  • 场景 Unity 组件丢失,例如挂载的 UGUI 相关 StandaloneInputModle、EventSystem
  • 图集引用错乱,降级后,原有 Prefab 引用的图集中图片全乱了
  • 所有在 Unity2021 修改过的 Prefab 都无法使用,Unity 组件,主要是 UGUI 出现 Missing

后续再一一记录处理方式。

# 场景 Unity 组件丢失

这个救不了,看修改记录引用 GUID 都有变化,而且降级之后 Unity 完全不会处理这一块,已被自动升级修改的也不会再自动改回去,Missing 了也不见怪,只能还原到升级之前。

# 图集引用错乱

如上图所示,真的很恐怖,查看相关组件,部分为 Missing,部分为错误的精灵引用。

经对比升级与现在降级后的修改记录,可以明显发现问题:ID 对应的精灵名字已经发生了变化

这个同样救不了了,需要还原。

此时必须先关闭 Unity,然后 Revert 本地所有修改 (因为使用 Unity2018 打开已经导致自动错误修改了大量 meta 了),然后再针对之前升级提交记录进行还原。

在 SVN 上找到上次的提交记录,选择 『Revert changes from this version』,表示还原所有自此次提交的修改:

还原时会有大量冲突,由于这次提交还原的主要是 meta 文件,因此只需要选择 Accept incomming 即可,meta 文件会被重新修改。

当然实际上没这么简单就是了,在资源目录总提交上,有些冲突 (例如 DLL) 会导致还原直接半途终止,因此最保险的方式还是从子目录开始,挨个检查是否涉及到需要还原的资源再进行还原。

图集还原之后,再将所有图集都重新打一遍就可以了。

还好之前帮策划写过一个一键重打图集的工具!

# 高版本修改后的 Prefab 无法使用

关于这个,拿一个 Prefab Missing 组件举例,此处为一个 Image 组件:

修改前的 Unity2017 版本:

从数据对比上来看,其中 Missing 的组件 ID 为 114414057906683420

然后搜索并对比修改前后两个组件的差异:

可以注意到,此处虽然高版本多了点东西、少了点啥,其实这些影响都不大,但是最关键的是 m_Scripts 字段 fileID、guid 全变了!

小心翼翼地手动将 fileID、guid 改回去,刷新一下:

已经 Missing 的组件变成正常了!

说明导致 Missing 的影响要素确实是这个问题。

注:官方 meta 文件描述

# 解决方法

经过上述尝试,可以发现有三种可供选择的方法:

  1. 碰到一个修一个,手动修改 fileID、guid

    这个简直就是灾难,并且会花费大量时间,或许可以给实习生练手?但是没有必要

  2. 直接还原这两个月的 Prefab 修改

    之前针对外服写过备份修改工具,可以一键重导入之前的修改。但是这涉及到部分工具无法处理,必须手动修改的 Prefab,可能出现遗漏

  3. 写个工具,直接遍历所有 Prefab,并将指定 fileID、guid 作对应替换

    手动改肯定不可能,不过就算写工具,也得一个个找出脚本新旧对应的 fileID、guid ,并改回去,但相比前两种方法,已经算是可以接受的程度了。

所以经过考虑,采用了第三种方法,首先对两个版本的组件 fileID、guid 进行对比:

  • # Unity2018.4.36f1:

Image:m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
RawImage:m_Script: {fileID: -98529514, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Scroll View:m_Script: {fileID: 1367256648, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Scrollbar:m_Script: {fileID: -2061169968, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Slider:m_Script: {fileID: -113659843, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Toggle:m_Script: {fileID: 2109663825, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Text:m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Button:m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Dropdown:m_Script: {fileID: 853051423, guid: f70555f144d8491a825f0804e09c671c, type: 3}
InputField:m_Script: {fileID: 575553740, guid: f70555f144d8491a825f0804e09c671c, type: 3}
ContentSizeFilter:m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Mask:m_Script: {fileID: -1200242548, guid: f70555f144d8491a825f0804e09c671c, type: 3}
GridLayoutGroup:m_Script: {fileID: -2095666955, guid: f70555f144d8491a825f0804e09c671c, type: 3}
HorizontalLayouGroup:m_Script: {fileID: -405508275, guid: f70555f144d8491a825f0804e09c671c, type: 3}
ToggleGroup:m_Script: {fileID: -1184210157, guid: f70555f144d8491a825f0804e09c671c, type: 3}
CanvasScaler:m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
GraphicRaycaster:m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
Outline:m_Script: {fileID: -900027084, guid: f70555f144d8491a825f0804e09c671c, type: 3}
EventTrigger:m_Script: {fileID: -1862395651, guid: f70555f144d8491a825f0804e09c671c, type: 3}
LayoutElement:m_Script: {fileID: 1679637790, guid: f70555f144d8491a825f0804e09c671c, type: 3}
VerticalLayoutGroup:m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
AspectRatioFitter:m_Script: {fileID: -1254083943, guid: f70555f144d8491a825f0804e09c671c, type: 3}
  • # Unity2021.3.6f1:

Image:m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
RawImage:m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
Scroll View:m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3}
Scrollbar:m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3}
Slider:m_Script: {fileID: 11500000, guid: 67db9e8f0e2ae9c40bc1e2b64352a6b4, type: 3}
Toggle:m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3}
Text (Legacy):m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
Button (Legacy):m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
Dropdown (Legacy):m_Script: {fileID: 11500000, guid: 0d0b652f32a2cc243917e4028fa0f046, type: 3}
InputField (Legacy):m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
ContentSizeFilter:m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
Mask:m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
GridLayoutGroup:m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3}
HorizontalLayouGroup:m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3}
ToggleGroup:m_Script: {fileID: 11500000, guid: 2fafe2cfe61f6974895a912c3755e8f1, type: 3}
CanvasScaler:m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
GraphicRaycaster:m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
Outline:m_Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
EventTrigger:m_Script: {fileID: 11500000, guid: d0b148fe25e99eb48b9724523833bab1, type: 3}
LayoutElement:m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
VerticalLayoutGroup:m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
AspectRatioFitter:m_Script: {fileID: 11500000, guid: 86710e43de46f6f4bac7c8e50813a599, type: 3}


(打印是后续调试进行过好几次的查漏补缺截图,因此数量才这么少)

另外需要注意千万不好混了,有一次就是复制重复了,导致组件上的脚本是有了,但却从 VerticalLayoutGroup 变成了 LayoutElement!

主要代码如下:

string resDir = Path.Combine(Application.dataPath, "Resources");
string[] prefabLists = Directory.GetFiles(resDir, "*.prefab", SearchOption.AllDirectories);
int num = prefabLists.Length;
string[] linesTemp;
bool doSave;
for (int i = 0; i < num; i++)
{
    EditorUtility.DisplayProgressBar("降级修复中……", $"请等待,执行进度:{i + 1}/{num}", (float)i / num);
    doSave = false;
    linesTemp = File.ReadAllLines(prefabLists[i]);
    for (int lineIndex = 0; lineIndex < linesTemp.Length; lineIndex++)
    {
        // 遍历 2021 最新的 id,检测每一行是否有对应数据
        for (int newIndex = 0; newIndex < Unity2021.Length; newIndex++)
        {
            if (linesTemp[lineIndex].Contains(Unity2021[newIndex]))
            {
                //2021 替换为 2018
                linesTemp[lineIndex] = linesTemp[lineIndex].Replace(Unity2021[newIndex], Unity2018[newIndex]);
                doSave = true;
            }
        }
    }
    if (doSave)
    {
        Debug.Log($"修复对象:{prefabLists[i]}");
        File.WriteAllLines(prefabLists[i], linesTemp);
    }
}
EditorUtility.ClearProgressBar();
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();

然后自己跑了下,出了真机包也试了一圈没什么问题,不过后续还是需要测试重新跑一次全量。