Unity脚本启动顺序调整方法

我们都知道,Unity中,某个游戏物体上的脚本初始化顺序是先Awake,再Start,那么假如现在有这样一种情况:

  有两个模块,它们都通过Awake或者Start来初始化,但其中一个会持有对另一个模块的引用,更具体一点,比如脚本1是单例的,脚本2中持有对脚本1的引用,而且脚本2会在初始化的时候将引用赋值为脚本1的单例。

  此时万一脚本2的Awake和Start先执行,那初始化时由于脚本1还没有初始化,肯定会出错,怎么办呢?

  一种解决方案是在Edit->Project Settings->Script Execution Order下设置脚本先后次序,可以参考:

  https://jingyan.baidu.com/article/0a52e3f4d47152bf62ed7297.html

  但这种方案当互相依赖的脚本比较多时,会比较繁琐。

 

  另一种方案是把模块初始化的内容放在一个单独的函数里,模块内部不再使用Awake和Start。这样,我们就可以在一个管理脚本中分别控制每个模块的初始化顺序,不会导致冲突。这是游戏开发的一种常用思路,虽然不涉及什么难的技术,但这种思想值得参考。

  我们先介绍一种常用的游戏开发架构思路:

  一种常见思路是创建一个空物体,将一个管理模块的脚本挂在此物体下,它负责启动游戏并初始化各个模块,根据游戏中各个部分功能的不同,不同的脚本大致可分为公共服务模块和单个业务系统模块,公共服务模块会向系统中的所有模块提供一些公共服务,比如资源加载,音频播放,网络服务等等。 

  单个业务系统模块分为很多种,比如登录系统业务模块,战斗业务模块,副本业务模块等等,各个单独业务模块负责管理本业务相关的脚本,比如某些UI窗口下是某个业务模块的界面,每个UI窗口下都会有对应的窗口管理脚本,这些窗口管理脚本就是由对应归属的单个业务系统模块脚本来操控的,反映到代码上,就是这些业务模块脚本会持有这些窗口管理脚本的引用。

  而公共服务模块和单个业务系统模块,是统一由管理模块初始化的,因此管理模块中需要持有对这两个模块的引用,我们可以不使用拖拽的方式来实现,可以将这两个模块与管理模块一起,放在空物体下,管理模块初始化时用代码获取这两个模块的引用,并控制这两个模块的初始化顺序。 

  下面给出实现的代码和结果:

GameRoot是管理模块,PublicSvc是公共服务模块,SingleSys是单个业务系统模块,由于业务系统模块中需要用到公共服务模块提供的服务,因此需要先初始化公共服务模块,再初始化业务模块。

再看一下它们在系统中的排布:

它们都放在空物体GameRoot下,方便GameRoot脚本取到对服务模块和业务模块的引用。

输出结果如下:

 

完结。

 

posted on 2019-06-12 22:35  暴躁法师  阅读(3833)  评论(0编辑  收藏  举报