树实现客户端红点系统

2023-11-17

树实现客户端红点系统


引用:https://zhuanlan.zhihu.com/p/85978429

红点系统总览

在这里插入图片描述如上图所示,规划红点系统的时候,我们将整个系统分为独立的三个部分:结构层、驱动层和表现层。

结构层用来部署红点的层级结构,做过红点系统的都知道,很多时候红点系统的层级都很深,所以我们要用一个结构来描述层级,这个就是我们今天的主题,树结构。

驱动层是指,如何驱动这个树结构产生状态变化,以及状态变化之后如何将变化的行为通知到指定的表现层,在一定的程度上将数据和表现分离开。

表现层就专门承担表现的职责,比如有的红点就是一个单纯的红点,有的需要显示数字,有的可能是图标晃动,有的是显示new标签,有的是播放特效等等。这些都可以归属在表现层统一去管控。

demo 设计

在这里插入图片描述
在这样一个界面先,我们可以看到主界面有三个主要入口,分别是 公会、任务、邮件。邮件界面里,又分为三个标签,系统、队伍、公会。

代码设```

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RedPointConst
{
    public const string main = "Main";
    public const string mail = "Main.mail";
    public const string mailTeam = "Main.mail.mailTeam";
    public const string mailSystem = "Main.mail.System";
}

定一个Const类,按照系统来划分树的各个节点,比如上面展示的红点树结构,代码可以使用string来完成。这个定义不仅仅是用来规划结构,也会为后面事件驱动的时候提供key。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RedPointNode
{

    public string nodeName;
    public int pointNum = 0;
    public RedPointNode parent = null;
    public RedPointSystem.OnPointNumChange OnPointNumChange;
    public Dictionary<string, RedPointNode> dicChilds = new Dictionary<string, RedPointNode>();

    public void SetRedPointNum(int rpNum)
    {
        if (dicChilds.Count > 0)
        {
            Debug.LogWarning("onlyC案setleaf Node");
            return;
        }
        pointNum = rpNum;
        NotifyPointNumChange();
        if (parent != null)
        {
            parent.ChangePredPointNum();
        }
    }

    public void ChangePredPointNum()
    {
        int num = 0;
        foreach (var item in dicChilds.Values)
        {
            num += item.pointNum;
        }
        if (num != pointNum)
        {
            pointNum = num;
            if (parent != null)
                parent.ChangePredPointNum();
            NotifyPointNumChange();
        }
    }
    public void NotifyPointNumChange()
    {
        OnPointNumChange?.Invoke(this);
    }
}

红点的属性以及所需要的回调函数。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RedPointSystem
{
    public delegate void OnPointNumChange(RedPointNode node);
    RedPointNode mRootNode;
    static List<string> istRedPointTreeList = new List<string>
    {
      RedPointConst.main,
      RedPointConst.mail,
      RedPointConst.mailTeam,
      RedPointConst.mailSystem,
};

    public void InitRedPointTreeNode()
    {
        mRootNode = new RedPointNode();
        mRootNode.nodeName = RedPointConst.main;
        foreach (var s in istRedPointTreeList)
        {
            var node = mRootNode;
            var treeNodeAy = s.Split('.');
            if (treeNodeAy.Length > 1)
            {
                for (int i = 0; i < treeNodeAy.Length; i++)
                {
                    if (!node.dicChilds.ContainsKey(treeNodeAy[i]))
                        node.dicChilds.Add(treeNodeAy[i], new RedPointNode());
                    node.dicChilds[treeNodeAy[i]].nodeName = treeNodeAy[i];
                    node.dicChilds[treeNodeAy[i]].parent = node;
                    node = node.dicChilds[treeNodeAy[i]];
                }
            }
        }
    }
    public void SetRedPointNodeCallBack(string strNode, RedPointSystem.OnPointNumChange callBack)
    {
        var nodeList = strNode.Split('.');
        var node = mRootNode;
        for (int i = 0; i < nodeList.Length; i++)
        {
            if (!node.dicChilds.ContainsKey(nodeList[i]))
            {
                Debug.LogWarning("未找到父节点" + nodeList[i]);
                return;
            }
            node = node.dicChilds[nodeList[i]];
            if (i == nodeList.Length - 1)
            {
                node.OnPointNumChange = callBack;
            }
        }
    }

    public void SetInvoke(string strNode, int rpNum)
    {
        var nodeList = strNode.Split('.');
        var node = mRootNode;
        for (int i = 0; i < nodeList.Length; i++)
        {
            if (!node.dicChilds.ContainsKey(nodeList[i]))
            {
                Debug.LogWarning("未找到父节点" + nodeList[i]);
                return;
            }
            node = node.dicChilds[nodeList[i]];
            if (i == nodeList.Length - 1)
            {
                node.SetRedPointNum(rpNum);
            }
        }
    }
}

红点管理器,注册了所有的const红点。

demo 展示 红点的驱动层和回调展示层

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BootStart : MonoBehaviour
{
    public Image imgMail;
    public Image imgMailSystem;
    public Image imgMailTeam;
    public Text textMail;
    public Text textMailSystem;
    public Text textMailTeam;

    private void Start()
    {
        RedPointSystem rps = new RedPointSystem();
        rps.InitRedPointTreeNode();
        rps.SetRedPointNodeCallBack(RedPointConst.mail,MailCallBack);
        rps.SetRedPointNodeCallBack(RedPointConst.mailSystem, MailSystemCallBack);
        rps.SetRedPointNodeCallBack(RedPointConst.mailTeam, MailTeamCallBack);
        rps.SetInvoke(RedPointConst.mailSystem,3);
        rps.SetInvoke(RedPointConst.mailTeam,2);


        void MailCallBack(RedPointNode node)
        {
            textMail.text = node.pointNum.ToString();
            imgMail.gameObject.SetActive(node.pointNum>0);
        }  

        void MailSystemCallBack(RedPointNode node)
        {
            textMailSystem.text = node.pointNum.ToString();
            imgMailSystem.gameObject.SetActive(node.pointNum > 0);
        }

        void MailTeamCallBack(RedPointNode node)
        {
            textMailTeam.text = node.pointNum.ToString();
            imgMailTeam.gameObject.SetActive(node.pointNum > 0);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

树实现客户端红点系统 的相关文章

  • Unity的C#编程教程_59_字典 Dictionary 详解及应用练习

    文章目录 C Dictionary Introduction C Dictionary Looping through Dictionary C Dictionary When to Use C Dictionary Using Dicti
  • Unity的C#编程教程_52_类 Class 详解及应用练习(一)

    文章目录 C Classes for Behaviours Custom Classes 1 Custom Classes 2 Serialized Custom Class RPG Item Database Example 3 When
  • unity3D期末作业捕鱼游戏,适合初学者学习使用,包含源程序所有文件

    虚拟现实期末作业捕鱼游戏 免积分下载 点我下载资源 有按钮 背景音乐 可以发射炮弹捕鱼 可以选择难度 可以调节音乐声音大小 有游戏加载进度条 详细情况请看如下动态图 点我下载资源
  • Unity3D方向键控制人物移动的代码

    代码 var v Input GetAxis Vertical var h Input GetAxis Horizontal transform Translate transform forward Time deltaTime move
  • Unity的Text Mesh Pro文字显示重叠处理

    在使用Text Mesh Pro的时候 出现文字重叠 如图 在编辑器内显示是正确的 最后发现是换行造成的 原本的文字是从pdf中复制过来 就会重叠 在记事本中删除换行用回车再次换行就能正确显示
  • Unity3D射线检测

    射线检测主要用于像子弹是否打中物体 捡取物品等情况 本来面向百度想找例子看看 不过没找到合适的 还是自己总结尝试吧 以下测试Unity3D版本 2017 4 2f2 射线的检测步骤如下 1 Ray 这个类为了产生一个射线 如果我们想要场景中
  • 《Unity Shader入门精要》彩图版免费分享~~~~~

    这书很多地方都要币或者要钱 这里就免费分享了 下面是网盘链接 顺手点个赞或者评论一波呗 下载链接 链接 https pan baidu com s 137Y1nkB6h8HIvKOfwFPnbQ 提取码 f8dw 顺手点个赞 蟹蟹蟹蟹
  • Unity笔记-打飞碟游戏

    目的 创建一个打飞碟游戏 简陋 游戏要求 游戏要分多个 round 飞碟数量每个 round 都是 n 个 但色彩 大小 发射位置 速度 角度 每次发射数量可以变化 游戏过程中 仅能创建 n 个飞碟 且不容许初始化阶段生成任何飞碟 飞碟线路
  • Unity+Pico 手柄按键控制

    一 定义手柄按键API 1 InputDevices GetDeviceAtXRNode 通过XRNode获取对应的设备 2 XRNode是一个枚举类型 包含LeftEye RightEye CenterEye Head LeftHand
  • Unity使用Newtonsoft报错的解决方案

    文章目录 Unity 使用 Newtonsoft 报错的解决方案 问题描述 解决方法 方法一 使用 Unity 的 Package Manager 自动导入 方法二 访问 GitHub 下载 unitypackage 文件手动导入 Unit
  • unity 读取和写入Excel中文出现乱码解决方法

    在编辑器中读取和写入中文一切正常 发布出来只要是中文就会出现乱码 解决方法 将C Program Files Unity Editor Data Mono lib mono unity 目录下的I18N dll和I18N CJK dll复制
  • 【Unity灯光与渲染技术】Global Illumination全局光照

    本系列主要参考Unity灯光与渲染技术教程Unity Lighting And Rendering 同时会加上一点个人实践过程和理解 分割线 这篇文章主要讲全局光照 在看教程的时候就有一个点不是很理解 就是作者开启物体的static这个选项
  • unity粒子特效附上贴图后播放动画

    转自 http jingyan baidu com article f96699bbb1a0d6894f3c1b77 html 参考 http www unitymanual com thread 2993 1 1 html dsign a
  • Input.GetAxis _ Unity3d

    Input GetAxis 获取轴 static function GetAxis axisName string float Description描述 Returns the value of the virtual axis iden
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • Unity中UI组件

    一 Canvers 画布组件 Canvers下面是添加Button和Image组件 Rect Transform 1 Position 坐标位置 2 Width Height 高宽尺寸 3 Anchors 锚点 4 Pivot中心点 即UI
  • java中Keytool的使用总结

    java中Keytool的使用总结 2011 02 26 15 30 15 分类 在申请Android Map API Key的时候使用到了java中Keytool 下面转一篇介绍java中Keytool的文章 http blog csdn
  • Unity3d + NGUI 的多分辨率适配

    移动端的多机型适配 现在要介绍的是 锁链战记 这款游戏的适配方法 这种适配方法是UI是一个基础尺寸 背景是一个基础尺寸 背景比UI多出的部分是一些没有实际作用的部分 这样的适配方式避免了在iPhone5这样的小屏幕上镶边 首先设定UIRoo
  • Unity在UI界面上显示3D模型/物体,控制模型旋转

    https blog csdn net ChinarCSDN article details 81058773
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w

随机推荐

  • TCP滑动窗口控制流量的原理

    TCP的滑动窗口机制 TCP这个协议是网络中使用的比较广泛 他是一个面向连接的可靠的传输协议 既然是一个可靠的传输协议就需要对数据进行确认 TCP协议里窗口机制有2种 一种是固定的窗口大小 一种是滑动的窗口 这个窗口大小就是我们一次传输几个
  • 浏览器识别操作系统

    前端识别操作系统 浏览器识别操作系统 软件设计模式概述 浏览器识别操作系统
  • thread_Timer(线程中定时器)

    package com gzhs zsd thread import java util Date import java util Timer import java util TimerTask Timer定时器运用 author 谢泽
  • java 支付宝红包接入

    1 将公钥验证升级为证书验证 会得到如下三个证书 2 配置文件相关 支付宝支付相关配置 alipayconfig appid pid app private key charset utf 8 alipay public key call
  • Ubuntu 提示 Could not get lock /var/lib/dpkg/lock-frontend.解决方法

    今天在Ubuntu上安装的达梦数据库出现了一点操作错误 进行删除后还原快照就出现了这个问题 当我进行 apt 源安装还有更新时就一直显示 Waiting for cache lock Could not get lock var lib d
  • 解决VScode代码注释异常高亮

    问题描述 VScode出现代码注释后仍然高亮的问题 或者定义的函数名或者关键词没有高亮 如下所示 正常情况 异常情况 原因分析 同时装了python的扩展和vscode for python的扩展导致 两个扩展的主题配色冲突 解决方案 卸载
  • unity之InputField的文本监听

    1 创建InputField creat gt UI gt InputField 2 基本属性界面 可以再content type属性下设置InputField的文本类型 图片中无显示 3 文本监听 创建脚本 代码如下 using Syst
  • 计算机视觉————目标检测,多尺度问题理解以及FCN(全卷积神经网络)存在的弊端,问题。

    在阅读文献中 通常会遇到一个名词 XX用来解决多尺度问题 多尺度问题是什么意思 目标检测中 我们希望对于输入图片 不管图片中某个目标或大或小 我们都需要将其识别 对于小物体 我们可以将其理解为两种方式 一种是绝对小物体 即它本身占的像素就比
  • Android.bp 语法浅析-Android10.0编译系统(八)

    Android取经之路 的源码都基于Android Q 10 0 进行分析 Android取经之路 系列文章 系统启动篇 Android系统架构Android是怎么启动的Android 10 0系统启动之init进程Android10 0系
  • mysql怎么创建出生日期表_MySQL表的创建

    第1步 设计 首先要设计一张用于我想要用途的表 例如如下用于描述个人的信息类型 姓名 性别 出生日期 地址 最喜爱的食物 下面为他来指定列和数据类型 列 类型 允许值 name varchar 40 gender char 1 M F bi
  • MyBatis之枚举类型

    枚举可以让代码变得更为优雅 B格更高 当然MyBatis也是支持枚举类型的啦 首先 MyBatis内置了Enum的TypeHandler TypeHandler Java类型 JDBC类型 EnumTypeHandler Enum VARC
  • 华为机试练习(二)二叉树遍历

    题目描述 给定一棵二叉树的前序遍历和中序遍历 求其后序遍历 输入 两个字符串 其长度n均小于等于26 第一行为前序遍历 第二行为中序遍历 二叉树中的结点名称以大写字母表示 A B C 最多26个结点 输出 输入样例可能有多组 对于每组测试样
  • NodeJs模块化

    目录 一 导入模块 二 模块暴露数据 三 注意事项 一 导入模块 在模块中使用 require 传入文件路径即可引入文件 const test require me js 案例 在func js中定义一个函数 在index js使用该函数
  • kube-flannel.yml

    flannel作为k8s的集群中常用的网络组件 其yml文件的获取 建议去github中获取 具体的获取方式如下 apiVersion policy v1beta1 kind PodSecurityPolicy metadata name
  • C#实现组合优化问题算法-背包问题(附源码)

    C 实现组合优化问题算法 背包问题 附源码 背包问题是一类经典的组合优化问题 也是NP完全问题中的一种 其基本思想是 有一个容量为V的背包和n个物品 每个物品有自己的体积和价值 在保证不超过背包容量的前提下 选择某些物品装入背包 使得背包中
  • 依赖项注入

    ASP NET Core 通过依赖关系注入 DI 生成 服务 如数据库上下文 在 Program cs 中向 DI 注册 这些服务通过构造函数参数提供给需要它们的组件 在 Controllers MoviesController cs 文件
  • rsyslogd、syslog远程传输、日志存储、转存

    一 产生本地日志 1 etc resolv conf 配置文件 local0 local7是用户自定义的日志 这里我们使用local1 添加以下 local1 www admin admin log web log 配置完需要重启 rsys
  • DNS 解析一个地址的时候会返回多个 IP 吗?

    这是一个或许对你有用的社群 一对一交流 面试小册 简历优化 求职解惑 欢迎加入 芋道快速开发平台 知识星球 下面是星球提供的部分资料 项目实战 视频 从书中学 往事上 练 互联网高频面试题 面朝简历学习 春暖花开 架构 x 系统设计 摧枯拉
  • nginx php-fpm 分别安装在不同的机器(理解nginx和php-fpm)

    先起一个ubuntu的docker docker run ti name test1 ubunt 然后安装php5 fpm apt get install php5 fpm 配置fpm 允许从其他机器访问 listen 9000 默认是12
  • 树实现客户端红点系统

    树实现客户端红点系统 红点系统总览 demo 设计 代码设 引用 https zhuanlan zhihu com p 85978429 红点系统总览 如上图所示 规划红点系统的时候 我们将整个系统分为独立的三个部分 结构层 驱动层和表现层