![](https://i-blog.csdnimg.cn/blog_migrate/429933746e1a26b7173cb3dd14de19dc.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/fcb3ca1822678eb27495706f75e3b77d.png)
namespace RedDot
{
public enum RedDotType
{
None = 0,
Email_UnReadSystem = 1,
Email_UnReadPlayer = 2,
}
}
- 红点物体;
- RedDotItem.cs
- Created by Onelei 12/11/2017 10:21:47 AM. All rights reserved.
**/
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
namespace RedDot
{
public class RedDotItem : MonoBehaviour
{
/// <summary>
/// 红点物体;
/// </summary>
public GameObject Go_RedDot;
/// <summary>
/// 红点类型;
/// </summary>
public List<RedDotType> redDotTypes;
private bool bCachedRedDot = false;
void Start()
{
//注册红点;
RedDotManager.Instance.RegisterRedDot(redDotTypes, this);
//设置红点;
bool bRedDot = RedDotManager.Instance.Check(redDotTypes);
SetData(bRedDot, true);
}
void OnDestroy()
{
//取消注册红点;
RedDotManager.Instance.UnRegisterRedDot(this);
}
/// <summary>
/// 设置红点显示;
/// </summary>
/// <param name="bRedDot"></param>
public void SetData(bool bRedDot, bool bForceRefresh = false)
{
if (bForceRefresh)
{
Go_RedDot.SetActive(bRedDot);
bCachedRedDot = bRedDot;
return;
}
if (bCachedRedDot != bRedDot)
{
Go_RedDot.SetActive(bRedDot);
bCachedRedDot = bRedDot;
}
}
/// <summary>
/// 获取当前物体挂载的所有红点;
/// </summary>
/// <returns></returns>
public List<RedDotType> GetRedDotTypes()
{
return this.redDotTypes;
}
}
}
/// 初始化红点系统(注意只需要初始化一次);
/// </summary>
public void Initilize()
{
RedDotConditionDict.Clear();
// 添加红点数据判断;
RedDotConditionDict.Add(RedDotType.Email_UnReadSystem, new RedDot_EmailUnReadSystem());
RedDotConditionDict.Add(RedDotType.Email_UnReadPlayer, new RedDot_EmailUnReadPlayer());
}</div></div><div class="content-item_2h5dMmiy type-unstyled"><div class="unstyled_cGikOLR-">我们需要一个通用的红点判断的基类,因此设计RedDotBase如下</div></div><div class="content-item_2h5dMmiy type-code-block"><div class="code-block_XPQq5Tjm">/**
- 红点数据类-基类;
- RedDotBase.cs
- Created by Onelei 12/11/2017 10:23:47 AM. All rights reserved.
**/
namespace RedDot
{
public abstract class RedDotBase
{
/// <summary>
/// 是否显示红点(true表示显示,false表示不显示;)
/// </summary>
/// <param name="?"></param>
/// <returns></returns>
public virtual bool ShowRedDot(object[] objs)
{
return false;
}
}
}
- 未读邮件红点判断逻辑-玩家红点;
- RedDot_EmailUnReadPlayer.cs
- Created by Onelei 12/11/2017 10:25:00 AM. All rights reserved.
**/
using RedDot;
public class RedDot_EmailUnReadPlayer : RedDotBase
{
public override bool ShowRedDot(object[] objs)
{
return MailManager.Instance.IsPlayerRedDot();
}
}
- 未读邮件红点判断逻辑-系统红点;
- RedDot_EmailUnRead.cs
- Created by Onelei 12/11/2017 10:25:00 AM. All rights reserved.
**/
using RedDot;
public class RedDot_EmailUnReadSystem : RedDotBase
{
public override bool ShowRedDot(object[] objs)
{
return MailManager.Instance.IsSystemRedDot();
}
}
/// 添加红点界面;
/// </summary>
/// <param name=“redDotType”></param>
/// <param name=“item”></param>
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);
}
}
/// 检查红点提示,内部调用;
/// </summary>
/// <param name=“redDotType”></param>
/// <returns></returns>
private bool Check(RedDotType redDotType, object[] objs)
{
if (RedDotConditionDict.ContainsKey(redDotType))
{
return RedDotConditionDict[redDotType].ShowRedDot(objs);
}
return false;
}
- 红点系统管理类;
- RedDotManager.cs
- Created by Onelei 12/11/2017 10:21:47 AM. All rights reserved.
**/
using System.Collections.Generic;
namespace RedDot
{
public class RedDotManager
{
private static RedDotManager _instance;
public static RedDotManager Instance
{
get
{
if (null == _instance)
{
_instance = new RedDotManager();
}
return _instance;
}
}
/// <summary>
/// 红点数据;
/// </summary>
Dictionary<RedDotType, RedDotBase> RedDotConditionDict = new Dictionary<RedDotType, RedDotBase>();
/// <summary>
/// 红点物体;
/// </summary>
Dictionary<RedDotType, List<RedDotItem>> RedDotObjDict = new Dictionary<RedDotType, List<RedDotItem>>();
/// <summary>
/// 初始化红点系统(注意只需要初始化一次);
/// </summary>
public void Initilize()
{
RedDotConditionDict.Clear();
// 添加红点数据判断;
RedDotConditionDict.Add(RedDotType.Email_UnReadSystem, new RedDot_EmailUnReadSystem());
RedDotConditionDict.Add(RedDotType.Email_UnReadPlayer, new RedDot_EmailUnReadPlayer());
}
/// <summary>
/// 注册红点;
/// </summary>
/// <param name="redDotType"></param>
/// <param name="item"></param>
public void RegisterRedDot(List<RedDotType> redDotTypes, RedDotItem item)
{
for (int i = 0; i < redDotTypes.Count; i++)
{
RegisterRedDot(redDotTypes[i], item);
}
}
/// <summary>
/// 取消注册红点;
/// </summary>
/// <param name="item"></param>
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;
}
}
}
/// <summary>
/// 检查红点提示;
/// </summary>
/// <param name="redDotType"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 更新该类型的所有红点组件;
/// </summary>
/// <param name="redDotType"></param>
/// <returns></returns>
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);
}
}
}
}
#region private
/// <summary>
/// 添加红点界面;
/// </summary>
/// <param name="redDotType"></param>
/// <param name="item"></param>
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);
}
}
/// <summary>
/// 检查红点提示,内部调用;
/// </summary>
/// <param name="redDotType"></param>
/// <returns></returns>
private bool Check(RedDotType redDotType, object[] objs)
{
if (RedDotConditionDict.ContainsKey(redDotType))
{
return RedDotConditionDict[redDotType].ShowRedDot(objs);
}
return false;
}
#endregion
}
}
void Start()
{
// 设置按钮回调;
Button_EmailSystem.onClick.AddListener(OnClickEmailSystem);
Button_EmailPlayer.onClick.AddListener(OnClickEmailPlayer);
}</div></div><div class="content-item_2h5dMmiy type-unstyled"><div class="unstyled_cGikOLR-">我们需要在按钮点击的时候,计算该红点类型所对应的的红点逻辑,同时刷新所有绑定了该红点类型的RedDotItem身上的红点。</div></div><div class="content-item_2h5dMmiy type-code-block"><div class="code-block_XPQq5Tjm"> /// <summary>
/// 系统按钮的回调;
/// </summary>
void OnClickEmailSystem()
{
// 点击之后表示邮件读取过了,设置邮件为已读状态;
// (注意这里不能够设置红点的显隐,因为是有数据控制的,所以要控制数据那边的红点逻辑);
// RedDot.RedDotManager.Instance.SetData(RedDot.RedDotType.Email_UnRead,false);
RedDot.MailManager.Instance.SetSystemRedDot(false);
RedDot.RedDotManager.Instance.NotifyAll(RedDot.RedDotType.Email_UnReadSystem);
}
/// <summary>
/// 玩家按钮的回调;
/// </summary>
void OnClickEmailPlayer()
{
// 点击之后表示邮件读取过了,设置邮件为已读状态;
// (注意这里不能够设置红点的显隐,因为是有数据控制的,所以要控制数据那边的红点逻辑);
// RedDot.RedDotManager.Instance.SetData(RedDot.RedDotType.Email_UnRead,false);
RedDot.MailManager.Instance.SetPlayerRedDot(false);
RedDot.RedDotManager.Instance.NotifyAll(RedDot.RedDotType.Email_UnReadPlayer);
}
总结
我们将红点的数据和表现分离,通过RedDotItem来控制红点的显示。RedDotItem是一个单独的Prefab,我们可以设计不同的红点,比如红点上面是否有数字等,都可以在一个RedDotItem上面进行扩展。同时还支持一个红点类型绑定在不同的Prefab上面,一个Prefab上面绑定多个红点。这样一对多的关系,我们使用Dictionary来方便管理,Key就是红点类型,Value是一个List,里面包含了该类型绑定的所有RedDotItem。只要取出来对应的红点类型的红点是否和之前不一样,不一样就刷新该Key对应的Value的所有RedDotItem红点的显示即可