红点系统

本文介绍了Unity中的Red Dot Manager类及其关联组件,展示了如何使用红点类型来标记未读邮件,通过RedDotItem和RedDotBase子类实现不同邮件类型的红点显示,并通过MailManager管理全局红点状态。同时,邮件按钮点击事件触发红点更新和邮件状态的同步。
摘要由CSDN通过智能技术生成

01.RedManager
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

 public enum RedDotType:ushort
{
    None=0,
    Email_UnReadSstem=1,
    Email_UnReadPlayer=2,
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RedDotItem : MonoBehaviour
{
    //红点物体
    [SerializeField]
    private GameObject GO_RedDot;
    //红点类型
    public List<RedDotType> redDotTypes;
    private bool bCacheRedDot = false;
    void Start()
    {
        RedDotManager.Instance.RegisterRedDot(redDotTypes, this);
        bool bRedDot = RedDotManager.Instance.Check(redDotTypes);
        SetData(bRedDot, true);
    }


    public void SetData(bool bRedDot,bool bForceRefresh=false)
    {
        if (bForceRefresh)
        {
            GO_RedDot.SetActive(bRedDot);
            bCacheRedDot = bRedDot;
            return;
        }
        if (bCacheRedDot != bRedDot)
        {
            GO_RedDot.SetActive(bRedDot);
            bCacheRedDot = bRedDot;
        }
    }

    public List<RedDotType> GetRedDotTypes()
    {
        return this.redDotTypes;
    }


    private void OnDestroy()
    {
        RedDotManager.Instance.UnRegisterRedDot(this);
    }


}

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

public abstract class RedDotBase
{
    public virtual bool ShowRedDot(object[] objs)
    {
        return false;
    }
}

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

public class RedDot_EmailUnReadSystem : RedDotBase
{
    public override bool ShowRedDot(object[] objs)
    {
        return MailManager.Instance.IsSystemRedDot();
    }
}

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

public class RedDot_EmailUnReadPlayer : RedDotBase
{
    public override bool ShowRedDot(object[] objs)
    {
        return MailManager.Instance.IsPlayerRedDot();
    }
}

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

public class MailManager
{
    private static MailManager _inctance;
    public static MailManager Instance
    {
        get
        {
            if (_inctance == null)
            {
                _inctance = new MailManager();
            }
            return _inctance;
        }
    }

    private bool bSystemRedDot = true;
    public bool IsSystemRedDot()
    {
        return bSystemRedDot;
    }

    public void SetSystemRedDot(bool bRedDot)
    {
        this.bSystemRedDot = bRedDot;
    }
    private bool bPlayerRedDot = true;

    public bool IsPlayerRedDot()
    {
        return bPlayerRedDot;
    }

    public void SetPlayerRedDot(bool bRedDot)
    {
        this.bPlayerRedDot = bRedDot;
    }
}


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

public class RedDotManager 
{
    private static RedDotManager _inctance;
    public static RedDotManager Instance
    {
        get
        {
            if (_inctance == null)
            {
                _inctance = new RedDotManager();
            }
            return _inctance;
        }
    }
    //红点数据
    Dictionary<RedDotType, RedDotBase> RedDotConditionDict = new Dictionary<RedDotType, RedDotBase>();
    //红点物体
    Dictionary<RedDotType, List<RedDotItem>> RedDotObjDict = new Dictionary<RedDotType, List<RedDotItem>>();

    public void Initilize()
    {
        RedDotConditionDict.Clear();
        RedDotConditionDict.Add(RedDotType.Email_UnReadSstem,new RedDot_EmailUnReadSystem());
        RedDotConditionDict.Add(RedDotType.Email_UnReadPlayer, new RedDot_EmailUnReadPlayer());
    }

    // 注册红点
    public void RegisterRedDot(List<RedDotType> redDotTypes,RedDotItem item)
    {
        for (int i=0;i<redDotTypes.Count; i++)
        {
            RegisterRedDot(redDotTypes[i], item);
        }
    }

    private void RegisterRedDot(RedDotType redDotType, RedDotItem item)
    {
        if (RedDotObjDict.ContainsKey(redDotType))
        {
            RedDotObjDict[redDotType].Add(item);
        }
        else
        {
            List<RedDotItem> items = new List<RedDotItem>();
            items.Add(item);
            RedDotObjDict.Add(redDotType,items);
        }
    }

    //取消注册红点
    public void UnRegisterRedDot(RedDotItem item)
    {
        Dictionary<RedDotType, List<RedDotItem>>.Enumerator itor = RedDotObjDict.GetEnumerator();
        while (itor.MoveNext())
        {
            List<RedDotItem> redDotItems = itor.Current.Value;
            if (redDotItems.Contains(item))
            {
                redDotItems.Remove(item);
                break;
            }
        }
    }
    // 检查红点提示
    public bool Check(List<RedDotType> redDotTypes, object[] objs = null)
    {
        for (int i = 0; i < redDotTypes.Count; i++)
        {
            if (Check(redDotTypes[i], objs))
            {
                return true;
            }
        }
        return false;
    }
    private bool Check(RedDotType redDotType, object[] objs)
    {
        if (RedDotConditionDict.ContainsKey(redDotType))
        {
            return RedDotConditionDict[redDotType].ShowRedDot(objs);
        }
        return false;
    }
    // 更新该类型的所有红点组件
    public void NotifyAll(RedDotType redDotType, object[] objs = null)
    {
        if (RedDotObjDict.ContainsKey(redDotType))
        {
            for (int i = 0; i < RedDotObjDict[redDotType].Count; i++)
            {
                RedDotItem item=RedDotObjDict[redDotType][i];
                if (item!=null)
                {
                    List<RedDotType> redDotTypes=item.GetRedDotTypes();
                   bool bCheck=Check(redDotTypes, objs);
                    item.SetData(bCheck);
                }
            }
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIEmail : MonoBehaviour
{
    /// <summary>
    /// 系统邮件按钮;
    /// </summary>
    [SerializeField]
    Button Button_EmailSystem;
    /// <summary>
    /// 玩家邮件按钮;
    /// </summary>
    [SerializeField]
    Button Button_EmailPlayer;

    void Awake()
    {
        // 注意这个函数只需要初始化一次;
        RedDotManager.Instance.Initilize();
    }

    // Use this for initialization
    void Start()
    {
        // 设置按钮回调;
        Button_EmailSystem.onClick.AddListener(OnClickEmailSystem);
        Button_EmailPlayer.onClick.AddListener(OnClickEmailPlayer);

    }

    /// <summary>
    /// 系统按钮的回调;
    /// </summary>
    void OnClickEmailSystem()
    {
        // 点击之后表示邮件读取过了,设置邮件为已读状态;
        // (注意这里不能够设置红点的显隐,因为是有数据控制的,所以要控制数据那边的红点逻辑);
        // RedDot.RedDotManager.Instance.SetData(RedDot.RedDotType.Email_UnRead,false);

        MailManager.Instance.SetSystemRedDot(false);
        RedDotManager.Instance.NotifyAll(RedDotType.Email_UnReadSstem);
    }

    /// <summary>
    /// 玩家按钮的回调;
    /// </summary>
    void OnClickEmailPlayer()
    {
        // 点击之后表示邮件读取过了,设置邮件为已读状态;
        // (注意这里不能够设置红点的显隐,因为是有数据控制的,所以要控制数据那边的红点逻辑);
        // RedDot.RedDotManager.Instance.SetData(RedDot.RedDotType.Email_UnRead,false);

        MailManager.Instance.SetPlayerRedDot(false);
        RedDotManager.Instance.NotifyAll(RedDotType.Email_UnReadPlayer);
    }
}

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 numChangeFunc; // 发生变化的回调函数

    // 子节点
    public Dictionary<string, RedPointNode> dicChilds = new Dictionary<string, RedPointNode>();

    /// <summary>
    /// 设置当前节点的红点数量
    /// </summary>
    /// <param name="rpNum"></param>
    public void SetRedPointNum(int rpNum)
    {
        if (dicChilds.Count > 0) // 红点数量只能设置叶子节点
        {
            Debug.LogError("Only Can Set Leaf Node!");
            return;
        }
        pointNum = rpNum;

        NotifyPointNumChange();
        if (parent != null)
        {
            parent.ChangePredPointNum();
        }
    }

    /// <summary>
    /// 计算当前红点数量
    /// </summary>
    public void ChangePredPointNum()
    {
        int num = 0;
        foreach (var node in dicChilds.Values)
        {
            num += node.pointNum;
        }
        if (num != pointNum) // 红点有变化
        {
            pointNum = num;
            NotifyPointNumChange();
        }
    }

    /// <summary>
    /// 通知红点数量变化
    /// </summary>
    public void NotifyPointNumChange()
    {
        numChangeFunc?.Invoke(this);
    }

}

public class RedPointConst
{
    public const string main = "Main";// 主界面
    public const string mail = "Main.Mail";// 主界面邮件按钮
    public const string mailSystem = "Main.Mail.System";// 邮件系统界面
    public const string mailTeam = "Main.Mail.Team";// 邮件队伍界面
    public const string mailAlliance = "Main.Mail.Alliance";// 邮件公会界面

    public const string task = "Main.Task";// 主界面任务按钮

    public const string alliance = "Main.Alliance";// 主界面公会按钮
}


public class RedPointSystem
{
    public delegate void OnPointNumChange(RedPointNode node);// 红点变化通知
    RedPointNode mRootNode; // 红点树Root节点

    static List<string> lstRedPointTreeList = new List<string> // 初始化红点树
    {
        RedPointConst.main,
        RedPointConst.mail,
        RedPointConst.mailSystem,
        RedPointConst.mailTeam ,
        RedPointConst.mailAlliance ,

        RedPointConst.task,

        RedPointConst.alliance,
    };

    public void InitRedPointTreeNode()
    {
        mRootNode = new RedPointNode();
        mRootNode.nodeName = RedPointConst.main;

        foreach (var s in lstRedPointTreeList)
        {
            var node = mRootNode;
            var treeNodeAy = s.Split('.');
            if (treeNodeAy[0] != mRootNode.nodeName)
            {
                Debug.Log("RedPointTree Root Node Error:" + treeNodeAy[0]);
                continue;
            }
            if (treeNodeAy.Length > 1)
            {
                for (int i = 1; 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('.');// 分析树节点
        if (nodeList.Length == 1)
        {
            if (nodeList[0] != RedPointConst.main)
            {
                Debug.Log("Get Wrong Root Node! current is " + nodeList[0]);
                return;
            }
        }

        var node = mRootNode;
        for (int i = 1; i < nodeList.Length; i++)
        {
            if (!node.dicChilds.ContainsKey(nodeList[i]))
            {
                Debug.Log("Does Not Contains Child Node :" + nodeList[i]);
                return;
            }
            node = node.dicChilds[nodeList[i]];

            if (i == nodeList.Length - 1) // 最后一个节点了
            {
                node.numChangeFunc = callBack;
                return;
            }
        }
    }

    /// <summary>
    /// 激发数据变化
    /// </summary>
    /// <param name="nodeName"></param>
    /// <param name="rpNum"></param>
    public void SetInvoke(string strNode, int rpNum)
    {
        var nodeList = strNode.Split('.');// 分析树节点
        if (nodeList.Length == 1)
        {
            if (nodeList[0] != RedPointConst.main)
            {
                Debug.Log("Get Wrong Root Node! current is " + nodeList[0]);
                return;
            }
        }

        var node = mRootNode;
        for (int i = 1; i < nodeList.Length; i++)
        {
            if (!node.dicChilds.ContainsKey(nodeList[i]))
            {
                Debug.Log("Does Not Contains Child Node :" + nodeList[i]);
                return;
            }
            node = node.dicChilds[nodeList[i]];

            if (i == nodeList.Length - 1) // 最后一个节点了
            {
                node.SetRedPointNum(rpNum); // 设置节点的红点数量
            }
        }
    }



}

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 txtMail;
    public Text txtMailSystem;
    public Text txtMailTeam;

    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, 4);
    }

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

        Debug.Log(node.nodeName + " rp Num changed!  num = " + node.pointNum);
    }

    void MailSystemCallBack(RedPointNode node)
    {
        txtMailSystem.text = node.pointNum.ToString();
        imgMailSystem.gameObject.SetActive(node.pointNum > 0);
        Debug.Log(node.nodeName + " rp Num changed! num = " + node.pointNum);
    }

    void MailTeamCallBack(RedPointNode node)
    {
        txtMailTeam.text = node.pointNum.ToString();
        imgMailTeam.gameObject.SetActive(node.pointNum > 0);
        Debug.Log(node.nodeName + " rp Num changed! num = " + node.pointNum);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值