红点基本上是游戏中必备的吧,红点遍地有,所以需要一套统一的红点系统来管理。
lua中判断Unity对象是否为空
--判断unity对象是否为空, 如果你有些对象是在c#删掉了,lua不知道
function IsNil(uobj)
if (uobj == nil) then
return true
end
if (uobj:Equals(nil)) then
return true
end
return false
end
红点注册
new_tip_register = {}
local this = new_tip_register
local LASTNUMBER = 99999
--红点枚举(第一步:注册红点枚举)
Enum_New = {
NEW_ALL = 999999, --遍历所有用
------------------------------------红点-----------------------------------
NEW_CHANGESTATE_MAIN = 1, --主界面右下角切换按钮
NEW_FACTION_MAIN = 2, --主界面帮会按钮(主界面帮会入口ID)
NEW_FACTION_MEMBER = 3, --帮会成员
NEW_FACTION_MAIN_RED_PACKET = 4, --帮会成员红包按钮
NEW_FACTION_MEMBER_RECRUIT = 5, --帮会成员招募按钮
NEW_FACTION_MEMBER_BUILDING = 6, --帮会建筑
NEW_FACTION_BUILD = 7, --帮会大厅
NEW_FACTION_BUILD_WEALFAREPANEL = 8, --帮会福利
NEW_FACTION_BUILD_SIGNE = 9, --帮会签到
NEW_FACTION_BUILD_WEALFAREBOX = 10, --福利宝箱
NEW_FACTION_BUILD_ACCOUNT = 11, --帮会建筑账房
NEW_FACTION_BUILD_ACCOUNT_WELFARE_ONE = 12, --帮会建筑福利
NEW_FACTION_BUILD_ACCOUNT_WELFARE_TWO = 13,
NEW_FACTION_MAIN_PANDECT = 14, --帮会总览
NEW_FACTION_LEVEL_UP = 15, --总览界面升级按钮
--帮会大厅下的升级按钮
NEW_FACTION_HALL_MAIN = 16, --帮会主厅(大厅)
NEW_FACTION_HALL_SHOP = 17, --帮会商店(大厅)
NEW_FACTION_HALL_BINGJIA = 18, --帮会兵甲(大厅)
NEW_FACTION_HALL_FANGJU = 19, --帮会防具(大厅)
NEW_FACTION_HALL_SHOUSHI = 20, --帮会首饰(大厅)
NEW_FACTION_HALL_SHOP_SELL = 21, --帮会商店物品上架
NEW_FACTION_BUILD_FACTIONSKILL = 22, --帮会技能
}
--[[--(第二步:注册红点枚举关系)
* @Description: 红点关系列表(主要控制根节点红点状态,父节点状态会根据子节点状态刷新)
]]
local EnumNewList = {
--主界面右下角切换按钮
[Enum_New.NEW_CHANGESTATE_MAIN] = {
--帮会
[Enum_New.NEW_FACTION_MAIN] = {
[Enum_New.NEW_FACTION_MAIN_PANDECT] = --总览
{
[Enum_New.NEW_FACTION_LEVEL_UP] = LASTNUMBER, --升级
},
[Enum_New.NEW_FACTION_MEMBER] = { --成员
[Enum_New.NEW_FACTION_MEMBER_RECRUIT] = LASTNUMBER, --招募
[Enum_New.NEW_FACTION_MAIN_RED_PACKET] = LASTNUMBER, --红包
},
[Enum_New.NEW_FACTION_MEMBER_BUILDING] = { --建筑
[Enum_New.NEW_FACTION_BUILD] = { --大厅
[Enum_New.NEW_FACTION_HALL_MAIN] = LASTNUMBER,
[Enum_New.NEW_FACTION_HALL_SHOP] = LASTNUMBER,
[Enum_New.NEW_FACTION_HALL_BINGJIA] = LASTNUMBER,
[Enum_New.NEW_FACTION_HALL_FANGJU] = LASTNUMBER,
[Enum_New.NEW_FACTION_HALL_SHOUSHI] = LASTNUMBER,
},
[Enum_New.NEW_FACTION_BUILD_ACCOUNT] = { --账房
[Enum_New.NEW_FACTION_BUILD_ACCOUNT_WELFARE_ONE] = LASTNUMBER,
},
[Enum_New.NEW_FACTION_HALL_SHOP_SELL] = LASTNUMBER,
},
[Enum_New.NEW_FACTION_BUILD_WEALFAREPANEL] = { --福利
[Enum_New.NEW_FACTION_BUILD_SIGNE] = LASTNUMBER, --签到
[Enum_New.NEW_FACTION_BUILD_FACTIONSKILL] = LASTNUMBER, --帮会技能
[Enum_New.NEW_FACTION_BUILD_WEALFAREBOX] = --宝箱
{
[Enum_New.NEW_FACTION_BUILD_ACCOUNT_WELFARE_TWO] = LASTNUMBER,
},
},
},
}
}
---------------外调-----------------
--获得红点枚举树结构
function this.GetEnumNewList()
return EnumNewList
end
----------------------------------
红点系统
--第一步:红点枚举
--new_tip_register
--第二步:绑定红点显示节点
--new_tip_register
require "logic/common/new_tip_register"
new_tip_system = {}
local this = new_tip_system
--变量声明
local newInfoList = nil
local LASTNUMBER = 99999
--内部方法声明
local InitNewTable = nil
local FreshAllRootNewState = nil
local SetActiveNew = nil
local RefreshCharacterAttr = nil
local SetOrGetStateEnum = nil
local PrintTrueLeaf = nil
local GetSubTree = nil
local curHeroLevel = nil
local EnumNewList = nil
---------------外调开始-----------
function new_tip_system.Init()
EnumNewList = {}
EnumNewList = new_tip_register.GetEnumNewList()
newInfoList = {}
InitNewTable(EnumNewList)
Notifier.regist(cmdName.MSG_REFRESH_CHARACTER_ATTR,RefreshCharacterAttr)
end
function new_tip_system.UnInit()
newInfoList = nil
EnumNewList = nil
Notifier.remove(cmdName.MSG_REFRESH_CHARACTER_ATTR,RefreshCharacterAttr)
end
--[[--(第三步:注册刷新红点状态或gameobject)
* @Description: 注册红点状态 注意:父节点只需要设置gameobject,如果设置了状态也会被根节点状态改变掉
@isActive 是否显示(可为空)
@objNew 红点GameObject(可为空)
@level 等级限制入口(比如入口等级,如果有等级限制Gameobject显影的时候设置等级,没有不设置)
]]
function new_tip_system.RegisterNewState(enumNew,isActive,objNew,level)
-- Trace("RegisterNewState:"..tostring(enumNew).." newInfoList:"..tostring(objNew).." isActive:"..tostring(isActive))
if curHeroLevel == nil then
curHeroLevel = data_center.GetPlayerUintValue(U_ACTOR_BASE_GRADE_ATTR)
end
if newInfoList ~= nil and newInfoList[enumNew] ~= nil then
local isNeedFresh = false
if isActive ~= nil then
if newInfoList[enumNew].state ~= isActive then
SetOrGetStateEnum(enumNew,isActive)
isNeedFresh = true
end
end
if not IsNil(objNew) then
newInfoList[enumNew].objNew = objNew
newInfoList[enumNew].widgetNew = componentGet(objNew.transform,typeof(UIWidget))
end
if level ~= nil then
newInfoList[enumNew].level = level
isNeedFresh = true
end
if isNeedFresh then
FreshAllRootNewState(EnumNewList,enumNew)
Notifier.dispatchCmd(cmdName.MSG_NEW_TIP_CHANGE,enumNew)
end
SetActiveNew(enumNew,SetOrGetStateEnum(enumNew))
end
end
function new_tip_system.RemoveRegisterNewState(enumNew)
if newInfoList[enumNew] ~= nil then
SetActiveNew(enumNew,false)
newInfoList[enumNew].objNew = nil
newInfoList[enumNew].widgetNew = nil
end
end
--[[--
* @Description: 获取红点状态
]]
function new_tip_system.GetNewState(enumNew)
if not table.IsNullOrEmpty(newInfoList) and not table.IsNullOrEmpty(newInfoList[enumNew]) then
return newInfoList[enumNew].state
end
return false
end
--[[--
* @Description: 打印使所给节点为true的叶节点
]]
function new_tip_system.PrintTreeTrueLeaf(enumNew)
local subTree = GetSubTree(EnumNewList,enumNew)
if subTree == nil then
Trace(string.format("节点%s不存在",enumNew))
elseif SetOrGetStateEnum(enumNew) ~= true then
Trace(string.format("节点%s不为true",enumNew))
elseif subTree == LASTNUMBER then
Trace(string.format("节点%s为叶节点",enumNew))
elseif subTree ~= LASTNUMBER then
Trace("被查找的中间节点:"..tostring(enumNew))
PrintTrueLeaf(subTree)
end
end
---------------外调结束-----------
---------------内部函数开始-----------
function InitNewTable(newList)
for k,v in pairs(newList) do
local newItem = {}
newItem.objNew = nil
newItem.state = false
newInfoList[k] = newItem
if v ~= LASTNUMBER then
InitNewTable(v)
end
end
end
--[[--
* @Description: 刷新变更子节点所有父节点红点的状态
@newList:关系列表
@enumNew:变更红点枚举
]]
function FreshAllRootNewState(newList,enumNew)
-- Trace("FreshAllRootNewState--------------:"..tostring(enumNew))
local result = false
local enumNewTarget = nil
for k,v in pairs(newList) do
local active = false
local target = nil
if v ~= LASTNUMBER then
if k ~= enumNew then
local tmpTarget = nil
active,tmpTarget = FreshAllRootNewState(v,enumNew)
active = SetOrGetStateEnum(k,active)
if tmpTarget ~= nil then
target = k
--刷新目标父节点状态
SetActiveNew(k,active)
end
else
active = SetOrGetStateEnum(k)
target = k
end
else
active = SetOrGetStateEnum(k)
if k == enumNew then
target = k
end
end
if enumNew == Enum_New.NEW_ALL then
SetActiveNew(k,active)
end
--优化:减少搜索次数 找到变更节点并且result为true可以直接break(结果已知不用向下查找)
if active then
result = true
if enumNewTarget ~= nil then
break
end
end
if target ~= nil then
enumNewTarget = target
if result then
break
end
end
end
return result,enumNewTarget
end
function SetActiveNew(typeEnum,isActive)
if not IsNil(newInfoList[typeEnum].objNew) then
newInfoList[typeEnum].objNew:SetActive(isActive)
end
end
--[[--
* @Description: 设置或获取红点状态(并根据等级返回最终状态,实际状态还保存)
]]
function SetOrGetStateEnum(typeEnum,state)
if state ~= nil then
newInfoList[typeEnum].state = state
else
state = newInfoList[typeEnum].state
end
if newInfoList[typeEnum].level ~= nil and newInfoList[typeEnum].level > curHeroLevel then
state = false
end
return state
end
--[[--
* @Description: 玩家等级改变刷新红点入口
]]
function RefreshCharacterAttr(param)
if param ~= nil then
for k,v in pairs(param) do
if k == U_ACTOR_BASE_GRADE_ATTR then
curHeroLevel = data_center.GetPlayerUintValue(U_ACTOR_BASE_GRADE_ATTR)
FreshAllRootNewState(EnumNewList,Enum_New.NEW_ALL)
break
end
end
end
end
--[[--
* @Description: 获得对应节点的子树
]]
function GetSubTree(newList,enumNew)
for k,v in pairs(newList) do
if k == enumNew then
return v
elseif v ~= LASTNUMBER then
local ret = GetSubTree(v,enumNew)
if ret ~= nil then
return ret
end
end
end
end
--[[--
* @Description: 打印状态为true的叶节点
]]
function PrintTrueLeaf(newList)
for k,v in pairs(newList) do
if v ~= LASTNUMBER then
PrintTrueLeaf(v)
else
if SetOrGetStateEnum(k) == true then
Trace("为true的叶节点:"..tostring(k))
end
end
end
end
说明和使用
使用时需要注意Enum_New中的数值是唯一的,不要重复了,不然可能会导致子节点的红点状态变更了,但父节点的没得到相应的刷新。
使用时调用new_tip_system.RegisterNewState(enumNew,isActive,objNew,level)即可,父节点的状态会随着子节点的状态的改变而改变。