树实现客户端红点系统

树实现客户端红点系统


引用: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);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity红点系统是一种常用的游戏UI设计,主要用于提醒玩家当前有新的任务、奖励或其他未读信息需要处理。下面是一个简单的Unity红点系统设计: 1. 定义红点控件:在UI界面中添加一个红点控件,通常是一个小圆点或小数字。该控件需要有一个唯一的名称,用于后续的操作。 2. 定义红点数据结构:为每个需要红点提醒的功能定义一个红点数据结构,包含以下信息: - 功能名称:用于标识该功能。 - 红点控件名称:与UI界面中的红点控件名称对应。 - 是否需要红点提醒:标识该功能是否需要红点提醒。 - 红点数量:如果需要显示数字红点,则需要记录具体的数量。 3. 定义红点管理类:创建一个红点管理类,用于管理所有的红点数据和UI界面上的红点控件。该类需要提供以下功能: - 添加红点数据:向红点管理类中添加新的红点数据。 - 更新红点状态:根据红点数据中的信息,更新UI界面上对应的红点控件状态。 - 监听红点变化:提供回调函数,当某个红点数据的状态发生变化时,通知相应的UI界面进行更新。 4. 使用红点系统:在需要使用红点系统的地方,调用红点管理类的方法添加红点数据和监听红点变化。当红点数据的状态发生变化时,红点管理类会自动更新UI界面上的红点控件状态。 通过以上步骤,就可以实现一个简单的Unity红点系统。当玩家有新的任务或奖励时,红点控件会自动提醒玩家,增强了游戏的交互性和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值