介绍

Unity 打开任何项目都会崩溃,非常奇怪。

环境

  • Unity 5.3.8f1

阶段一

打开项目时 Unity 会弹出提示框,提示缺失文件:

1
2
3
Copying file failed
Copying C:/Program Files/Unity/Editor/Data/Resources/Packages/package.json to C:/Users/builder/AppData/Roaming/Unity/Packages/package.json: 系统找不到指定的文件。
Try Again | Force Quit | Cancel

经过检查发现是在安装新版本 Unity 时错误选择旧版本安装目录,安装程序首先会卸载旧版本,发现错误后中止安装。最终的结果是 Editor/Data 目录下除了 Mono 目录外的内容全被删除,因此才会弹出上面的提示。

处理方法也很简单,重新安装旧版本 Unity 即可。

阶段二

再次使用 Unity 打开项目时,Unity 直接崩溃了,弹出了 Crash Reporter 程序。

刚开始的时候没什么头绪,尝试了一些方案均无效:尝试使用 Unity 打开其他项目,依然崩溃。

后来仔细查看 UnityEditor.Log 发现是在导入 UnityExtensions 时崩溃:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Initializing Unity extensions:
Crash!!!

// 中间内容省略

========== OUTPUTING STACK TRACE ==================

0x00000001406A8874 (Unity) AssetImporter::GetAssetPathName
0x00000001407DB9A4 (Unity) UnityExtensions::Initialize
0x0000000140BA414E (Unity) Application::InitializeProject
0x0000000140DDA6AF (Unity) WinMain
0x00000001414F9D64 (Unity) read
0x0000000076F0652D (kernel32) BaseThreadInitThunk

========== END OF STACKTRACE ===========

猜测

由此联想到另外一个 Unity Bug,必须将 Editor/Data/UnityExtensions 目录剪切到 Unity 安装目录外,打开项目,再剪切回 Unity 安装目录中,打开项目来解决问题:

1
Asset 'C:/Program Files (x86)/Unity/Editor/Data/UnityExtensions/Unity/GUISystem/4.6.0/UnityEngine.UI.dll' is in timestamps but is not known in assetdatabase

I may have found a workaround. The idea is to totally remove the UI System from Unity then put it back. Unity should reload its modules.
I wrote a full walktrough but overall it is very simple. It is better than a full reimport.
1. Remove the UI System
1. Close Unity
2. Access on Unity’s installation folder on Explorer or Finder on mac (On mac rightclick on the App and click on ShowPackageContent).
3. Locate the folder named “UnityExtensions/Unity”. (On Mac: “Content/UnityExtensions/Unity”.
4. In this folder you will notice a folder named “GUISystem”
5. Move this folder from the installation folder (you may need administrator rights). Yes, right. Do not just rename it or move it out the “Unity” folder, Unity will find it… I assure you…
2. Have Unity notice the change
1. Open Unity again in the project you had the issue
2. You may have an error “GameObject (named ‘Canvas’) references runtime script in scene file. Fixing!”
3. Close Unity, DO NO SAVE ANY SCENE
3. Restore the UI System
1. Make sure Unity is closed
2. Restore the “GUISystem” to its previous location
3. Open Unity again
4. Unity will compile script
5. You will see the warning “Timestamps (19) and assets (21) maps out of sync.” and the errors “Asset ” is in assets but has no assettimestamp…” just ignore them
6. Everything should be ok again

此问题发生时会导致整个项目无法编译,因而项目内存在的重新导入 UnityEngine.UI.dll 脚本并未编译导致无法执行;另外,实测即使将重新导入脚本放在 DLL 中规避编译失败问题,重新导入依然无法解决问题。

而且此问题发生极率较低,项目打包几十次能有一次是这个 Bug 导致的失败。

修复

尝试使用上述解决方案,问题解决。

联想

使用 rg --text GUISystem 可以快速搜索 Library/meta 目录下 UI 模块相关的缓存,如果将找到的内容删除是否可以不用使用剪切 UnityExtensions 目录方法?

结论

Unity 在加载扩展这块儿一直都有问题,不知道什么原因导致模块缓存失效,只能把它当黑盒,不断试验。