Unity预加载设计

大部分游戏应该都需要预加载,为什么呢?
我们先谈谈预加载的好处与坏处。
你们的游戏是不是也有这样的情况:
1. 假如我有一个技能, 召唤另外一个对象,而这个对象需要载入模型。 那么在你使用技能的时候是不是会出现突然卡顿的现象?
2. 假如我们要使用一个技能,需要载入一个UI,或者一个粒子特效,假如需要的资源足够多,也会出现突然卡顿的现象?
要解决这些现象就需要我们的预加载技术出炉了。
实际预加载技术很简单的。具体到游戏中实际应该会有2种情况。
1. 假如你们的游戏是使用空场景,然后所有的游戏对象都采取动态创建的方式来生成,那么恭喜你,你们这个已经变相预加载了。
2. 或者你们的游戏与我现在的项目一样,所有的关卡元素保存在Unity的场景文件中,需要实时生成我们的预加载信息。
3. 在加载场景的读进度条的时候,把我们我们需要预加载的对象,初始化一遍。该加载的资源加载。
第一种方式暂且不提, 实际上和第二种差不多。因为你们的创建对象的入口已经统一,唯一需要处理的就是假如你有技能B,技能B出发效果A,效果A产生对象C,而对象C需要预加载处理。 这个其实和第二种情况一样。leanote还不太会用
第二种方式如果需要预加载的话,有二种做法:
在场景载入的时候,动态寻找所需要的组件,然后进行预加载。 这个不用说,肯定PASS掉,因为这样会导致场景的加载巨慢。那么很容易想到第二种做法,所有的查找放到编辑模式下。
在游戏编辑模式下,获取到我们所有游戏中所有需要进行预加载的对象,放到一个列表中,当我们的场景进行加载的时候,拿到这个对象,进行预加载。
根据第二种方式我们来分析一下我们需要的东西:
1. 我们需要能够获取到场景中所有的需要预加载的对象。
2. 我们需要一个能够实时监听场景文件修改的工具。每当策划修改场景文件的时候,我们就重新生成我们的预加载信息。
3. 一个预加载对象都需要实现的接口函数
4. 一个存储所有需要预加载对象列表的管理器
这是我们预加载的第一版。
既然有第一版,那肯定有第二版。 因为在游戏中,因为我们不分青红皂白直接把对象加入到预加载列表,而并没有问下人家自身的意愿,因为不是所有技能,BUFF都带有召唤功能的。所以比较能想到的对于第一版的补充。
预加载接口函数,新增是否预加载函数,用于判断是否需要预加载,按需加入。
需要注意的一点是,我们预加载的对象也不能浪费啊,我们最好配合我们自身游戏的对象池组件,或者其他东西,把我们的对象给放入到这个管理器里面,当需要实例化该对象的时候直接拿出来使用。

用到的编辑器工具有:
1. 编辑模式自启动脚本: 使用 InitializeOnLoadAttribute, 或者 InitializeOnLoadMethodAttribute 方式。 会在游戏启动之后 Awake –> OnEnable –> RuntimeMethodLoad –> Start。 但是这个脚本不建议用在正式流程, 因为会控制不了流程。
2. Unity资源修改监听器: AssetModificationProcessor, AssetPostprocessor

我们的对策划需求应该有:
1. 要求策划把关卡场景统一放到某个目录,如: Scenee/Level, 然后我们在 AssetModificationProcessor 脚本里面监听资源修改, 如果是路径是以Scenee/Level 开头 且以 .unity结尾那么,可以确定是我们需要进行处理预加载的文件。
2. 根据你们的项目自定义预加载的流程, 假如你们是自己写的地编, 那么只需要分析你们自己生成的 配置信息。 如果你们是直接在Unity里面进行编辑,那么就需要 获取到全局中需要预加载的对象,然后进行是否需要预加载的检测。对于这种,如果你们的配置文件是放到Unity里面的话,应该也能做到自动化与静默化。
3. 预加载实际是一个深度优先的查询, 对于第一种和第二种实际都是一样。 我们需要分析我们需要预加载的对象,是否预加载, 同时分析他能产生的其他的对象的信息, 然后在分析这些被产生的对象是否需要预加载, 如果有任意一个需要预加载处理, 那么视为这个对象需要预加载处理。 并加入预加载列表。

————————————————-接上面: 设计修改————————————-

在自己的实际项目中,突然发现上面的处理方式不太合理。
我们游戏中突然有了这样的需求, 在我们进入关卡的时候, 我们并不知道自己会面对哪些Monster, 这些Monster都是从服务器发下来的, 这种情况下我们上面的预加载处理实际上不够的。 因为我们需要实时分析每个怪物是否需要预加载,如果随机的数量不多,当然没问题。 如果数量过多, 就会导致进战斗的时间过长,大部分时间都用于去分析是否预加载去了。 因为分析的过程是 递归式。
我们应该想办法把这个分析挪到编译期间, 一个比较容易想到的是, 在策划对表进行修改后,我们直接载入表,然后对表进行分析,如果需要某项需要加载,我们就直接在表中体现出来,下次如果再次需要对这个东西进行预加载分析的时候, 我们就可以直接从表中读取,而不用再去有再去分析是否需要预加载的过程了。

举个例子: 假如现在策划填入一个 在Excel中填入一个新的技能, 然后通过某种工具到导出你们项目能用的配置文件,我们现在就需要对导出的文件进行分析,我们遇到的问题有:
1. 对某个文件夹进行监听的工具, 如果一旦某个文件夹改变。 我们可以知道, 并且开始我们的预加载分析处理。
2. 对文件的操作, 我们需要动态在表中增加一行, 或者 直接体现到Xml中。 在分析到需要预加载的时候,我们填入表 中。
3. 或者我们直接监听XML目录,如果Excel目录一个修改,即分析Excel表中的是否需要预加载,然后动态的修改Excel再进行导出。
4. 如果你们嫌以上的东西太过于繁琐, 你们也可以让你们策划去填这一行, 让策划决定某个东西是否需要预加载,但其实人工很容易出问题, 而且策划也不太明白有一些什么东西需要预加载的。

所以实际需要我们在实际编码中,要把每种战斗的数据 即Data 与逻辑分开。

具体的实现,大家自己把握。

你可能感兴趣的:(Unity游戏开发)