大部分工程现在还是在4.x上做的,那么现在需要做的就是将工程从Unity4.x中移植到unity5。这对我20人的team来说是一个需要谨慎思考、规划的巨大挑战。各位的工程可能不如我们的大,但仍希望你们能从我们的经验中有所收获。
首先从版本控制系统中复制出一份工程分支。这个分支作为工程的过渡版本—主工程坏掉几天不能用了,是因为team一直在修正移植到Unity5时的插件,或我们自己编写的代码引起的问题。(稍后说明)
复制这个独立的分支使得美工和策划能够继续使用Unity 4.x的版本进行工作而不至于停止工作,直到项目在Unity 5能够正常运行。在几周之前,我们把一个减掉很多功能的版本移植到Unity 5。它被美术用来开发和测验Unity 5根据物理上色功能设计的烘托通道。去掉了一切第三方的插件——任何感觉可能会阻止移植的东西。当Unity 5的项目分支测验没问题后,就可以让所有team迁移到新分支上,并将旧分支备份。
假如你们也正在Revision control(版本控制),推荐你们一定要复制一个工程分支(其实不管在任何时候都强烈推荐用Revision control)。无论怎样,保证你升级到Unity 5之前备份一下原本能run的工程。我们的UI设计师及源码操控专家, Charlie Helman,担任我们所有team的移植工作,他与我们共享了移植进程的笔记和截屏。这是从旧有的Unity 4.x工程拷贝的新分支。
《Republique》的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中,会发现脚本中一些名字和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 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
Unity5中,着色器编译器从Cg2.2切换成HLSL,你会发现需求愈加严厉了。在HLSL中,未彻底初始化的输出变量会致使一个编译过错。许多情况下我们都没有初始化色彩变量中的alpha值,或position变量中的w。要处理这个疑问,你就需要把变量初始化为0,可以用UNITY_INITIALIZE_OUTPUT宏。有时,仍会发现有彻底没有用过的数据从顶点函数传递到片元函数,即便已经从v2f构造中将它们去掉了。
代码中有少量几处要自己手动修正的之一即是经过组件名而不是类型来获取组件,Unity 不再使用该方法。在脚本自动更新器的过程中,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的各种测试版本进行,旗舰版的经验可能会有所不同。
关注“泰斗社区”了解更多相关资讯。