在使用Unity3d开发游戏的时,我们总会涉及Unity内置的生命周期函数。弄清这些函数的调用顺序和特性十分重要,因为这影响到逻辑的执行顺序,例如:初始化要在使用之前,注册回调要在响应之前等等。
通常说来,在大型商业项目中,我们需要自制一套游戏循环,来满足多变的游戏玩法。哪些现有的生命周期函数可以使用?哪些需要被替换掉?这些取舍贯穿了整个游戏开发过程。
生命周期
Unity3d的函数调用有固定的顺序,对于脚本生命周期(Script Lifecycle),官方文档中给出一张时序图如下:
深入理解这张图,可以应对大多数的时序问题。在Initialization、Disable/enable、Decommissioning区域的函数只会调用有限次数,而其他部分都是受控重复或循环调用。其中:
- Awake 函数在构造脚本对象时调用
- OnEnable/OnDisable 在每次激活对象时调用
- Start 在第一次触发脚本时调用
- OnDestory 在销毁对象时调用
主循环分为物理模拟、游戏逻辑、渲染绘制三个子循环。从Unity实现的方式上看,这三个循环放是在同一个线程中。不过自从Unity3d的5.x版本后,引擎加入了多线程渲染的选项,即将第三步循环放在另一个线程中进行。这样做就可以在固定帧率下降低逻辑循环的压力,降低掉帧现象的发生。至于物理模拟循环,我个人觉得没必要拆出到另一个线程。毕竟线程间通信也需要性能,而物理模拟循环运行到速度一般要快于游戏逻辑,如果出现数据访问的冲突还需要加锁,就得不偿失了。本文内容出自《游戏架构:核心技术与面试精粹》,感兴趣的读者可以在主流电商网站上查到。
重写模版脚本
在实际项目中,我会通过更改代码的模板文件,来优化生命周期函数的使用方式。在Unity的安装目录中,有创建代码的模版文件。通过自定义这个文件,可以更改创建默认文件的内容。文件目录为:
- Windows: Unity安装目录/Editor/Data/Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt
- Mac: Unity安装目录/Contents/Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt
根据自己团队开发人员的编程习惯,我自定义了一个代码模版。大家可以根据自己的需要做相应的更改。