Unity4项目怎么升级到Unity5

2016年08月11日 18:06 0 点赞 0 评论 更新于 2025-11-21 13:35

目前,大部分项目仍基于Unity 4.x版本开发。将项目从Unity 4.x移植到Unity 5,对一个20人的团队而言,是一项需要谨慎思考和规划的重大挑战。即便你的项目规模较小,也希望你能从我们的经验中有所收获。

一、创建项目分支

首先,从版本控制系统中复制出一份项目分支,该分支作为过渡版本。在移植到Unity 5的过程中,团队可能会花费数天时间来修复因插件或自定义代码引发的问题(后续会详细说明)。

复制独立分支的好处是,美工和策划人员可以继续使用Unity 4.x版本开展工作,直至项目在Unity 5中正常运行。几周前,我们将一个精简了大量功能的版本移植到Unity 5,供美术人员开发和测试Unity 5基于物理上色功能设计的烘托通道。在这个过程中,我们移除了所有可能阻碍移植的第三方插件。当Unity 5的项目分支测试通过后,就可以让整个团队迁移到新分支,并备份旧分支。

如果你正在使用版本控制(Revision control),强烈建议复制一个项目分支(实际上,任何时候都推荐使用版本控制)。无论如何,在升级到Unity 5之前,务必备份原本可以正常运行的项目。我们的UI设计师兼源码操控专家Charlie Helman负责整个团队的移植工作,他分享了移植过程的笔记和截屏。

《Republique》的Unity项目规模庞大,达到了45.7GB!将该项目导入某些机器可能需要24小时,但使用Cache Server可以将导入时间缩短至30分钟。

二、启用Cache Server

在打开项目之前,需要在Unity 5的Preferences中启用Cache Server,并设置外部代码和图像编辑器(如Visual Studio或Photoshop)。具体操作如下:

  1. 使用Unity 5创建一个新的项目。
  2. 项目创建并打开后,前往首选项Preferences(Mac:Unity > Preferences;Windows:Edit > Preferences)。
  3. 在Preferences的Cache Server选项卡中,勾选“Use Cache Server”,并将IP设置为缓存服务器地址(此处简单填写“Server”)。
  4. 使用“Check Connection”验证连接是否正常,然后关闭该项目。

完成上述操作后,就可以打开真正的项目了。几分钟后,你将看到导入进度条,期间可能会看到相关提示。

三、API变更处理

由于Unity 5的API有很多改动,原来的“快捷”引用(如.rigidbody或.transform,其内部实际上调用了.GetComponent()函数)现在需要显式调用GetComponent。例如,myCharacter.rigidbody需要改写为myCharacter.GetComponent()。不过,Unity会自动处理这些转换。

当点击“I Made a Backup. Go Ahead!”后,Unity将开始处理转换。Unity 5的自动化升级工具非常强大,它可以分析整个代码库并进行最合适的更新。

四、脚本升级

在Unity 5中,脚本的一些名称和API发生了变化。通常,旧名称会添加Obsolete属性,编译器会给出替代方案的建议。但有时不仅是名称改变,你可能需要考虑多个替代方案。例如,AnimatorStateInfo的nameHash被替换为shortHash和fullPathHash。shortHash是不以前缀层名或状态机名的状态名,大多数情况下已足够使用。如果不同状态使用了相同名称,但位于不同的状态机或层中,则可以使用fullPathHash。

如果你希望脚本与旧版本的Unity保持向后兼容,可以使用Unity版本宏。我们推荐使用这种方法来处理不同版本的Unity,如Unity 5及更高版本。这样在下次更新时,就无需重新检查这段代码。

以下是一个多版本Unity代码共存的示例:

#if (UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6 || UNITY_3_7 || UNITY_3_8 || UNITY_3_9)
// Code specific to Unity 3 versions.
// 针对Unity3的代码
#elif (UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9)
// Code specific to Unity 4 versions.
// 针对Unity4的代码
#else
// Code specific to other versions of Unity.
// 针对其它Unity版本的代码
// Here we shall assume this is Unity 5 and later, and in doing so choose not to support Unity 2 or earlier.
// 这里我们假定是Unity 5或更高版本的代码,这么选择是不再支持Unity 2或更低的版本
// There may be a few defines for Unity 2 if you wish to support those versions.
// 如果你想要支持Unity 2的话,这里可以加上一些Unity 2的宏定义。
#endif

五、着色器更新

在Unity 5中,着色器编译器从Cg2.2切换到HLSL,要求更加严格。在HLSL中,未完全初始化的输出变量会导致编译错误。在很多情况下,我们没有初始化颜色变量的alpha值或position变量的w值。解决这个问题的方法是将变量初始化为0,可以使用UNITY_INITIALIZE_OUTPUT宏。有时,即使从v2f构造中移除了未使用的数据,仍然会发现有从未使用的数据从顶点函数传递到片元函数。

六、手动编辑

代码中有少量需要手动修改的地方,例如通过组件名而非类型来获取组件,Unity 5不再支持这种方式。在脚本自动更新过程中,Unity会将通过名称获取组件的旧代码:

GetComponent("MyMonoType")

更改为:

UnityEngineInternal.APIUpdaterRuntimeServices.GetComponent(go, "Assets/PathToMyMonoType/Scripts/MyMonoType.cs (207,8)", "MyMonoType")

你可能会在控制台看到这些转换出错的信息,因为理论上这些修改无法通过编译。

这种组件获取错误通常来自第三方插件,我们在《Republique》代码库中尽量保证类型安全。但在一些旧的AI代码中,GOAP系统采用了一种动态列表的方式来指定Actions和Goals,列表通过名称使用MonoBehaviors,这在运行时可以实现灵活配置。然而,Unity 5对组件获取的新限制使这种机制失效。在这种特殊情况下,我们不再将基础的Action和Goal类派生自MonoBehavior,而是将它们转换为标准类来解决问题。

对于其他需要手动修改的类型获取问题,可以通过以下新方法解决:

System.Type.GetType("MyMonoType")

七、美术工具

最后,为你介绍一下我们在基于物理上色方面的工作,详细内容将在下一篇开发日志中分享。

为了将《Republique》现有的材质进行基于物理上色处理,我们需要重新考虑材质对应的纹理制作方式。之前,大多数材质只对应少量纹理,而在基于物理上色中,材质需要对应更多纹理。为了快速处理现有材质,我们的程序员开发了一个材质转换工具。该工具节省了大量时间,它会存档旧材质和对应的源材质,移动并重命名现有的源材质(使用Unity的AssetDatabase方法获取预制、模型的链接),然后连接到新的基于物理的纹理映射,设置所需的纹理导入设置,并最终生成打包后的map和表示纹理映射的资源。

这个工具使美工组每天能够转换数百个材质,极大地改进了工作流程,降低了转换过程中的出错几率。如果你正从Unity 4.x移植到Unity 5,且有大量材质需要转换,强烈建议开发这样一个工具,它可以将美工的材质转换时间缩短30%以上。

需要注意的是,我们的大部分工作是在Unity 5的各种测试版本上进行的,旗舰版的情况可能会有所不同。

关注“泰斗社区”了解更多相关资讯。