Unity 红点系统

首先明确一个,即红点系统的数据结构是一颗树,并且红点的数据结构的初始化需要放在游戏的初始化中,之后再是对应的红点UI侧的注册,对应的红点UI在销毁时需要注销对红点UI的显示回调注册,但是不销毁数据侧的红点注册

- 具体分布

1. ReddotNode 红点结点类,数据侧

在这里插入图片描述
红点结点类负责承载红点的数据关系,其中在_reddotCnt的数据改变时,判断和现有值是否相等,如果不相等,赋值的同时,调用UI更新的回调

2. 红点UI类,表现侧

在这里插入图片描述
这里设计的是一个红点表现的抽象基类,因为红点的表现可能有多种多样,比如最直接的一个红色的点,或者是显示数字的红点,或者其他,那么对应的红点类型只需要继承这个类,然后实现各自的ReddotCallback就行了
在SubReddot方法中isCallImmediate参数用来判断是否需要在UI注册时立马调用一次回调,一般来说,在UI注册时,默认需要调用一次来判断是否需要显示红点,所以这里默认是true,这样的话,当重新回到某个UI面板时,重走一遍初始化注册时,会自动调一次红点显示判断

3. 具体红点类型

在这里插入图片描述
这里举了个例子,这是一个直接显示,隐藏的红点类型,所以只需要重写ReddotCallback,在内部判断红点计数,控制UI的显示隐藏就好

4. 红点树管理类

在这里插入图片描述
既然是管理类所以这个类被设计为一个单例类
在这个类的设计中,在查找方法中不设置创建的部分,因为之前参考某些红点框架,在查找不到时会去主动创建,但这里没有这么做,但在设置红点时,存在查找的部分
对于改变红点计数方法,其传入的数字是一个增量,是可正可负的,因为有的时候是减红点数,有的时候是加红点数,这个时候就可以传入-1或+1,如果当前结点的红点数加上增量 < 0,说明超出了范围,那么手动将增量设置为负的当前结点红点数,这样保证了即使超出范围,最后得到的值是0
并且在这里一开始是用的SetReddots方法,即设置,因为当想要改变一个红点的计数时,说明已经要用到这个结点,那么没有的话一定要创建出来,如果有的话,刚好直接查找就好
之后遍历这条路径上的每一个结点,将增量加上

- 具体使用

1. 邮件面板主页

public class Mail : MonoBehaviour
    {
        public Button mailButton;
        public GameObject mailPanel;
        public GameObject mailContent;

        public ReddotView reddotView;

        public GameObject mailTab;

        public GameObject Tab;

        public List<Button> tabs = new List<Button>();

        void Awake()
        {
            mailButton = GetComponent<Button>();
            mailButton.onClick.AddListener(OnMailButtonClick);
            
            //ReddotTree.Instance.SetReddots("Mail");

            InitMailData();
            reddotView.SubReddot("Mail");

            // var node = ReddotTree.Instance.SearchNode("Mail");
            // if(node.ReddotCnt > 0)
            // {
            //     reddotView.ReddotCallback(node);
            // }
        }

        void OnMailButtonClick()
        {
            for (int i = 0; i < 3; i++)
            {
                var tab = Instantiate(mailTab, Tab.transform.Find("Viewport/Content")).GetComponent<MailTab>();

                var index = i;

                tab.Init("Mail/Tab" + index);
                tab.GetComponent<Button>().onClick.AddListener(() => OnTabClick("Tab" + index));
            }

            OnTabClick("Tab0");
        }

        public void OnTabClick(string tabName)
        {
            var content = mailPanel.transform.Find("Viewport/Content");
            for (int i = 0; i < content.childCount; i++)
            {
                Destroy(content.GetChild(i).gameObject);
            }

            for (int i = 0; i < 5; i++)
            {
                var newMail = Instantiate(mailContent, mailPanel.transform.Find("Viewport/Content")).GetComponent<MailContent>();
                newMail.transform.SetAsLastSibling();

                var index= i;
                var path = "Mail/" + tabName + "/" + index;
                newMail.Init(path, tabName);
            }
        }

        /// <summary>
        /// 初始化红点数据
        /// </summary>
        public void InitMailData()
        {
            for (int i = 0; i < 3; i++)
            {
                var path = "Mail/Tab" + i;
                for (int j = 0; j < 5; j++)
                {
                    var mailPath = path + "/" + j;
                    ReddotTree.Instance.ChangeReddotCnt(mailPath, 1);
                }
            }
        }

        public void OnDestroy()
        {
            reddotView.UnSubReddot("Mail");
        }

    }

这是一个模拟邮件主面板的类,其初始化红点数据的方法写在了InitMailData中
在这里插入图片描述
这里直接使用了ChangeReddotCnt方法,在查找不到的时候直接设置红点结点数据,这个方法会在面板初始化的时候调用
在这里插入图片描述
可以看到,在数据初始化之后,此面板才注册了自身节点

在这里插入图片描述
注意在OnDestroy方法中需要注销对于红点UI的注册

具体结构如下
在这里插入图片描述
可以看到红点的UI默认是没有激活的

2. 邮件侧边栏

public class MailTab : MonoBehaviour
{
    public ReddotView reddotView;
    public string path;

    public void Init(string path)
    {
        reddotView.SubReddot(path);

        this.path = path;

        // var node = ReddotTree.Instance.SearchNode(path);
        // if(node.ReddotCnt > 0)
        // {
        //     reddotView.ReddotCallback(node);
        // }
    }

    public void OnDestroy()
    {
        reddotView.UnSubReddot(path);
    }
}

这里只需要在初始化的时候注册红点就行,因为红点数据已经在一开始初始化了,同时OnDestroy的时候需要取消注册
在这里插入图片描述

3. 邮件条目

public class MailContent : MonoBehaviour
    {
        public ReddotView reddotView;

        public Button contentButton; 

        public Button deleteButton;
        public string path;
        public Text contentText;

        public void Init(string path, string content)
        {
            this.path = path;
            reddotView.SubReddot(path);

            // var node = ReddotTree.Instance.SearchNode(path);
            // if(node.ReddotCnt > 0)
            // {
            //     reddotView.ReddotCallback(node);
            // }
            //ReddotTree.Instance.ChangeReddotCnt(path, 1);

            contentText.text = content;
        }

        void Awake()
        {
            contentButton.onClick.AddListener(OnContentButtonClick);
            deleteButton.onClick.AddListener(OnDeleteButtonClick);
        }

        public void OnContentButtonClick()
        {
            ReddotTree.Instance.ChangeReddotCnt(path, -1);
        }

        public void OnDeleteButtonClick()
        {
            ReddotTree.Instance.ChangeReddotCnt(path, -1);
            //ReddotTree.Instance.UnSubReddot(path);
            Destroy(gameObject);
        }

        void OnDestroy()
        {
            //ReddotTree.Instance.ChangeReddotCnt(path, -1);
            //ReddotTree.Instance.UnSubReddot(path);
            reddotView.UnSubReddot(path);
        }
    }

同样是在初始化时注册,销毁时注销
在这里插入图片描述

4. 效果

在这里插入图片描述

Unity红点系统是一种常用的游戏UI设计,主要用于提醒玩家当前有新的任务、奖励或其他未读信息需要处理。下面是一个简单的Unity红点系统设计: 1. 定义红点控件:在UI界面中添加一个红点控件,通常是一个小圆点或小数字。该控件需要有一个唯一的名称,用于后续的操作。 2. 定义红点数据结构:为每个需要红点提醒的功能定义一个红点数据结构,包含以下信息: - 功能名称:用于标识该功能。 - 红点控件名称:与UI界面中的红点控件名称对应。 - 是否需要红点提醒:标识该功能是否需要红点提醒。 - 红点数量:如果需要显示数字红点,则需要记录具体的数量。 3. 定义红点管理类:创建一个红点管理类,用于管理所有的红点数据和UI界面上的红点控件。该类需要提供以下功能: - 添加红点数据:向红点管理类中添加新的红点数据。 - 更新红点状态:根据红点数据中的信息,更新UI界面上对应的红点控件状态。 - 监听红点变化:提供回调函数,当某个红点数据的状态发生变化时,通知相应的UI界面进行更新。 4. 使用红点系统:在需要使用红点系统的地方,调用红点管理类的方法添加红点数据和监听红点变化。当红点数据的状态发生变化时,红点管理类会自动更新UI界面上的红点控件状态。 通过以上步骤,就可以实现一个简单的Unity红点系统。当玩家有新的任务或奖励时,红点控件会自动提醒玩家,增强了游戏的交互性和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值