[Unity]Unity红点逻辑

    在玩游戏的时候,尤其是手游的时候,经常会看到那些小红点,让你不断点进去,总有种逼死强迫症的感觉!从玩家的角度来说,很讨厌,其实程序员也比较讨厌的。虽然红点就2个状态,显示和不显示,但如果红点逻辑没写好,对性能的影响非常大。

    先简单来说几个原因:

1.读表

    没法避免的要素,几乎所有的红点逻辑都需要读表,这个就不说了。

2.监听事件太多

    举个简单的例子:商城上的红点,比如一个商品购买最基本的必须要有钱(游戏币),那就需要监听货币事件,有人物等级限制,需要监听人物等级事件,有vip限制,需要监听vip等级事件,有够买限制,需要监听商店事件等等。导致的结果就是有时候事件频发的时候执行了很多遍红点逻辑。一般的做法就是做延迟,到现在也没遇到什么好的解决方案。不知道有大神知道吗?

3.子页签

    其实一开始我认为要写红点逻辑一般会采用树结构,直到我看到了神一般大代码后,我服了!举个简单的例子:还是商店,主界面会有商店Icon,商店里有页签,页签里有很多商品,这些全部都是分开的,比如执行一大串红点逻辑后,显示商店Icon红点,再执行一大串几乎一样的逻辑后,显示页签红点,再执行一大串几乎一样的逻辑后,显示商品红点。这个我就不太多说了。

[Unity]Unity红点逻辑_第1张图片

    先来幅自己画的树结构,不错,符合程序美。树结构具体什么就不解释了,网上一堆,看数据结构也绕不过去。只要明白叶节点决定父节点,父节点的父节点,父节点的父节点的父节点。。。是否显示红点就好了,这应该很清楚了。

    直接上代码,因为项目是lua,所以红点也是lua写的,易于以后热更。

require "Manager/RedDotStateMgr"

local RedDot = {}
RedDot.__index = RedDot

function RedDot:New()
    local new_ins = {}
    setmetatable(new_ins, RedDot)
    new_ins.m_dotName = 0
    new_ins.m_bIsShow = false
    new_ins.m_childDotList = {}

    return new_ins
end

-- 从叶节点往根节点递归
function RedDot:GetIsShowRedDot()
    if  self.m_childDotList == nil or next(self.m_childDotList) == nil then
        return self.m_bIsShow
    end

    local bIsShow = false
    for childDotName, childDot in pairs(self.m_childDotList) do
        if childDot:GetIsShowRedDot() then
            bIsShow = true
            break
        end
    end
    return bIsShow
end

-- 获取红点数量
function RedDot:GetRedDotNum()
    if  self.m_childDotList == nil or #self.m_childDotList == 0 then
        return 0
    end

    local redDotNum = 0
    for childDotName, childDot in pairs(self.m_childDotList) do
        if childDot:GetIsShowRedDot() then
            redDotNum = redDotNum + 1
        end
    end
    return redDotNum
end

--刷新叶节点数据
function RedDot:UpdateLeafData(bIsShow)
    self.m_bIsShow = bIsShow
end

--获取子节点数据
function RedDot:GetChildDot(childDotName)
    return self.m_childDotList[childDotName]
end

--添加子节点数据
function RedDot:AddChildDot(childDotName, childDot)
    self.m_childDotList[childDotName] = childDot
end

RedDotMgr = {}
RedDotMgr.m_DotDataList = {}--红点数据
RedDotMgr.m_DotUIList = {}--红点UI

--设置红点状态,树结构
--childDotName:子节点,parentDotName:根节点
--bIsShow:只需要设置叶节点状态
function RedDotMgr:SetRedDotState(childDotName, parentDotName, bIsShow)
    local childDot = self:GetRedDot(childDotName)
    if bIsShow ~= nil then
        childDot:UpdateLeafData(bIsShow)
    end
    local parentDot = self:GetRedDot(parentDotName)
    if parentDot:GetChildDot(childDotName) == nil then
        parentDot:AddChildDot(childDotName, childDot)
    end
end

--显示红点(从池里取)
function RedDotMgr:ShowRedDotUI(dotName, parentTran, pos)
    if self:GetRedDotIsShow(dotName) then
        local redDotUI = self:GetRedDotUI(dotName, parentTran)
        if redDotUI == nil then
            self:CreateRedDotUI(dotName, parentTran, pos)
        end
    else
        self:RemoveRedDotUI(dotName)
    end
end

--删除红点(放回池里)
function RedDotMgr:RemoveRedDotUI(dotName)
    if self.m_DotUIList[dotName] ~= nil then
        // 放回池里
        self.m_DotUIList[dotName] = nil
    end
end

function RedDotMgr:GetRedDotUI(dotName)
    return self.m_DotUIList[dotName]
end

function RedDotMgr:CreateRedDotUI(dotName, parentTran, pos)
    //	动态创建红点GamObject
    //	再挂到parentTran节点下
end

function RedDotMgr:GetRedDot(dotName)
    if dotName == nil then return end
    if self.m_DotDataList[dotName] == nil then
        local tempDot = RedDot:New()
        self.m_DotDataList[dotName] = tempDot
    end

    return self.m_DotDataList[dotName]
end

--获取红点状态:true:显示  false:不显示
function RedDotMgr:GetRedDotIsShow(dotName)
    local dot = self:GetRedDot(dotName)
    return dot:GetIsShowRedDot()
end

--获取子节点红点数量
function RedDotMgr:GetChildRedDotNum(dotName)
    local dot = self:GetRedDot(dotName)
    return dot:GetRedDotNum()
end

    逻辑很简单就不解释了,具体使用就这样,也很简单

function UUpdateDotState()
    local isShow = false

    // 一系列判断

    RedDotMgr:SetRedDotState(叶节点, 子节点1, isShow)
    RedDotMgr:SetRedDotState(子节点1, 子节点2)
    //。。。
    RedDotMgr:SetRedDotState(子节点n, 根节点)
end

function UpdateRedDotUI()
    RedDotMgr:ShowRedDotUI(叶节点, 叶节点transform)
    RedDotMgr:ShowRedDotUI(子节点1, 子节点1transform)
    //。。。
    RedDotMgr:ShowRedDotUI(根节点, 根节点transform)
end

function UIHero:RemoveRedDotUI()
    RedDotMgr:RemoveRedDotUI(叶节点)
    RedDotMgr:RemoveRedDotUI(子节点1)
    //。。。
    RedDotMgr:RemoveRedDotUI(根节点)
end

你可能感兴趣的:(Unity)