onEnable() 与 onDisable() 的一个有意思的现象

一般来说一个挂载在节点上的组件的onEnable()和onDisable()在node生命周期内都是成对出现的嘛? 比方说节点当前active为true,先设这个节点active=false,再设为true,那么会先调用onDisable()再调用onEnable()。不会出现连续两个onEnable()或者onDisable()。

因为这个特点,我一般喜欢在这两个函数里注册/注销事件监听,但是最近我发现项目中有个组件重复添加了事件监听,然后我发现这俩居然有情况下不是成对出现的!!!

当你在onEnable()函数里调用了this.node.active = false,对不起!this.node.active = false不会触发onDisable()!!!

这样嵌套容易出问题吧
可以使用setTimeout(() => {this.node.active = false;}, 0);

scheduleOnece(()=>{active=false})
很多情况下都需要在下一帧再执行操作才可能.

我觉得可以套娃,

onEnable => this.node.active = false; 
onDisable => this.node.active = true; 

:joy:

+1 我觉得你的逻辑没毛病,正常情况就应该是这样滴

不过有个情况是: 如果初始化node.active = true时,也应该进入一次onEnabe()

这是正常的,这部分是我实现的,在我的理解中,这是一种取消操作。
onEnable,这是普通时态,说明函数调用的时候正在激活的过程中。激活到一半,你把人家给禁用了,这不是说明了你不想取消激活吗?所以这种情况下并没有成功激活,自然也不会再调用 onDisable。

可以随意嵌套。Creator 还是把这一块做得比较完善的,只要没有报错信息,就说明引擎能正确处理。

额, 这个设计不太好吧,不应该有取消这种操作的吧, 从开发者角度来说,设置false和true完全是2种状态的,应该立即改变状态,难道引擎是为了考虑频繁改状态影响性能,在下一帧才改变状态?

想象一下一个节点树,里面有多个节点的 onEnable 相互关联。
结果有一个节点激活到一半把整棵树禁用了。
就会导致前面的节点激活了、禁用了,后面的节点没有同步刷新状态。
对引擎来说也是的,引擎的同步方法,调用到一半,结果发现节点状态被 onEnable 改变了,这就是激活到一半取消了。

不好意思我没怎么理解, 节点相互关联,是啥意思呢,父节点active状态改变子节点的active状态也需要改变么? 如果需要改变的话确实很需要递归所有子节点,但是这个递归也是个同步操作呀。为啥会有调用到一半呢,我悟性有点低没理解…

可能调用的时候做中断处理了

就是多个组件之间的 onEnable 或者 onDisable 存在调用顺序上的依赖。必须一起调用,或者依次调用之类的。

没有问题,这种树状结构就是会这样。你这样处理有你的考虑,我这里只是纪录一下,以免下次踩坑。