树实现客户端红点系统

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(使用前将#替换为@)

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

  • Unity3D之MonoBehaviour

    Unity3D中的MonoBehaviour是一种基于组件的编程架构 用于开发游戏和应用程序 它是Unity引擎中用于创建行为的基类之一 并且可以让你通过重写其方法来定义对象在游戏运行时的行为 首先 在Unity中创建一个游戏对象并向其添加
  • Unity UGUI的RawImage(原始图片)组件的介绍及使用

    Unity UGUI的RawImage 原始图片 组件的介绍及使用 1 什么是RawImage组件 RawImage是Unity UGUI中的一个组件 用于显示原始图片 与Image组件不同 RawImage可以直接显示原始图片的像素数据
  • Unity3d 简单的按照路径移动物体!

    在TORQUE引擎中 我们只要设置几个点 然后物体会按照这几个点顺序移动 Unity3d也可以的 现在介绍一个很简单的按照路径移动的方法 目标是让蓝色方块沿着紫色方块组成的路径移动 设计思想就是让蓝色方块移动第一个 然后继续移动到第二个 然
  • URP——后期处理特效

    通用渲染管道 URP 包括一个后处理效果的集成实现 如果使用URP 则不需要为后期处理效果安装额外的包 URP与Post Processing Stack v2包不兼容 URP使用体积框架进行后期处理效果 下面的图片显示了一个URP场景有没
  • unity中通过touch旋转、放大和缩小物体以及滑动方向的判断

    unity中通过touch旋转 放大和缩小物体以及滑动方向的判断这个需求在游戏开发中也是非常频繁 话不多说直接上代码 using System Collections using System Collections Generic usi
  • Unity笔记-打飞碟游戏

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

    了解界面 如果您对编辑器界面没有非常地了解 那么请花一些时间查看并熟悉 Editor 编辑器 界面 Editor 主窗口由选项卡式窗口组成 这些窗口可重新排列 因此 Editor 的外观可能因项目或者开发者而异 具体取决于个人偏好 Wind
  • 【Unity3d】Animator和Animation组件使用注意事项

    一 Animator一般用于人物动画控制 特点是动画是持续的 可能有动作切换 Animation一般用于间断性的动画的控制 比如一个场景特效的播放 只播放一次就完了 二 实测Animation速度比Animator快10 左右 内存占用没测
  • 闲云:unity中不能识别monobehevior关键字的问题

    有时候一些小问题很恼人 如unity中新建脚本后不能识别monobehevior关键字 在vs2017右侧的解决方案中点击刷新图标 或者把不能识别的脚本添加到vs2017右侧的解决方案中的Assets中即可 还不行就点击 排除 然后再 添加
  • JPush极光推送Unity插件iOS设备无法获取DeviceToken

    前言 最近在使用JPush进行极光推送 Unity插件GitHub地址https github com jpush jpush unity3d plugin 问题描述 但是发现了一个问题 按照官方文档操作 最终仍然无法获取DeviceTok
  • 游戏开发unity编辑器扩展知识系列:一个方法添加至多个MenuItem

    代码如下 用多个MenuItem标记方法就可以了 MenuItem GameObject 生成带图片的Image false 100 MenuItem Assets 生成带图片的Image static void GenImageGameO
  • unity本地分数排行榜简单解决方案(Json)

    具体效果 大体方法 创建一个分数类Score和一个分数类的容器List
  • unity3d 输入法相关API

    Input inputString 获取输入的文字 正在打的中文是接受不到的 只有在文字写到文本框才能获取 Input imeCompositionMode 是否是激活输入框状态 on 是 Input compositionString 空
  • Unity3D 官方文档 平台特殊化之Standalone和多显示器的处理

    版本 unity 5 6 语言 C 总起 Standalone 我一眼看下去的理解就是PC机平台 官方文档中说该平台指的是Mac Windows和Linux 这篇文章主要讲的是Standalone平台下的设置 通过点击菜单栏的File gt
  • unity中的一些快捷键(齐)

    重命名的快捷键是F2 ALT 鼠标左键点击Hierarchy对象可以展开和收起对象的所有子物体 SHIFT 空格 可以对当前窗口进行放大缩小
  • Unity使用spine动画

    Unity使用spine动画 在 Unity 中 常常使用 Spine 来制作一些动画 引擎本身并不能直接播放 Spine 动画 需要额外导入一个 RunTime 插件库才能支持 官网插件导入 当然 也可以到 Spine 官网关于 Unit
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • Unity打包WebGL的优化常用操作?

    1 贴图部分优化 如果贴图格式时2048 在不影响画面效果的情况下 改成1024或者5 12 还可以缩小包体 2 压缩和解压缩问题 WebGL打包的时候分三种压缩情况 gzip 比Brotli文件打 但打包快 http和https都支持 B
  • java中Keytool的使用总结

    java中Keytool的使用总结 2011 02 26 15 30 15 分类 在申请Android Map API Key的时候使用到了java中Keytool 下面转一篇介绍java中Keytool的文章 http blog csdn
  • Unity3D的四种坐标系

    1 World Space 世界坐标 我们在场景中添加物体 如 Cube 他们都是以世界坐标显示在场景中的 transform position可以获得该位置坐标 2 Screen Space 屏幕坐标 以像素来定义的 以屏幕的左下角为 0

随机推荐

  • 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 红点系统总览 如上图所示 规划红点系统的时候 我们将整个系统分为独立的三个部分 结构层 驱动层和表现层