当前位置:网站首页>Unity 通用红点系统
Unity 通用红点系统
2022-07-27 23:51:00 【lcl20093466】
红点系统一般用多叉树实现。
树:
using System;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class SGTreeNode
{
[SerializeField]
System.Object mData = null;
[SerializeField]
SGTreeNode mParent = null;
[SerializeField]
List<SGTreeNode> mChildren = null;
[SerializeField]
bool mIsLeaf = true;
public bool IsLeaf {
get {
return mIsLeaf; } }
public SGTreeNode Parent {
get {
return mParent; } }
public List<SGTreeNode> Children {
get {
return mChildren; } }
public SGTreeNode(System.Object data)
{
mChildren = new List<SGTreeNode>();
mData = data;
}
public System.Object GetData()
{
return mData;
}
public SGTreeNode SearchNode(Predicate<System.Object> compare)
{
if (compare.Invoke(mData))
{
return this;
}
else
{
SGTreeNode searchedNode = null;
foreach (var item in mChildren)
{
if (compare.Invoke(item.mData))
{
searchedNode = item;
}
else
{
searchedNode = item.SearchNode(compare);
}
if (searchedNode != null)
{
break;
}
}
return searchedNode;
}
}
public SGTreeNode AddChild(SGTreeNode child)
{
this.mIsLeaf = false;
child.mParent = this;
mChildren.Add(child);
return child;
}
}
红点管理器:
以下红点系统树形结构参见初始化。
using SG.Utils;
using System;
using System.Collections.Generic;
using UnityEngine;
public enum RedPointType
{
Null,
Root,//红点系统根节点
Task,//任务节点
SignIn,//签到
DailyTask, //每日任务
DailyTaskItem, //每日具体项
WeeklyTask,//每周任务
WeeklyTaskItem,//每周任务具体项
AchievementTask,//成就任务
AchievementTaskItem,//成就任务具体项
}
public enum RedPointEvent
{
RefreshRedPoint,
}
public class RedPointData
{
public RedPointType mType = RedPointType.Null;
public bool mIsShow = false;
public Dictionary<string, bool> mExtDatas = new Dictionary<string, bool>();
public int mRedCount = 0;
public RedPointData(RedPointType type)
{
mType = type;
mIsShow = false;
}
}
public class RedPointManager2 : MonoSingleton<RedPointManager2>
{
[SerializeField]
SGTreeNode mRootNode = null;
/// <summary>
/// 初始化红点系统
/// </summary>
public new void Init()
{
mRootNode = new SGTreeNode(new RedPointData(RedPointType.Root));
var taskNode = mRootNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.Task)));
var signNode = taskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.SignIn)));
var dailyTaskNode = taskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.DailyTask)));
var weeklyTaskNode = taskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.WeeklyTask)));
var achievementTaskNode = taskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.AchievementTask)));
dailyTaskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.DailyTaskItem)));
weeklyTaskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.WeeklyTaskItem)));
achievementTaskNode.AddChild(new SGTreeNode(new RedPointData(RedPointType.AchievementTaskItem)));
}
/// <summary>
/// 根据红点类型刷新红点是否显示。注:只能刷新叶子节点小红点数据
/// </summary>
/// <param name="redPointType"></param>
/// <param name="isShow"></param>
public void UpdateRedPoint(RedPointType redPointType, bool isShow)
{
var node = SearchNode(redPointType);
if (node != null)
{
if (node.IsLeaf)
{
var data = node.GetData() as RedPointData;
data.mIsShow = isShow;
data.mRedCount = 1;
UpdateParent(node.Parent);
SendRefreshRedPointEvent(node);
}
}
}
/// <summary>
/// 根据红点类型刷新红点是否显示。注:只能刷新叶子节点小红点数据
/// </summary>
/// <param name="redPointType"></param>
/// <param name="extData">当前红点类型包含多条红点数据</param>
public void UpdateRedPoint(RedPointType redPointType, Dictionary<string, bool> extData)
{
var node = SearchNode(redPointType);
if (node != null)
{
if (node.IsLeaf)
{
var data = node.GetData() as RedPointData;
var isShow = false;
var showCount = 0;
foreach (var item in extData)
{
isShow = item.Value || isShow;
if (item.Value)
{
showCount++;
}
data.mExtDatas.Remove(item.Key);
data.mExtDatas[item.Key] = item.Value;
}
data.mIsShow = isShow;
data.mRedCount = showCount;
UpdateParent(node.Parent);
SendRefreshRedPointEvent(node);
}
}
}
/// <summary>
/// 获取红点数据信息
/// </summary>
/// <param name="redPointType"></param>
/// <returns></returns>
public RedPointData GetRedPointData(RedPointType redPointType)
{
var node = SearchNode(redPointType);
if (node != null)
{
return node.GetData() as RedPointData;
}
else
{
return null;
}
}
SGTreeNode SearchNode(RedPointType redPointType)
{
var node = mRootNode.SearchNode(new Predicate<object>(delegate (object nodeData) {
RedPointData data = nodeData as RedPointData;
if (data != null)
{
return data.mType == redPointType;
}
else
{
return false;
}
}));
return node;
}
RedPointData GetNodeData(SGTreeNode node)
{
return node.GetData() as RedPointData;
}
void UpdateParent(SGTreeNode node)
{
if (node != null && !node.IsLeaf)
{
if (node.Children.Count > 0)
{
int redCount = 0;
bool isShow = false;
foreach (var item in node.Children)
{
var dataTemp = GetNodeData(item);
isShow = isShow || dataTemp.mIsShow;
if (GetNodeData(item).mIsShow)
{
redCount = redCount + dataTemp.mRedCount;
}
}
var data = node.GetData() as RedPointData;
data.mIsShow = isShow;
data.mRedCount = redCount;
}
UpdateParent(node.Parent);
}
}
void SendRefreshRedPointEvent(SGTreeNode node)
{
if (node != null)
{
GameEventMgr.Instance.SendEvent(RedPointEvent.RefreshRedPoint, new GameEventMgr.GameEventArgs()
{
data = node.GetData()
});
SendRefreshRedPointEvent(node.Parent);
}
}
}
使用示例:
void TestRedPoint()
{
GameEventMgr.Instance.RemoveEvent(RedPointEvent.RefreshRedPoint, OnEventUpdateRedPoint);
GameEventMgr.Instance.AddEvent(RedPointEvent.RefreshRedPoint, OnEventUpdateRedPoint);
Debug.Log("=========UpdateRedPoint:SignIn");
RedPointManager2.Instance.UpdateRedPoint(RedPointType.SignIn, true);
Debug.Log("=========UpdateRedPoint:DailyTaskItem 1");
RedPointManager2.Instance.UpdateRedPoint(RedPointType.DailyTaskItem, true);
Debug.Log("=========UpdateRedPoint:DailyTaskItem 2");
Dictionary<string, bool> mData = new Dictionary<string, bool>();
mData["1000"] = true;
mData["1001"] = true;
mData["1002"] = false;
RedPointManager2.Instance.UpdateRedPoint(RedPointType.DailyTaskItem, mData);
}
void OnEventUpdateRedPoint(AEventArgs arg)
{
var temp = arg as GameEventMgr.GameEventArgs;
var data = temp.data as RedPointData;
Debug.Log("===========TestEvent:" + LitJson.JsonMapper.ToJson(data));
}
输出:
边栏推荐
猜你喜欢
随机推荐
软件测试面试题:性能测试指标有哪些?
梳理 SQL 性能优化,收藏经典!
Interpretation of new features | the restriction of MySQL 8.0 on gtid is lifted
Interview question 01.06. string compression
股票问题5连
Unity shader introduction Essentials - basic texture
【向 Dice Roller 应用添加图片】
Kibana6.2.4 version update x-pack certification
Niuke net question brushing training (III)
软件测试面试题:你们的性能测试需求哪里来?
数仓搭建——DWS层
likeshop外卖点餐系统【100%开源无加密】
Leetcode 2351. the first letter that appears twice
Let's move forward together, the 10th anniversary of Google play!
Leetcode 2341. How many pairs can an array form
Interview question 01.09. string rotation
Day 013 一维数组练习
A comprehensive case of crawler learning -- visiting websites
Interview question 01.07. rotation matrix
Software test interview question: what are the performance test indicators?









