文章主要介绍了红点系统的特点,如何基于前缀树这一数据结构实现红点系统,提出了相关实现中存在的两个性能问题,以及如何去解决这两个问题,并在最后基于UnityEditor的TreeView开发了树视图窗口,方便使用者在开发阶段的Debug需求。
红点系统是在大部分游戏中都能看到的常见需求。
其作用在于,在玩家达成某种条件时(如新获得某个装备、道具数量达到某个需求),在相关的UI上亮起红点来提示玩家进行相关操作。
红点系统的一个鲜明特征即是它的“层层套娃”性,子界面亮起红点时其父界面也需要同时被亮起红点,一直点亮到主界面为止。
以下图为例,当某个特定的主线章节亮起红点时,
其父界面的主线章节按钮和出击页签也需要被亮起红点。
最后主界面上的出击按钮也会亮起红点来最终达到提示玩家的目的。
如此层层嵌套下来,如果不对父子红点进行统一的触发管理,而是让负责各个模块的程序员各自管理,必将导致各个模块的红点触发逻辑难以维护且性能堪忧的结果。
而针对红点系统这种十分强调父子关系的业务需求,使用“前缀树”进行管理将是非常好的选择。
那么何为前缀树呢?
前缀树本质上是一种多叉树,树节点存储了字符,具有相同前缀的字符串将具有相同的父节点,在进行字符串保存和查找时具有较好的性能优势。
通过将红点抽象为路径,只需要稍加修改,让节点中存储对应的路径字符串和节点值,便可以方便地实现红点系统。
以之前的图为例,笔者将每一层UI都依其父子关系设置为树中节点,最终只需要点亮路径为MainAttack/Attack/Chapter/18的节点,便可以同时亮起其所有父节点对应的UI的红点。
而当叶子节点的红点被隐藏时,其所有父节点也会自动检测所有子节点状态来决定是否隐藏自身的红点。
使用前缀树来实现红点系统自然并非笔者的首创,但目前为止网上能找到的相关资料中往往存在两个性能痛点:
1. 在处理路径时直接使用split方法进行字符串暴力切割,导致造成额外的内存分配。
2. 在子节点状态改变后需要也改变父节点状态时不进行限制,多个子节点同时改变将导致额外的无用刷新。
笔者在后续章节对红点系统的具体实现中,便试图解决这两个痛点,并开发一个编辑器下的红点树可视化窗口,辅助使用者对红点系统进行Debug。
课程最后会提供包含完整代码与测试用例的Demo工程方便读者学习。
更多精彩课程可下载【在理】APP查看。