01.RedManager

红点系统_ide


红点系统_i++_02


红点系统_数据_03


红点系统_i++_04

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

}