[官方教程] RÉPUBLIQUE 开发日记#2 :从Unity 4迁移到Unity 5

发表于2015-08-25
评论0 1k浏览

我们开始使用Unity 5最重要的一步就是将工程从Unity 4中移植过来。这对我们20人的团队来说是一个需要谨慎规划的巨大挑战。你的工程可能不如我们的大,但仍希望你能从我们的经验中有所收获。


首先我们从版本控制系统中复制出一份工程分支。这个分支作为工程的过渡版本——主工程坏掉几天不能用了,因为我们一直在修复移植到Unity 5时插件或我們自己的代码引起的编译错误。(稍后详述)


创建这个独立的分支使得我们的美术和策划可以继续用Unity 4的工程版本工作而不至于停工,直到项目在Unity 5可以正常运行。在几周之前,我们还创建了一个工程简化版本移植到Unity 5。它被美术用来开发和测试我们自己为Unity 5基于物理着色功能设计的渲染通道。简化的版本去掉了所有第三方的插件——任何我们认为可能会阻碍移植进程的东西。當Unity 5的项目分支测试沒问题后,我们就让整个团队迁移到新分支上,并将旧分支归档。


如果你正在使用版本控制系统,我们建议你一定要拉一个工程分支(其实我们在任何时候都强烈建议使用版本控制)。无论怎样,确保你升级到Unity 5之前备份你的工程。


我们的UI设计师及源码控制专家, Charlie Helman,负责我们整个团队范围的移植工作,他与我们分享了移植过程的笔记和截屏。


这是我们从旧有的Unity 4工程创建的新分支。 


《République》的Unity工程相比于其它移动游戏来说是很庞大的,有45.7GB之大。将工程导入到一些机器上会花24小时之久。但用Cache Server 可以将这个时间缩短到30分钟。



打开你的工程之前,确保在Unity 5的Preferences 中启用了Cache Server。也顺便设置比如外部代码和图片编辑器(Visual Studio 或 Photoshop)。要设置这些,需要启动Unity 5创建一个新的工程。




一旦新工程打开,就前往首选项Preferences(Mac: Unity > Preferences; Windows:Edit > Preferences)




在Preferences 的Cache Server 选项卡中,确保“Use Cache Server”被勾选,并将IP设置为缓存服务器地址(这里简单地填了“Server”)。通过“Check Connection”来验证它是否工作,然后我关闭了这个工程。



现在,我们已经准备好打开真正的工程了。几分钟后,我们看到了导入的进度条。每隔一段时间,我们会看到这样的提示。




由于Unity 5的API 大量改变。改变之一就是所有的“快捷”引用(比如.rigidbody或.transform,在以前它内部其实是调用一个 .GetComponent<T>() 方法),现在都必须显示地调用 GetComponent。所以myCharacter.rigidbody现在必须改写成 myCharacter.GetComponent<Rigidbody>()。Unity 去掉了所有的“快捷”引用,并且自动帮你处理这个转换工作。


当我们选择“I Made a Backup. Go Ahead!”,Unity 就开始处理。


Unity 5的自动升级器太棒了。最让人满意的是,它可以分析你的整个代码库来作适合的更新。


说到这,让我们来看看一些Unity 5脚本的变化,以及Camouflaj 如何让它们正常运行。


Unity 5的脚本升级


在Unity 5中,我们会发现脚本中一些名字和API 发生了变化。通常是在旧的名字上加上Obsolete 属性,这样编译器会给出替代方案的建议。然而有时候不仅是名字发生了改变:你可能需要考虑多个可替代方案。比如,AnimatorStateInfo nameHash被替换成了shortHash和fullPathHash。shortHash是不以层名或状态机名为前缀的状态名,大多数情况下这就够了。如果不同的状态用了相同名字,但是在不同的状态机或层下面,那么你可以用fullPathHash。


如果你想让你的脚本与以前的Unity 版本保持向后兼容,你可以用Unity版本宏。我们更喜欢用这种方式来处理Unity 的未知版本,比如Unity 5或更高的版本。这样在下次升级时,我们就可以基本不用复核这段代码了。


下面是一段有多个Unity 版本代码共存的例子。

[C] 
<font face="微软雅黑, Microsoft YaHei"><font style="color:rgb(62, 62, 62)">#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 will 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</font></font>


着色器更新


Unity5中,着色器编译器从Cg2.2切换成HLSL,你会发现要求更加严格了。在HLSL中,未完全初始化的输出变量会导致一个编译错误。很多时候我们没有初始化颜色变量中的alpha值,或位置变量中的w。要解决这个问题,你就需要把变量初始化为0,或者用UNITY_INITIALIZE_OUTPUT宏。有时候,我们仍会发现有完全没有使用的数据从顶点函数传递到片元函数,即使我们已经从v2f结构中将它们移除了。


手工编辑而非脚本自动升级


代码中有少数几处需要手动修改的地方之一就是通过组件名而不是类型来获取组件,Unity 不再支持这种方式。在脚本自动更新器的处理中,Unity 将那些以名字来取组件的老代码:

GetComponent(“MyMonoType”)

更新为:

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

你可能会看到有些这样的转换在控制台抛出错误,因为理论上这些修改编译不过。


这种组件获取的问题主要产生于第三方插件,因为我们是尽最大努力使《République》代码库尽可能地类型安全。然而,在我们的一些老的AI 代码中,我们已经将GOAP 系统设定为这样一种方式,即Actions 和Goals 可以以动态列表的形式来指定,而列表是通过名字来引用MonoBehaviors 的 。这使得我们可以灵活地在运行时动态配置,但Unity 5取组件的新限制就让这种机制失效了。在这种特殊情况下,我们就不再需要将基础的Action 和Goal 类派生自MonoBehavior ,而是仅仅是把它们转换为标准的类就可以解决这个问题。


对其它那些需要手工修改的取类型的地方,我们通过一个新的策略来解决这个问题,就是像下面这样通过名字来取得类型。

System.Type.GetType("MyMonoType")


美术工具


最后带你瞧一下我们在基于物理着色方面的工作,我们将会在下一篇开发日志中详细讲述。


为了准备将《République》现有的材质进行基于物理着色,我们要重新考虑如何制作材质对应的纹理。在以前,我们大部分的材质只对应的少量的纹理。在基于物理着色中,我们的材质必须对应大量的材质。为了快速处理现有的材质,我们的程序员写了一个材质转换工具。这个工具为转换节省了大量时间:它把老的纹理和对应的源材质存档,移动并且重命名已有的源材质(使用Unity 的AssetDatabase的方法来取得已有的到预制、模型的链接,以及链接本身)。然后它就链接到新的基于物理的纹理映射,设定需要的一系列纹理导入设置,并且最终生成打包后的map和表示纹理映射的资源。


这使得我们的美术组每天可以转换数百个材质,这极大的改进了他们的工作流程且减少了转换过程中的出错机会。如果你正从Unity 4移植到Unity 5,且有很多的材质要转换,强烈建议创建一个这样的工具——我们发现这使我们美术的纹理转换效率提升了30%以上。听起来像是不多,但如果你在一个像我们一样的快节奏的工作环境下,任何小改变都会带来很大的帮助。


注意:大部分的工作是利用Unity 5的各种测试版本进行。最终版的经验可能会有所不同。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引