开源项目
bit-condition:红点该不该显示,交给条件系统自动算
Cocos Creator 条件显示系统,用装饰器注册条件类型,自动计算红点、解锁提示的显示状态,定时批量更新省去手动刷新逐个节点。
bit-condition:红点该不该显示,交给条件系统自动算
它解决什么问题
红点系统看着简单,做起来烦。一个红点的显示条件可能是”有未读邮件”,另一个可能是”背包里有新装备 或者 有可升级的装备”,条件组合一多,代码里到处散落着 if (hasNewMail() || hasUpgradableItem()) 这种判断,而且数据一变还要记得手动去刷新对应的红点节点,漏刷新是最常见的红点 bug 来源。
bit-condition 把”判断条件”和”通知 UI 更新”这两件事拆开管理:你只管写条件类怎么判断,节点怎么显示交给框架,数据变化时通知框架重新算一遍,该显示的自动显示,该隐藏的自动隐藏。
安装
bit-core 和 @gongxh/fairygui-cc 是 peer 依赖:
npm install @gongxh/bit-condition @gongxh/bit-core @gongxh/fairygui-cc
核心用法
1. 加条件模块
场景根节点或者一个常驻的管理节点上挂 ConditionModule 组件,它负责定时批量重算所有待更新的条件(默认 0.3 秒一次),不是每次数据变化就立刻算,攒一批一起处理,性能更友好:
// 挂在场景管理节点上,updateDeltaTime 可以在 Inspector 里调
2. 定义条件类型和条件类
先用枚举定义好有哪些条件类型,再继承 ConditionBase 实现判断逻辑:
import { _conditionDecorator, ConditionBase } from '@gongxh/bit-condition';
enum ConditionType {
NewMail,
UpgradableItem,
}
@_conditionDecorator.conditionClass(ConditionType.NewMail)
export class NewMailCondition extends ConditionBase {
protected onInit(): void {
// 这里可以注册数据变化的监听
}
protected evaluate(): boolean {
return MailSystem.hasUnreadMail();
}
}
evaluate() 只管返回布尔值,什么时候调用、调用完怎么通知节点,都不用你操心。
3. 数据变化时喊一声
邮件系统收到新邮件时,找到条件实例调用 tryUpdate(),告诉框架”我这个条件可能变了,下个周期重新算一下”:
newMailCondition.tryUpdate();
4. 挂红点节点
ConditionAnyNode 和 ConditionAllNode 是内置的两种组合模式,分别对应”任一条件满足就显示”和”所有条件都满足才显示”:
import { ConditionAnyNode } from '@gongxh/bit-condition';
// 邮件红点:有未读邮件 或者 有可升级装备,任一满足就亮红点
const redDot = new ConditionAnyNode(redDotNode, ConditionType.NewMail, ConditionType.UpgradableItem);
节点销毁前记得调用 destroy() 解绑;如果是挂在 FairyGUI 对象上的 ConditionFGUINode,GObject.removeFromParent() 的时候会自动帮你解绑,不用手动处理。
条件组合模式
ConditionMode 只有两种:
Any(0)—— 任意一个条件满足就算满足,红点、提示类场景最常用All(1)—— 所有条件都要满足,比如某个功能同时要求”等级达到10级”和”完成新手引导”才解锁
如果 Any/All 都不够表达你的逻辑(比如条件之间还要加权重、或者要 A 且非 B),直接继承 ConditionBase 自己写一个组合条件类,evaluate() 里调用其他条件实例的结果自己拼逻辑就行,框架没有限制你必须用内置的两种模式。
避坑提醒
evaluate()不会自动被高频调用,只有调用过tryUpdate()之后,才会在下一个更新周期被重新计算。如果条件判断依赖的数据变了但忘了调tryUpdate(),红点状态就会一直停留在旧值,这是最容易踩的坑。ConditionModule只能挂一份在场景里生效,别指望多挂几个能加速刷新——批量定时更新本身就是为了避免频繁计算,加实例只会重复算,不会更快。- 条件类型枚举建议一次性统一定义好,散落在各个业务模块里定义容易和其他系统的枚举撞值。
项目信息
- GitHub: https://github.com/gongxh0901/bit-framework/tree/main/bit-condition
- npm: @gongxh/bit-condition
- 许可证: MIT License
跟 bit-ui 的窗口系统配合起来用效果最好,红点挂在窗口内的 FairyGUI 节点上,窗口关闭时节点自动跟着销毁解绑。