[Unity]红点系统

news/2024/11/29 12:36:22/

参考大佬的lua 版本【游戏开发实战】手把手教你在Unity中使用lua实现红点系统(前缀树 | 数据结构 | 设计模式 | 算法 | 含工程源码)_unity红点系统_林新发的博客-CSDN博客

修改为c#版本,本人的仓库地址:

https://github.com/Zhou04191919/RedPointSystem.git

核心脚本:

RedPointNode.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RedPointNode 
{/// <summary>/// 节点名/// </summary>public  string name;/// <summary>/// 节点被经过的次数/// </summary>public int passCnt=0;/// <summary>/// 节点作为尾节点的次数/// </summary>public int endCnt = 0;/// <summary>/// /// </summary>public int redpointCnt = 0;public Dictionary<string, RedPointNode> children = new Dictionary<string, RedPointNode>();public Dictionary<string, Action<int>> updateCb = new Dictionary<string, Action<int>>();public RedPointNode(string name){this.name = name;this.passCnt = 0;this.endCnt = 0;this.redpointCnt = 0;this.children = new Dictionary<string, RedPointNode>();this.updateCb = new Dictionary<string, Action<int>>();}public static RedPointNode New(string name){return new RedPointNode(name);}
}

RedpointTree.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Xml.Linq;
using Unity.VisualScripting;
using UnityEngine;public class RedpointTree
{private RedPointNode root;public Dictionary<string, string> NodeNames = new Dictionary<string, string>{{ "Root","Root"},{ "ModelA","Root|ModelA"},{ "ModelA_Sub_1 ","Root|ModelA|ModelA_Sub_1"},{ "ModelA_Sub_2 ","Root|ModelA|ModelA_Sub_2"},{ "ModelB ", "Root|ModelB"},{ "ModelB_Sub_1 ","Root|ModelB|ModelB_Sub_1"},{ "ModelB_Sub_2 ","Root|ModelB|ModelB_Sub_2"}};public RedpointTree(){root = new RedPointNode("Root");}public void Init(){this.root =new RedPointNode("Root");构建前缀树foreach (var name in NodeNames.Values){this.InsertNode(name);}ChangeRedPointCnt(NodeNames["ModelA_Sub_1"], 1);ChangeRedPointCnt(NodeNames["ModelA_Sub_2"], 1);ChangeRedPointCnt(NodeNames["ModelB_Sub_1"], 1);ChangeRedPointCnt(NodeNames["ModelB_Sub_2"], 1);}public void InsertNode(string name){if (string.IsNullOrEmpty(name)){return;}if (SearchNode(name) != null){Debug.Log("你已经插入了此节点" + name);return;}RedPointNode node = root;node.passCnt += 1;string[] pathList = name.Split("|");foreach (string path in pathList){if (!node.children.ContainsKey(path)){node.children.Add(path, RedPointNode.New(path));}node = node.children[path];node.passCnt = node.passCnt + 1;}node.endCnt = node.endCnt + 1;}/// <summary>/// 查询节点是否在树中并返回节点/// </summary>/// <param name="name"></param>/// <returns></returns>public RedPointNode SearchNode(string name){if (string.IsNullOrEmpty(name)){return null;}RedPointNode node = this.root;string[] pathList = name.Split("|");foreach (string path in pathList){if (!node.children.ContainsKey(path)){return null;}node = node.children[path];}if (node.endCnt > 0){return node;}return null;}/// <summary>/// 删除某个节点/// </summary>/// <param name="name"></param>public void DeleteNode(string name){if (SearchNode(name) == null){return;}RedPointNode node = this.root;node.passCnt = node.passCnt - 1;string[] pathList = name.Split("|");foreach (string path in pathList){RedPointNode childNode = node.children[path];childNode.passCnt = childNode.passCnt - 1;if (childNode.passCnt == 0){// 如果该节点没有任何孩子,则直接删除node.children.Remove(path);return;}node = childNode;}node.endCnt = node.endCnt - 1;}/// <summary>/// 修改节点的红点数/// </summary>/// <param name="name"></param>/// <param name="delta"></param>public void ChangeRedPointCnt(string name,int delta){RedPointNode targetNode = SearchNode(name);if(targetNode==null){return;}if(delta<0&& targetNode.redpointCnt+delta<0){delta = -targetNode.redpointCnt;}RedPointNode node = this.root;string[] pathList = name.Split("|");foreach (string path in pathList){RedPointNode childNode = node.children[path];childNode.redpointCnt = childNode.redpointCnt + delta;node = childNode;foreach (Action<int> cb in node.updateCb.Values){cb?.Invoke(node.redpointCnt);}}}/// <summary>/// 设置红点更新回调函数/// </summary>/// <param name="name"></param>/// <param name="key"></param>/// <param name="cb"></param>public void SetCallBack(string name,string key,Action<int>cb){RedPointNode node = SearchNode(name);if (node == null){return;}node.updateCb.Add(key, cb);}/// <summary>/// 查询节点的红点数/// </summary>/// <param name="name"></param>/// <returns></returns>public int GetRedPointCnt(string name){RedPointNode node = SearchNode(name);if (node == null){return 0;}return node.redpointCnt;}
}public class NodeNames
{public const string Root = "Root";public const string ModelA = "Root|ModelA";public const string ModelA_Sub_1 = "Root|ModelA|ModelA_Sub_1";public const string ModelA_Sub_2 = "Root|ModelA|ModelA_Sub_2";public const string ModelB = "Root|ModelB";public const string ModelB_Sub_1 = "Root|ModelB|ModelB_Sub_1";public const string ModelB_Sub_2 = "Root|ModelB|ModelB_Sub_2";public static List<string> NodeList = new List<string>() {Root,ModelA,ModelA_Sub_1,ModelA_Sub_2,ModelB,ModelB_Sub_1,ModelB_Sub_2};
}

 应用:

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;public class GameHallPanel : MonoBehaviour
{[SerializeField] Text txtRoot;[SerializeField] Text txtModelA;[SerializeField] Text txtModelA_1;[SerializeField] Text txtModelA_2;[SerializeField] Text txtModelB;[SerializeField] Text txtModelB_1;[SerializeField] Text txtModelB_2;[SerializeField] Button txtRootBtn;[SerializeField] Button txtModelABtn;[SerializeField] Button txtModelA_1Btn;[SerializeField] Button txtModelA_2Btn;[SerializeField] Button txtModelBBtn;[SerializeField] Button txtModelB_1Btn;[SerializeField] Button txtModelB_2Btn;[SerializeField] Button ReBtn;[SerializeField] GameObject op;[SerializeField] GameObject tp;[SerializeField] GameObject ap;[SerializeField] GameObject bp;RedpointTree redpointTree;void Start(){//redpointTree= new RedpointTree();//redpointTree.Init();//redpointTree.SetCallBack(redpointTree.NodeNames["Root"], "Root", redpointCnt =>//{//    UpdateRedPoint(redpointCnt);//});op.SetActive(true);tp.SetActive(false);RegisterClickEvents();CreateTree();SetCallBack();AddDate();}private void CreateTree(){redpointTree = new RedpointTree();for (int i = 0; i < NodeNames.NodeList.Count; i++){redpointTree.InsertNode(NodeNames.NodeList[i]);}}private void RegisterClickEvents(){txtRootBtn.onClick.AddListener(()=> { op.SetActive(false);tp.SetActive(true); }); ;ReBtn.onClick.AddListener(() => { op.SetActive(true); tp.SetActive(false); });txtModelABtn.onClick.AddListener(() => { bp.SetActive(false); ap.SetActive(true); }) ;txtModelA_1Btn.onClick.AddListener(()=> { redpointTree.ChangeRedPointCnt(NodeNames.ModelA_Sub_1, -1); });txtModelA_2Btn.onClick.AddListener(() => { redpointTree.ChangeRedPointCnt(NodeNames.ModelA_Sub_2, -1); });txtModelBBtn.onClick.AddListener(() => { bp.SetActive(true); ap.SetActive(false); }) ;txtModelB_1Btn.onClick.AddListener(() => { redpointTree.ChangeRedPointCnt(NodeNames.ModelB_Sub_1, -1); });txtModelB_2Btn.onClick.AddListener(() => { redpointTree.ChangeRedPointCnt(NodeNames.ModelB_Sub_2, -1); });}private void SetCallBack(){redpointTree.SetCallBack(NodeNames.Root, "Root", (redpointCnt) =>{ShowText(txtRoot, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelA, "ModelA", (redpointCnt) =>{ShowText(txtModelA, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelA_Sub_1, "ModelA_Sub_1", (redpointCnt) =>{ShowText(txtModelA_1, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelA_Sub_2, "ModelA_Sub_2", (redpointCnt) =>{ShowText(txtModelA_2, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelB, "ModelB", (redpointCnt) =>{ShowText(txtModelB, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelB_Sub_1, "ModelB_Sub_1", (redpointCnt) =>{ShowText(txtModelB_1, redpointCnt);});redpointTree.SetCallBack(NodeNames.ModelB_Sub_2, "ModelB_Sub_2", (redpointCnt) =>{ShowText(txtModelB_2, redpointCnt);});}    private void ShowText( Text text, int redpointCnt){text.text = redpointCnt.ToString();text.transform.parent.gameObject.SetActive(redpointCnt > 0);}private void AddDate(){redpointTree.ChangeRedPointCnt(NodeNames.ModelA_Sub_1, 1);redpointTree.ChangeRedPointCnt(NodeNames.ModelA_Sub_2, 1);redpointTree.ChangeRedPointCnt(NodeNames.ModelB_Sub_1, 1);redpointTree.ChangeRedPointCnt(NodeNames.ModelB_Sub_2, 1);}
}


http://www.ppmy.cn/news/487082.html

相关文章

数据库系统概述——第六章 关系数据理论(知识点复习+练习题)

&#x1f31f;博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;离散数学考前复习&#xff08;知识点题&#xff09; &#x1f353;专栏&#xff1a;概率论期末速成&#xff08;一套卷&#xff09; &#x1f433;专栏&#xff1a;数字电路考前复习 &#x1f99a;专栏&am…

android x86玩和平精英,和平精英iOS和安卓可以一起玩吗 和平精英iOS和安卓数据互通吗...

和平精英手游分为iOS版和安卓版&#xff0c;每个系统都有各自的玩家。那么&#xff0c;和平精英iOS和安卓可以一起玩吗&#xff1f;和平精英iOS和安卓数据互通吗&#xff1f;接下来就让优游网小编为大家介绍一下和平精英iOS系统和安卓系统的相关内容&#xff0c;一起来看看吧&a…

鸿蒙系统是否能玩游戏,鸿蒙系统玩游戏跟安卓互通吗

相信平时玩手机游戏的朋友都经常会遇到安卓和ios不同服的情况。所以就有人开始担心鸿蒙系统玩游戏如果和安卓不互通&#xff0c;不仅会找不到一起玩游戏的朋友&#xff0c;还会丢失自己的数据。 鸿蒙系统玩游戏跟安卓互通吗 答&#xff1a;互通的。 1、首先&#xff0c;本身鸿蒙…

国服光遇android和ios能一起玩吗,光遇安卓和苹果可以一起玩吗 数据互通问题详解[多图]...

光遇安卓和苹果这两个系统的玩家可以一起组队吗&#xff0c;相信各位小伙伴都不清楚&#xff0c;同时游戏的数据互通吗&#xff0c;接下里为大家详细介绍互通规则解答。 光遇数据互通问题详解 首先经过测试&#xff0c;国际服的安卓和苹果是可以一起玩的&#xff0c;这两个平台…

C++实现德州扑克游戏(和电脑一起玩)

事先声明&#xff0c;本人坚决反对赌博&#xff0c;对众多程序员助纣为虐&#xff0c;远赴东南亚等地编写赌博网站的行为也很反感&#xff0c;更有甚者&#xff0c;使用python进行黑客行为&#xff0c;非法爬虫&#xff0c;真正实现了“C从入门到入土”,“python从入门到入狱”…

游戏陪玩APP开发的功能和特点

1、游戏评测推荐 根据对游戏的评测&#xff0c;向用户介绍该款游戏的内容&#xff0c;后根据游戏的可玩性和用户的特点&#xff0c;向用户推荐。 2、社区交流 通过社区的交流&#xff0c;促进用户之前的关系的建立&#xff0c;促进用户的活跃度。 3、游戏陪玩服务 用户们可…

大家一起做游戏

【题】 大家一起做游戏

胡调乱侃之一(一起玩游戏平台)

有好多人玩网游和单机游戏一样就一个人玩&#xff0c;找不到玩家&#xff0c;只能一个人练级&#xff0c;很枯燥。&#xff08;包括我&#xff09; 如果能提供一个平台来聚集玩家&#xff0c;从而有伙伴。平台可以提供公会&#xff0c;让你进游戏后就有公会的人帮忙。名字统一…