当前位置: 首页 > news >正文

Unity 红点系统

首先明确一个,即红点系统的数据结构是一颗树,并且红点的数据结构的初始化需要放在游戏的初始化中,之后再是对应的红点UI侧的注册,对应的红点UI在销毁时需要注销对红点UI的显示回调注册,但是不销毁数据侧的红点注册

- 具体分布

1. ReddotNode 红点结点类,数据侧

在这里插入图片描述
红点结点类负责承载红点的数据关系,其中在_reddotCnt的数据改变时,判断和现有值是否相等,如果不相等,赋值的同时,调用UI更新的回调

2. 红点UI类,表现侧

在这里插入图片描述
这里设计的是一个红点表现的抽象基类,因为红点的表现可能有多种多样,比如最直接的一个红色的点,或者是显示数字的红点,或者其他,那么对应的红点类型只需要继承这个类,然后实现各自的ReddotCallback就行了
在SubReddot方法中isCallImmediate参数用来判断是否需要在UI注册时立马调用一次回调,一般来说,在UI注册时,默认需要调用一次来判断是否需要显示红点,所以这里默认是true,这样的话,当重新回到某个UI面板时,重走一遍初始化注册时,会自动调一次红点显示判断

3. 具体红点类型

在这里插入图片描述
这里举了个例子,这是一个直接显示,隐藏的红点类型,所以只需要重写ReddotCallback,在内部判断红点计数,控制UI的显示隐藏就好

4. 红点树管理类

在这里插入图片描述
既然是管理类所以这个类被设计为一个单例类
在这个类的设计中,在查找方法中不设置创建的部分,因为之前参考某些红点框架,在查找不到时会去主动创建,但这里没有这么做,但在设置红点时,存在查找的部分
对于改变红点计数方法,其传入的数字是一个增量,是可正可负的,因为有的时候是减红点数,有的时候是加红点数,这个时候就可以传入-1或+1,如果当前结点的红点数加上增量 < 0,说明超出了范围,那么手动将增量设置为负的当前结点红点数,这样保证了即使超出范围,最后得到的值是0
并且在这里一开始是用的SetReddots方法,即设置,因为当想要改变一个红点的计数时,说明已经要用到这个结点,那么没有的话一定要创建出来,如果有的话,刚好直接查找就好
之后遍历这条路径上的每一个结点,将增量加上

- 具体使用

1. 邮件面板主页

public class Mail : MonoBehaviour{public Button mailButton;public GameObject mailPanel;public GameObject mailContent;public ReddotView reddotView;public GameObject mailTab;public GameObject Tab;public List<Button> tabs = new List<Button>();void Awake(){mailButton = GetComponent<Button>();mailButton.onClick.AddListener(OnMailButtonClick);//ReddotTree.Instance.SetReddots("Mail");InitMailData();reddotView.SubReddot("Mail");// var node = ReddotTree.Instance.SearchNode("Mail");// if(node.ReddotCnt > 0)// {//     reddotView.ReddotCallback(node);// }}void OnMailButtonClick(){for (int i = 0; i < 3; i++){var tab = Instantiate(mailTab, Tab.transform.Find("Viewport/Content")).GetComponent<MailTab>();var index = i;tab.Init("Mail/Tab" + index);tab.GetComponent<Button>().onClick.AddListener(() => OnTabClick("Tab" + index));}OnTabClick("Tab0");}public void OnTabClick(string tabName){var content = mailPanel.transform.Find("Viewport/Content");for (int i = 0; i < content.childCount; i++){Destroy(content.GetChild(i).gameObject);}for (int i = 0; i < 5; i++){var newMail = Instantiate(mailContent, mailPanel.transform.Find("Viewport/Content")).GetComponent<MailContent>();newMail.transform.SetAsLastSibling();var index= i;var path = "Mail/" + tabName + "/" + index;newMail.Init(path, tabName);}}/// <summary>/// 初始化红点数据/// </summary>public void InitMailData(){for (int i = 0; i < 3; i++){var path = "Mail/Tab" + i;for (int j = 0; j < 5; j++){var mailPath = path + "/" + j;ReddotTree.Instance.ChangeReddotCnt(mailPath, 1);}}}public void OnDestroy(){reddotView.UnSubReddot("Mail");}}

这是一个模拟邮件主面板的类,其初始化红点数据的方法写在了InitMailData中
在这里插入图片描述
这里直接使用了ChangeReddotCnt方法,在查找不到的时候直接设置红点结点数据,这个方法会在面板初始化的时候调用
在这里插入图片描述
可以看到,在数据初始化之后,此面板才注册了自身节点

在这里插入图片描述
注意在OnDestroy方法中需要注销对于红点UI的注册

具体结构如下
在这里插入图片描述
可以看到红点的UI默认是没有激活的

2. 邮件侧边栏

public class MailTab : MonoBehaviour
{public ReddotView reddotView;public string path;public void Init(string path){reddotView.SubReddot(path);this.path = path;// var node = ReddotTree.Instance.SearchNode(path);// if(node.ReddotCnt > 0)// {//     reddotView.ReddotCallback(node);// }}public void OnDestroy(){reddotView.UnSubReddot(path);}
}

这里只需要在初始化的时候注册红点就行,因为红点数据已经在一开始初始化了,同时OnDestroy的时候需要取消注册
在这里插入图片描述

3. 邮件条目

public class MailContent : MonoBehaviour{public ReddotView reddotView;public Button contentButton; public Button deleteButton;public string path;public Text contentText;public void Init(string path, string content){this.path = path;reddotView.SubReddot(path);// var node = ReddotTree.Instance.SearchNode(path);// if(node.ReddotCnt > 0)// {//     reddotView.ReddotCallback(node);// }//ReddotTree.Instance.ChangeReddotCnt(path, 1);contentText.text = content;}void Awake(){contentButton.onClick.AddListener(OnContentButtonClick);deleteButton.onClick.AddListener(OnDeleteButtonClick);}public void OnContentButtonClick(){ReddotTree.Instance.ChangeReddotCnt(path, -1);}public void OnDeleteButtonClick(){ReddotTree.Instance.ChangeReddotCnt(path, -1);//ReddotTree.Instance.UnSubReddot(path);Destroy(gameObject);}void OnDestroy(){//ReddotTree.Instance.ChangeReddotCnt(path, -1);//ReddotTree.Instance.UnSubReddot(path);reddotView.UnSubReddot(path);}}

同样是在初始化时注册,销毁时注销
在这里插入图片描述

4. 效果

在这里插入图片描述

http://www.xdnf.cn/news/392491.html

相关文章:

  • Rockchip RK3308 开发(二)
  • 【人工智能】全面掌控:使用Python进行深度学习模型监控与调优
  • Springboot整合Swagger3
  • HttpServletResponse的理解
  • 【音视频工具】ffplay介绍
  • Redis 分布式锁
  • iOS实名认证模块的具体实现过程(swift)
  • 串口通讯
  • Docker使用ClickHouse | ClickHouse 配置用户名密码 | ClickHouse 可视化 | windows系统 | 镜像
  • [强化学习的数学原理—赵世钰老师]学习笔记01-基本概念
  • lampiao靶场渗透
  • # KVstorageBaseRaft-cpp 项目 RPC 模块源码学习
  • TikTok 账号运营干货:AI 驱动优化
  • Python----神经网络(基于Alex Net的花卉分类项目)
  • 按钮样式统一
  • Kids A-Z安卓版:儿童英语启蒙的优质选择
  • 特励达力科LeCroy推出Xena Freya Z800 800GE高性能的800G以太网测试平台
  • LLM 论文精读(四)LLM Post-Training: A Deep Dive into Reasoning Large Language Models
  • 基于多层权重博弈与广播机制的仿生类脑 AI 决策框架
  • 组合模式(Composite Pattern)详解
  • FR2012A富芮坤ADC:频繁调用adc_get_data要延时
  • 使用lldb看看Rust的HashMap
  • 三、c语言练习四题
  • Linux网络编程实现FTP服务器
  • 探秘 Cursor 核心:解锁系统提示词的进阶之路
  • c++ 如何写类(不带指针版)
  • k8s 资源对比总结
  • 精讲C++四大核心特性:内联函数加速原理、auto智能推导、范围for循环与空指针进阶
  • vue数据可视化开发echarts等组件、插件的使用及建议-浅看一下就行
  • 什么是硬件中断请求号?什么是中断向量号?