基于Unity的红点系统通用框架

在现代游戏开发中,红点提示系统是一种常见且有效的用户交互方式,能够及时提示玩家需要关注的内容。本文将介绍一个基于Unity的红点系统通用框架的实现,并提出一些优化建议,以提高代码的性能和可维护性。

框架设计概述

该红点系统框架主要由三个核心部分组成:

  1. RedNode 类:表示红点的节点,每个节点可以有子节点和父节点。
  2. IRedPoint 接口:定义了红点节点的基本行为。
  3. RedManager 类:管理所有的红点节点,提供节点的注册和管理功能。
RedNode 类

RedNode 类实现了 IRedPoint 接口,包含以下主要成员:

  • redType:节点类型(主节点或子节点)。
  • MountObject:该节点挂载的游戏对象。
  • Children:子节点列表。
  • UpdateEvents:节点状态更新事件。
  • hasRedPointcachedHasRedPoint:当前节点是否有红点及其缓存状态。
  • parent:父节点引用。

节点的红点状态通过 GetSetHasRedPoint 属性进行管理,该属性会触发红点状态的更新和事件通知。

RedManager 类

RedManager 类负责管理红点节点,包含以下主要功能:

  • MasterNode:主节点字典。
  • objectToNodeMap:游戏对象与红点节点的映射。
  • AddMasterNode:添加主节点和子节点。
  • ClickToRefreshTheEvent:处理红点点击事件,刷新红点状态。
  • RegisterNode:注册红点节点。
public enum RedType
{
    MasterNode,
    SecondaryNode,
}

public interface IRedPoint
{
    bool HasRedPoint();
}

public class RedNode : IRedPoint
{
    public RedType redType;
    public GameObject MountObject;
    public List<RedNode> Children { get; private set; } = new List<RedNode>();
    public UnityEngine.Events.UnityAction UpdateEvents;

    private bool hasRedPoint;
    private bool cachedHasRedPoint;
    private RedNode parent;

    public bool GetSetHasRedPoint
    {
        get => hasRedPoint;
        set
        {
            if (Children.Count > 0)
                return;
            if (hasRedPoint != value)
            {
                hasRedPoint = value;
                OnRedPointChanged();
            }
        }
    }

    public bool CachedHasRedPoint
    {
        get => cachedHasRedPoint;
        private set
        {
            if (cachedHasRedPoint != value)
            {
                cachedHasRedPoint = value;
                UpdateRedPointState();
            }
        }
    }

    public RedNode(RedType type, GameObject mountObject)
    {
        redType = type;
        MountObject = mountObject;
    }

    public void SetRedPoint(bool hasRedPoint)
    {
        this.hasRedPoint = hasRedPoint;
    }

    private void OnRedPointChanged()
    {      
        UpdateEvents?.Invoke();
        parent?.OnChildRedPointChanged();
        UpdateRedPointState();
    }

    private void OnChildRedPointChanged()
    {
        UpdateRedPointState();
        //UpdateCachedRedPointState();
        UpdateEvents?.Invoke();
        parent?.OnChildRedPointChanged();
    }


    private void UpdateRedPointState()
    {
        if (MountObject != null)
        {
            Transform Red = MountObject.transform.Find("red");// SendMessage("SetRedPointActive", CachedHasRedPoint);
            Text text = MountObject.transform.Find("count").GetComponent<Text>();
            Red.gameObject.SetActive(Children.Count > 0);
            text.text = Children.Count.ToString();
        }        
        //foreach (var child in Children)
        //{
        //    child.UpdateRedPointState();
        //}
    }

    public void AddChild(RedNode child)
    {
        if (child != null && !Children.Contains(child))
        {
            Children.Add(child);
            child.parent = this;
            child.UpdateRedPointState();
            child.parent.UpdateRedPointState();
        }
    }

    public bool HasRedPoint()
    {
        return CachedHasRedPoint;
    }
}

public class RedManager
{
    public Dictionary<string, RedNode> MasterNode { get; private set; }
    //创建一个缓存池子 便于查找
    public Dictionary<GameObject, RedNode> objectToNodeMap { get; private set; }
    public RedManager()
    {
        MasterNode = new Dictionary<string, RedNode>();
    }
    public void AddMasterNode(GameObject obj,GameObject parentNode) 
    {
        if (objectToNodeMap.ContainsKey(obj)) return;
        RedNode ParentNode = objectToNodeMap.ContainsKey(parentNode) ? objectToNodeMap[parentNode]: null;                    
        RedType Redtype = ParentNode==null ? RedType.MasterNode : RedType.SecondaryNode;
        RedNode Node = new RedNode(Redtype, obj);
        if (ParentNode==null)        
            MasterNode.Add(obj.name, Node);        
        else         
            ParentNode.AddChild(Node);
        RegisterNode(Node);
    }

    public void ClickToRefreshTheEvent(GameObject obj ) 
    {
        RedNode ParentNode;
        if (!objectToNodeMap.TryGetValue(obj, out ParentNode))
            Debug.LogError("Node not registered in the red point system");
        else
            ParentNode.GetSetHasRedPoint = false;
    }
    public void RegisterNode(RedNode node) 
    {
        if (!objectToNodeMap.ContainsKey(node.MountObject))
            objectToNodeMap.Add(node.MountObject, node);
        //for (int i = 0; i < node.Children.Count; i++)
        //{
        //    RegisterNode(node.Children[i]);
        //}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值