查看原文
其他

CreatorPrimer|预制件嵌套

张晓衡 Creator星球游戏开发社区 2021-08-09



1. LoadPrefab组件


预制件嵌套可以将复杂UI界面模块化,让每一个界面模块可以独立运行,也可以组合使用,开篇之前先看个视频演示:

不知道大家是否还记得之前的一篇教程《CreatorPrimer|加载预制件》,我们在这篇教程中提供的LoadPrefab组件中增加一行特殊代码就能实现预制件的嵌套,先看下代码:

前面说的特殊代码就是:

node._objFlags |= cc.Object.Flags.DontSave;

在每一个node节点上都有一个_objFlags变量,它是一个位标记,变量参数定义在cc.Object.Flags中,请看下图:

cc.Object.Flags.DontSave中“DontSave”故名思意,该节点不保存,不保存到那儿呢?该节点不会保存到场景文件.fire或者是预制件文件.prefab中。

2. 激活编辑器中的组件脚本


不保存到场景或预制文件中有意义呢?这个功能需要组件的executeInEditMode配合,它可以实现一个很有意思的功能:

“在编辑器状态执行组件生命周期函数”

看下面代码:

  1. cc.Class({

  2.    extends: cc.Component,

  3.    editor: {

  4.        executeInEditMode: true,   //注意这里

  5.    },

  6.    onLoad () {

  7.        Editor.log(`${this.node.name}: onLoad`);

  8.    },

  9.    onEnable() {

  10.        Editor.log(`${this.node.name}: onEnable`);

  11.    },

  12.    start () {

  13.        Editor.log(`${this.node.name}: start`);

  14.    },

  15. });

组件开启executeInEditMode为true,所有组件生命周期函数都可以在编辑器状态被执行,不用等到在打开浏览器就能运行预览,请看下图:

在编辑器状态下,组件生命周期函数被执行,在此实例化出一个预制节点,同样会显示在场景编辑器中。

3. DontSave的作用


在开发过程中,每当打开场景或修改代码,都会触发编辑器中的组件生命周期函数被执行。

如果此时你按个ctrl+scmd+s保存当前界面,实例化出的预制节点也会保存当前场景中,如此反复操作,节点就会越来越多,但这是并不是我们想要的,因此下面这段代码就是关键了:

  1. node._objFlags |= cc.Object.Flags.DontSave;

使用了上面这段代码,就不会担心节点被持久化到界面配置文件中了,每次实例化出的都是最新的预制节点。

4. 注意事项


隐藏API的使用

引擎提供的API中,以下划线开头的变量和方法其实是不建议随便使用的。

node._objFlags变量在官方文档中并没有介绍,Shawn从1.x用到了2.x暂时没有什么变化,请在使用前自己评估风险,这个需要说在前面。

注意节点不会被保存

使用LoadPrefab实例化出的预制节点是临时的,不会被持久化到编辑器配置文件中。

因此修改实例化出的预制节点的属性、组件属性是不起作用的,需要回到原始预制节中去修改,但修改预制节点下绑定的脚本代码是有效的。

executeInEditMode

注意开启了组件的executeInEditMode属性后,update函数也会在编辑器中被每帧执行,一它会让你的编辑器变慢,二此时可能还会有未初始化的操作,这应该不是你想要的,需要特别处理一下:

  1. update() {

  2.     //编辑器环境退出

  3.     if (CC_EDITOR) {

  4.         return;

  5.     }

  6.     ...

  7. }

CC_EDITOR是引擎内置的全局变量,用于检查当前是否在编辑器状态,类似的变量还有不少,下面列举几个常用的:

变量说明
CC_EDITOR是否为编辑器环境
CC_PREVIEW是否为预览环境
CC_JSB是否为JSB环境
CC_DEBUG是否为调试环境
CC_WECHATGAME是否为微信小游戏环境
CCWECHATGAMESUB是否为微信小游戏子域环境

以上变量可以用于帮助大家判断代码当前执行环境,为不同环境、平台上做条件执行。

注意代码控制时机

如果需要用代码控制实例化出的预制节点,要特别注意控制时机,等待节点被创建成功后才能被正常访问。

5. 小结

本篇通过在编辑器中执行代码,动态实例化出临时预制节点,可实现多层的预制嵌套。

预制件的嵌套并不是目的,目的是利用预制件的嵌套组合,可以将一个复杂的UI界面拆分成多个子模块,从而实现多人分工协作,最后通过LoadPrefab组件将各个小模块(预制件)整合起来。


如果觉得公众号的文章对您或您身边的朋友有帮助,感谢分享给他们,愿我们一起成长!


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存