c1_lua/lua/app/ui/ui_manager.lua
2023-08-01 18:20:35 +08:00

1289 lines
35 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local UIManager = {}
local MESSAGE_BOX_PATH = "assets/prefabs/ui/common/message_box.prefab"
local TUTORIAL_PATH = "assets/prefabs/ui/tutorial/tutorial_ui.prefab"
UIManager.UI_TYPE = {
DEFAULT = 0,
MULTI = 1, -- 非唯一界面,此类型界面同一时间可以打开多个
MAIN = 2, -- 主要的界面,打开此界面的时候会关闭所有其他界面
}
UIManager.MESSAGE_BOX_TAG = {
BATTLE_SKIP = 1,
LOGIN_FAIL = 2
}
-- 个别uipath不同模块需要使用统一写到一个地方避免后期要改的话改漏了
UIManager.UI_PATH = {
GM_TOO_UI = "app/ui/gm/gm_tool_ui",
MAINCITY_UI = "app/ui/main_city/main_city_ui",
BATTLE_UI = "app/ui/battle/battle_ui",
ROGUE_SKILL_UI = "app/ui/battle/battle_skill_select_ui",
REWARD_BOX = "app/ui/tips/reward_box",
HERO_DETAIL_UI = "app/ui/hero/hero_detail_ui",
ARENA_MATCH_UI = "app/ui/arena/arena_match_ui",
BATTLE_PVP_UI = "app/ui/battle/battle_ui_pvp",
}
-- 动画类型
UIManager.ANI_TYPE = {
POP = 1, -- 弹出
NONE = 2, -- 无动画
}
-- loading类型
UIManager.LOADING_TYPE = {
BLACK = 1,
CLOUD = 2
}
-- ui缓存上限
local UI_CACHE_SIZE = 5
-- 根据以往项目的经验提前申请一个值,避免动态扩容导致的开销,可根据项目实际情况调整
local MAIN_CANVAS_HIERARCHY_CAPACITY = 20480
local MAIN_CANVAS_ORDER = 1000
local UI_INTERVAL_ORDER = 400
local UI_MAX_ORDER = 28000
local UI_BARS_UNDER_ORDER = 2
local CLICK_EFFECT = 31000
local OTHER_CANVAS_INTERVAL_ORDER = {
TOAST = 1,
TUTORIAL = 2,
NET = 3,
LOADING = 4,
SWALLOW_TOUCH = 5,
MESSAGE_BOX_TOP = 6,
LOADING_TOP = 7,
-- 这里要注意一下不要超过sortingOrder的最大值32767,目前UI_MAX_ORDER + UI_INTERVAL_ORDER * LOADING_TOP:28000 + 400 * 7 = 30800 小于 32767
}
function UIManager:init(callback)
if self.uiRoot and CS.BF.Utils.IsNull(self.uiRoot:getGameObject()) then
return
end
self.uiList = {}
self.loadingUI = {}
self.uiCacheList = {}
self.uiLoadedListeners = {}
self.disableTouchCount = 0
self.waitNetCount = 0
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/ui_root.prefab", nil, function(uiRoot)
self.uiRoot = uiRoot
CS.UnityEngine.GameObject.DontDestroyOnLoad(uiRoot:getGameObject())
local uiMap = uiRoot:genAllChildren()
self.uiCamera = uiMap["ui_root.ui_camera"]
self.mainCanvas = uiMap["ui_root.main_canvas"]
self.mainCanvas:getTransform().hierarchyCapacity = MAIN_CANVAS_HIERARCHY_CAPACITY
self.currencyRoot = uiMap["ui_root.main_canvas.currency_root"]
self:_loadCurrencyBar()
self.currencyCanvas = self.currencyRoot:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS)
self.swallowUITouches = uiMap["ui_root.main_canvas.swallow_ui_touches"]
self.swallowUITouchesCanvas = self.swallowUITouches:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS)
self.toastCanvas = uiMap["ui_root.toast_canvas"]
self.toastCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.TOAST
self.toastNode = uiMap["ui_root.toast_canvas.toast"]
self.messageBoxNode = uiMap["ui_root.toast_canvas.messagebox"]
self.netCanvas = uiMap["ui_root.net_canvas"]
local netCanvasOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.NET
self.netCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = netCanvasOrder
self.netCanvas:setActive(false)
self.tutorialCanvas = uiMap["ui_root.tutorial_canvas"]
self.tutorialCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.TUTORIAL
self.loadingCanvas = uiMap["ui_root.loading_canvas"]
self.blackLoadingImg = uiMap["ui_root.loading_canvas.black"]
self.swallowTouchesCanvas = uiMap["ui_root.swallow_touches_canvas"]
self.swallowTouchesCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
self.swallowTouchesCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.SWALLOW_TOUCH
-- ui预制件pool节点
self.uiPrefabPoolNode = uiMap["ui_root.ui_prefab_pool"]
callback()
end)
end
function UIManager:showUI(uiPath, params)
if self.uiRoot == nil then
return
end
local uiObj = self:checkOpen(uiPath)
if uiObj then
return uiObj
end
uiObj = require(uiPath):create(params)
uiObj:setUIIndex(uiPath)
uiObj:_recordParams(params)
local topUISiblingIndex
local topUI = self.uiList[#self.uiList]
if topUI then
topUISiblingIndex = topUI:getSiblingIndex() + 1
topUI:_onCover()
else
topUISiblingIndex = 1
end
table.insert(self.uiList, uiObj)
self:setUIOrder(uiObj, topUISiblingIndex)
local aniType = self:getAniType(uiObj)
if aniType then
self:_setUISwallowOrder(topUISiblingIndex + 1)
self.swallowUITouches:getGameObject():SetActive(true)
else
self:_updateUISwallowOrder()
end
uiObj:_onCreate()
local bgm = uiObj:getBGMId()
if bgm then
self:playBGM(bgm)
end
Logger.logHighlight("Show UI:%s", uiPath)
-- 上报打开界面事件
BIReport:postOpenUI(uiObj:getPrefabPath())
return uiObj
end
function UIManager:closeUI(uiObj)
local uiNum = #self.uiList
local removeIndex = 0
for i = uiNum, 1, -1 do
if uiObj == self.uiList[i] then
removeIndex = i
break
end
end
if removeIndex <= 0 then
Logger.log(uiObj:getUIIndex(), " is not open")
return
end
if removeIndex == uiNum then -- 需要关闭的界面在最上层
uiNum = uiNum - 1
if uiNum > 0 then
local topUI = self.uiList[uiNum]
topUI:_onReshow()
local aniType = self:getAniType(uiObj)
if aniType and aniType ~= UIManager.ANI_TYPE.POP and
aniType ~= UIManager.ANI_TYPE.NONE then
if removeIndex > 0 then
table.remove(self.uiList, removeIndex)
end
self:_setUISwallowOrder(uiObj:getSiblingIndex() + 1)
self.swallowUITouches:getGameObject():SetActive(true)
uiObj:_playExitAnimation()
else
if removeIndex > 0 then
table.remove(self.uiList, removeIndex)
end
uiObj:_onExitAnimationComplete()
self:_updateUISwallowOrder()
end
local bgm = topUI:getBGMId()
if bgm then
self:playBGM(bgm)
elseif uiObj:getBGMId() then
local openedUINum = uiNum
while openedUINum > 1 do
openedUINum = openedUINum - 1
bgm = self.uiList[openedUINum]:getBGMId()
if bgm then
self:playBGM(bgm)
break
end
end
end
else
uiObj:_onExitAnimationComplete()
end
else
if removeIndex > 0 then
table.remove(self.uiList, removeIndex)
end
uiObj:_onExitAnimationComplete()
if uiObj:isFullScreen() and uiObj:isVisible() then
local curIndex = removeIndex - 1
local currObj = nil
while curIndex >= 1 do
currObj = self.uiList[curIndex]
currObj:_setVisible(true)
self:setBarsVisible(currObj, true)
if currObj:isFullScreen() then
break
end
curIndex = curIndex - 1
end
end
end
uiObj:_onClose()
end
function UIManager:checkOpen(uiPath)
local uiNum = #self.uiList
if uiNum > 0 then
for i = uiNum, 1, -1 do
if self.uiList[i]:getUIIndex() == uiPath then
-- 如果这个界面可以打开多个
if self.uiList[i]:getUIType() == UIManager.UI_TYPE.MULTI then
return nil
end
if i < uiNum then -- 如果这个界面已经打开,并且不是最顶层
local reshowUI
if self.uiList[i]:getUIType() == UIManager.UI_TYPE.MAIN then
-- 关闭此界面之上所有界面
for j = uiNum, i + 1, -1 do
local closeUIObj = table.remove(self.uiList, j)
closeUIObj:_onClose()
closeUIObj:_onExitAnimationComplete()
end
reshowUI = self.uiList[i]
else
-- 将此界面放到所有界面的最顶层
local topUI = self.uiList[uiNum]
local siblingIndex = topUI:getSiblingIndex() + 1
topUI:_onCover()
reshowUI = table.remove(self.uiList, i)
table.insert(self.uiList, reshowUI)
self:setUIOrder(reshowUI, siblingIndex)
end
self:_updateUISwallowOrder()
reshowUI:_onReshow()
local bgm = reshowUI:getBGMId()
if bgm then
self:playBGM(bgm)
end
return reshowUI
end
return self.uiList[i]
end
end
end
return nil
end
function UIManager:getUIPrefab(path, callback)
for k, prefabObj in ipairs(self.uiCacheList) do
if prefabObj:getAssetPath() == path then
prefabObj:setParent(self.mainCanvas, false)
table.remove(self.uiCacheList, k)
return callback(prefabObj)
end
end
UIPrefabManager:loadUIWidgetAsync(path, self.mainCanvas, callback)
end
function UIManager:clearUIPrefabCache()
for i = 1,#self.uiCacheList do
table.remove(self.uiCacheList):destroy()
end
end
function UIManager:putbackUIPrefab(prefabObj)
prefabObj:setParent(self.uiPrefabPoolNode, false)
if #self.uiCacheList >= UI_CACHE_SIZE then -- 缓存的ui prefab已经超上限了
local head = table.remove(self.uiCacheList, 1)
head:destroy()
end
table.insert(self.uiCacheList, prefabObj)
end
function UIManager:setUIOrder(uiObj, siblingIndex)
local order = MAIN_CANVAS_ORDER + siblingIndex * UI_INTERVAL_ORDER
if order < UI_MAX_ORDER then
uiObj:setUIOrder(siblingIndex, order)
else -- 超过最大值了,全部界面重新设置一下order
for i, obj in ipairs(self.uiList) do
order = MAIN_CANVAS_ORDER + i * UI_INTERVAL_ORDER
obj:setUIOrder(i, order)
end
if self.currencyBarBindUI then
local sortingOrder = self.currencyBarBindUI:getUIOrder()
self.currencyCanvas.sortingOrder = sortingOrder + UI_INTERVAL_ORDER - UI_BARS_UNDER_ORDER
end
self:_updateUISwallowOrder()
end
end
function UIManager:setBarsVisible(uiObj, visible)
if self.currencyBarBindUI == uiObj then
if self.currencyBar then
self.currencyBar:setVisible(visible)
end
end
end
function UIManager:updateBarsState(uiObj)
if self.currencyBarBindUI == uiObj then
self:showCurrencyBar(uiObj)
end
end
function UIManager:hideBehindUI(uiObj)
local findIndex = 0
for i = #self.uiList, 1, -1 do
if uiObj == self.uiList[i] then
findIndex = i
break
end
end
local curIndex = findIndex - 1
local currObj = nil
while curIndex >= 1 do
currObj = self.uiList[curIndex]
if currObj:isVisible() == false then
break
end
currObj:_setVisible(false)
self:setBarsVisible(currObj, false)
curIndex = curIndex - 1
end
end
function UIManager:showBehindUI(uiObj)
local findIndex = 0
for i = #self.uiList, 1, -1 do
if uiObj == self.uiList[i] then
findIndex = i
break
end
end
local curIndex = findIndex - 1
local currObj = nil
while curIndex >= 1 do
currObj = self.uiList[curIndex]
currObj:_setVisible(true)
self:setBarsVisible(currObj, true)
if currObj:isFullScreen() then
break
end
curIndex = curIndex - 1
end
end
function UIManager:getUIByIndex(index)
for k, v in ipairs(self.uiList) do
if v:getUIIndex() == index then
return v
end
end
return nil
end
-- 获取引导UI
function UIManager:getTutorial(callback)
if self.tutorial == nil then
UIPrefabManager:loadUIWidgetAsync(TUTORIAL_PATH, self.tutorialCanvas, function (prefabObject)
if self.tutorial then
prefabObject:destroy()
return
end
self.tutorial = prefabObject
if callback then
callback(prefabObject)
end
end)
else
self.tutorial:setActive(true)
if callback then
callback(self.tutorial)
end
end
end
-- 显示引导节点
function UIManager:showTutorial()
self.tutorialCanvas:setActive(true)
end
-- 隐藏引导节点
function UIManager:hideTutorial()
self.tutorialCanvas:setActive(false)
end
function UIManager:getBlackLoadingImg()
return self.blackLoadingImg
end
function UIManager:showLoading(loadingType, callback)
self:disableTouch()
self.loadingCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = true
self.loadingCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.LOADING
loadingType = loadingType or UIManager.LOADING_TYPE.BLACK
if self.currLoadingType == nil then
self.currLoadingType = loadingType
end
ModuleManager.LoadingManager:showLoading(loadingType, self.loadingCanvas, callback)
end
function UIManager:closeLoading(callback)
if self.currLoadingType == nil then
self.loadingCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
if callback then
callback()
end
return false
end
ModuleManager.LoadingManager:closeLoading(self.currLoadingType, function ()
self:onLoadingUICompletelyClosed()
if callback then
callback()
end
end)
self.currLoadingType = nil
return true
end
function UIManager:onLoadingUICompletelyClosed()
self:enableTouch()
self.loadingCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
function UIManager:closeAllUI()
local uiNum = #self.uiList
for i = uiNum, 1, -1 do
self.uiList[i]:_onClose()
self.uiList[i]:_onExitAnimationComplete()
end
self.uiList = {}
self.currencyBarBindUI = nil
if self.currencyBar then
self.currencyBar:setVisible(false)
end
end
function UIManager:closeAllUIExceptMainUI(includeCurrencyBar)
local uiNum = #self.uiList
for i = uiNum, 1, -1 do
if self.uiList[i]:getUIIndex() ~= UIManager.UI_PATH.MAINCITY_UI then
self.uiList[i]:_onClose()
self.uiList[i]:_onExitAnimationComplete()
table.remove(self.uiList, i)
end
end
if includeCurrencyBar and self.currencyBar then
self.currencyBarBindUI = nil
self.currencyBar:setVisible(false)
end
end
function UIManager:hideMainUIExceptBattle()
local uiObj = UIManager:getUIByIndex(UIManager.UI_PATH.MAINCITY_UI)
if uiObj and uiObj:getIsLoadedComplete() then
uiObj:hideMainUIExceptBattle()
end
end
function UIManager:showMainUIExceptBattle()
local uiObj = UIManager:getUIByIndex(UIManager.UI_PATH.MAINCITY_UI)
if uiObj and uiObj:getIsLoadedComplete() then
uiObj:showMainUIExceptBattle()
end
end
-- 测试专用,有隐患,正常逻辑不要直接使用
function UIManager:reshowAllUI()
if DEBUG and EDITOR_MODE then
local reshowList = {}
for k, v in ipairs(self.uiList) do
reshowList[k] = v
end
self:closeAllUI()
for i = 1, #reshowList do
local params = reshowList[i]:_getRecordParams()
if params and type(params) == "table" then
params.aniType = nil
end
self:showUI(reshowList[i]:getUIIndex(), params)
end
end
end
function UIManager:closeBehindUI(uiObj)
local closeFlag = false
for i = #self.uiList, 1, -1 do
local curUIObj = self.uiList[i]
if closeFlag then
table.remove(self.uiList, i)
curUIObj:_onClose()
curUIObj:_onExitAnimationComplete()
else
if curUIObj == uiObj then
closeFlag = true
end
end
end
if closeFlag then
self:_updateUISwallowOrder()
end
end
function UIManager:closeUnderUI(uiObj)
local closeFlag = false
for i = 1, #self.uiList do
local curUIObj = self.uiList[i]
if curUIObj == uiObj then
for j = #self.uiList, i + 1, -1 do
curUIObj = self.uiList[j]
table.remove(self.uiList, j)
curUIObj:_onClose()
curUIObj:_onExitAnimationComplete()
closeFlag = true
end
break
end
end
if closeFlag then
uiObj:_onReshow()
self:_updateUISwallowOrder()
end
end
function UIManager:onUILoadedComplete(uiObj)
local callback = self.uiLoadedListeners[uiObj:getUIIndex()]
if callback then
self.uiLoadedListeners[uiObj:getUIIndex()] = nil
callback()
end
end
function UIManager:onUIClosedComplete(uiObj)
self:updateBarsWhenCloseUI(uiObj)
if self.uiLoadedListeners[uiObj:getUIIndex()] then
self.uiLoadedListeners[uiObj:getUIIndex()] = nil
end
end
function UIManager:addLoadUICompleteListener(uiIndex, callback)
local uiObj = self:getUIByIndex(uiIndex)
if uiObj and uiObj._baseLoadComplete then
callback()
else
self.uiLoadedListeners[uiIndex] = callback
end
end
function UIManager:getMessageBox(top, callback)
if top then
if self.topMsgBox == nil then
UIPrefabManager:loadUIWidgetAsync(MESSAGE_BOX_PATH, self.messageBoxNode, function (prefabObject)
if self.topMsgBox then
prefabObject:destroy()
callback(self.topMsgBox)
return
end
prefabObject:initPrefabHelper()
prefabObject:getTransform():SetAsLastSibling()
local messageBoxCanvas = prefabObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS)
local messageBoxCanvasOrder = UI_MAX_ORDER + UI_INTERVAL_ORDER*OTHER_CANVAS_INTERVAL_ORDER.MESSAGE_BOX_TOP
messageBoxCanvas.overrideSorting = true
messageBoxCanvas.sortingOrder = messageBoxCanvasOrder
self.topMsgBox = prefabObject
callback(prefabObject)
end)
else
self.topMsgBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = true
callback(self.topMsgBox)
end
else
if self.messageBox == nil then
UIPrefabManager:loadUIWidgetAsync(MESSAGE_BOX_PATH, self.messageBoxNode, function (prefabObject)
if self.messageBox then
prefabObject:destroy()
callback(self.messageBox)
return
end
prefabObject:initPrefabHelper()
self.messageBox = prefabObject
callback(prefabObject)
end)
else
self.messageBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = true
callback(self.messageBox)
end
end
end
function UIManager:getMessageBoxGameObject(top)
if top then
return self.topMsgBox
else
return self.messageBox
end
end
function UIManager:getMessageBoxCanvas()
return self.messageBoxNode:getTransform()
end
function UIManager:hideMessageBox()
if self.messageBox then
self.messageBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
end
function UIManager:hideMessageBoxByTag(tag)
if self.messageBox then
if self.messageBox:getTag() == tag then
self.messageBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
end
if self.topMsgBox then
if self.topMsgBox:getTag() == tag then
self.topMsgBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
end
end
function UIManager:getToast(callback)
if not self.toastPool then
self.toastPool = {}
end
local toast
for _, toastObj in ipairs(self.toastPool) do
if not toastObj._using then
toast = toastObj
end
end
if toast == nil then
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/toast.prefab", self.toastNode, function (_prefabObject)
_prefabObject:initPrefabHelper()
table.insert(self.toastPool, _prefabObject)
callback(_prefabObject)
end)
else
callback(toast)
end
end
function UIManager:getTaskToast(callback)
if self.taskToast == nil then
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/task_toast.prefab", self.toastNode, function (_prefabObject)
_prefabObject:initPrefabHelper()
self.taskToast = _prefabObject
callback(_prefabObject)
end)
else
callback(self.taskToast)
end
end
function UIManager:getAllToast()
return self.toastPool
end
function UIManager:hideToast()
if self.toastPool then
ModuleManager.ToastManager:clear()
for i, toastObj in ipairs(self.toastPool) do
if toastObj._toastSequence then
toastObj._toastSequence:Kill()
toastObj._toastSequence = nil
end
toastObj._using = false
toastObj:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
end
if self.taskToast then
ModuleManager.ToastManager:clear()
end
end
function UIManager:showUpdateToast(msgData)
local ts = msgData.ts // 1000
GFunc.showUpdateToast(ts - Time:getServerTime())
end
function UIManager:getRollToast(callback)
if not self.rollToast then
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/roll_toast.prefab", self.toastNode, function (_prefabObject)
if self.rollToast then
_prefabObject:destroy()
return
end
_prefabObject:initPrefabHelper()
self.rollToast = _prefabObject
callback(_prefabObject)
end)
else
callback(self.rollToast)
end
end
---- 回到登录界面时 killseq为true
function UIManager:hideRollToast(killSeq)
if not self.rollToast then
return
end
if killSeq and self.rollToast._toastSequence then
self.rollToast._toastSequence:Kill()
self.rollToast._toastSequence = nil
end
ModuleManager.RollToastManager:clear(not killSeq)
self.rollToast:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
function UIManager:hideToastAndMessageBox()
self:hideToast()
self:hideRollToast()
end
function UIManager:getMainCanvasTransform()
return self.mainCanvas:getTransform()
end
function UIManager:getMainCanvas()
return self.mainCanvas
end
function UIManager:getUICameraComponent()
return self.uiCamera:getComponent(GConst.TYPEOF_UNITY_CLASS.CAMERA)
end
function UIManager:showWaitPay()
if self.waitNetCount == 0 then
if self.waitPaySeq == nil then
local seq = DOTweenManager:createSeqWithIntId(GConst.DOTWEEN_IDS.WAIT_PAY)
seq:SetAutoKill(false)
seq:AppendInterval(1)
seq:AppendCallback(function()
self.netCanvas:setActive(true)
end)
self.waitPaySeq = seq
elseif not self.waitPaySeq:IsPlaying() then
self.waitPaySeq:Restart()
end
end
self.waitNetCount = self.waitNetCount + 1
self:disableTouch()
end
function UIManager:hideWaitPay()
self:hideWaitNet()
if self.waitNetCount <= 0 then
if self.waitPaySeq then
self.waitPaySeq:Pause()
end
end
end
function UIManager:showWaitNet(forceRestart)
if self.waitNetCount == 0 or forceRestart then
if self.waitNetSeq == nil then
local seq = DOTweenManager:createSeqWithIntId(GConst.DOTWEEN_IDS.WAIT_NET)
seq:SetAutoKill(false)
seq:AppendInterval(1)
seq:AppendCallback(function()
self.netCanvas:setActive(true)
end)
seq:AppendInterval(GConst.WAIT_NET_RSP_TIME)
seq:OnComplete(function()
-- 一段时间后还没收到回复就断开连接
NetManager:disconnectAndReconnect()
end)
self.waitNetSeq = seq
elseif not self.waitNetSeq:IsPlaying() then
self.waitNetSeq:Restart()
end
end
self.waitNetCount = self.waitNetCount + 1
self:disableTouch()
end
function UIManager:hideWaitNet(hideAll)
if hideAll then
local count = self.waitNetCount
self.waitNetCount = 0
if self.waitNetSeq then
self.waitNetSeq:Pause()
end
self.netCanvas:setActive(false)
for i = 1, count do
self:enableTouch()
end
else
if self.waitNetCount > 0 then
self:enableTouch()
end
self.waitNetCount = self.waitNetCount - 1
if self.waitNetCount <= 0 then
self.waitNetCount = 0
if self.waitNetSeq then
self.waitNetSeq:Pause()
end
self.netCanvas:setActive(false)
end
end
end
function UIManager:getWaitNetCount()
return self.waitNetCount
end
function UIManager:disableTouch()
if self.disableTouchCount == 0 then
self.swallowTouchesCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = true
end
self.disableTouchCount = self.disableTouchCount + 1
if self.disableTouchCount <= 0 then
Logger.logError("UIManager:disableTouch count error:%d", self.disableTouchCount)
end
end
function UIManager:enableTouch()
self.disableTouchCount = self.disableTouchCount - 1
if self.disableTouchCount <= 0 then
self.swallowTouchesCanvas:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
end
end
function UIManager:_updateUISwallowOrder()
local topSwallowTouchIndex = 0
for i = #self.uiList, 1, -1 do
if self.uiList[i]:swallowTouchBetweenUI() then
topSwallowTouchIndex = self.uiList[i]:getSiblingIndex()
self:_setUISwallowOrder(topSwallowTouchIndex)
break
end
end
self.swallowUITouches:getGameObject():SetActive(topSwallowTouchIndex > 0)
end
function UIManager:_setUISwallowOrder(siblingIndex)
local order = MAIN_CANVAS_ORDER + siblingIndex * UI_INTERVAL_ORDER
self.swallowUITouches:getTransform():SetSiblingIndex(siblingIndex - 1)
self.swallowUITouchesCanvas.sortingOrder = order - 1
end
function UIManager:_getUpperUIObj(uiObj)
local uiNum = #self.uiList
for i = uiNum, 1, -1 do
if self.uiList[i] == uiObj then
return self.uiList[i - 1]
end
end
return nil
end
function UIManager:getTopUIObj()
local uiNum = #self.uiList
return self.uiList[uiNum]
end
function UIManager:getTopUIIndex()
if not self:getTopUIObj() then
return
end
return self:getTopUIObj():getUIIndex()
end
function UIManager:getUIList()
return self.uiList
end
function UIManager:getAniType(uiObj)
local params = uiObj:_getRecordParams()
if type(params) == "table" and params.aniType then
return params.aniType
end
if not uiObj:isFullScreen() then
return self.ANI_TYPE.POP
end
return nil
end
function UIManager:playBGM(id)
if id ~= self.currBGMId then
self.currBGMId = id
AudioManager:playMusic(id, true)
end
end
function UIManager:stopBGM(id)
if id == self.currBGMId then
self.currBGMId = nil
AudioManager:stopMusicById(id, true)
end
end
function UIManager:stopCurrentBGM()
if self.currBGMId then
AudioManager:stopMusicById(self.currBGMId, true)
self.currBGMId = nil
end
end
function UIManager:getCurrentBGM()
return self.currBGMId
end
function UIManager:clear()
if self.waitNetSeq then
self.waitNetSeq:Kill()
self.waitNetSeq = nil
end
end
function UIManager:destroyUIRoot()
if self.uiRoot then
self.uiRoot:destroy()
self.uiRoot = nil
end
end
-- 显示刘海屏(模拟IphoneX)
function UIManager:showNotchScreen()
if self.notchScreen then
self.notchScreen:setActive(true)
else
-- 创建一个刘海屏
local notchHeight = SafeAreaManager:getNotchScreenHeight()
Logger.log("模拟刘海屏高度:%s", notchHeight)
local notchScreen = CS.UnityEngine.GameObject("NotchScreen")
notchScreen:AddComponent(GConst.TYPEOF_UNITY_CLASS.RECTTRANSFORM)
self.notchScreen = BaseObject:create()
self.notchScreen:initWithGameObject(notchScreen)
self.notchScreen:getTransform():SetParent(self.toastCanvas:getTransform())
self.notchScreen:getTransform().anchorMin = BF.Vector2(0, 1)
self.notchScreen:getTransform().anchorMax = BF.Vector2(1, 1)
self.notchScreen:getTransform().pivot = BF.Vector2(0.5, 1)
self.notchScreen:setAnchoredPosition(0, 0)
self.notchScreen:setSizeDelta(0, notchHeight)
self.notchScreen:setLocalScale(1, 1, 1)
local cacheLocalPos = self.notchScreen:getTransform().localPosition
self.notchScreen:getTransform().localPosition = BF.Vector3(cacheLocalPos.x, cacheLocalPos.y, 0)
local img = notchScreen:AddComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE)
img.color = BF.Color(0, 0, 0, 0.5)
end
end
function UIManager:backToLogin()
self:stopCurrentBGM()
SDKManager:logout()
-- 清除引导
ModuleManager.TutorialManager:stopTutorial()
self:closeAllUI()
ModuleManager.BattleManager:clearOnExitScene()
Game:showLoginUI()
end
function UIManager:backToLoginWithoutLogout()
self:hideMessageBox()
self:stopCurrentBGM()
ModuleManager.TutorialManager:stopTutorial()
self:closeAllUI()
ModuleManager.BattleManager:clearOnExitScene()
Game:showLoginUI()
end
-- 掉线提示处理
function UIManager:showKickOut(msgData)
local content
local reason = NetManager:getKickOutReasonEnum(msgData.reason)
if reason == 0 then -- 服务器维护
content = I18N:getGlobalText(I18N.GlobalConst.MAINTAIN)
elseif reason == 1 then -- 网络消息流控,也就是短时间内通信次数太多
content = I18N:getGlobalText(I18N.GlobalConst.DISCONNECT_RELOGIN)
elseif reason == 2 then -- 封号
content = I18N:getGlobalText(I18N.GlobalConst.FORBIDDEN)
elseif reason == 3 then -- 多点登录
content = I18N:getGlobalText(I18N.GlobalConst.OTHER_LOGIN)
else
content = I18N:getGlobalText(I18N.GlobalConst.DISCONNECT_RELOGIN)
end
self.disconnectMsgBoxVisible = true
-- 被踢了的话就先断开连接再弹确认框
NetManager:closeAndClear()
local params = {
content = content,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
okFunc = function()
self.disconnectMsgBoxVisible = false
ModuleManager.LoginManager:goToLoginScene()
end,
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
top = true,
}
GFunc.showMessageBox(params)
end
-- 掉线提示处理
function UIManager:showDisconnect()
self.disconnectMsgBoxVisible = true
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.DISCONNECT_RELOGIN),
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
okFunc = function()
self.disconnectMsgBoxVisible = false
ModuleManager.LoginManager:goToLoginScene()
end,
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
top = true,
}
GFunc.showMessageBox(params)
end
function UIManager:isDisconnectMsgBoxVisible()
return self.disconnectMsgBoxVisible
end
function UIManager:_loadCurrencyBar(params, showBg, hidAddImg)
if self.currencyBar == nil then
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/currency_bar.prefab", self.currencyRoot, function (_prefabObject)
if self.currencyBar then
_prefabObject:destroy()
else
self.currencyBar = _prefabObject:addLuaComponent(GConst.TYPEOF_LUA_CLASS.CURRENCY_BAR)
end
self.currencyBar:show(params, showBg, hidAddImg)
end)
end
end
function UIManager:showCurrencyBar(uiObj)
local params, showBg, hidAddImg = uiObj:getCurrencyParams()
if params then
local currCurrencyBarOrder = 0
if self.currencyBarBindUI then
currCurrencyBarOrder = self.currencyBarBindUI:getUIOrder()
end
local sortingOrder = uiObj:getUIOrder()
if sortingOrder >= currCurrencyBarOrder then
self.currencyBarBindUI = uiObj
-- 设置为比下一个界面的order低x点
self.currencyCanvas.sortingOrder = sortingOrder + UI_INTERVAL_ORDER - UI_BARS_UNDER_ORDER
if self.currencyBar == nil then
self:_loadCurrencyBar(params, showBg, hidAddImg)
else
self.currencyBar:show(params, showBg, hidAddImg)
end
return true
elseif sortingOrder == currCurrencyBarOrder then -- 同界面
if self.currencyBar then
self.currencyBar:show(params, showBg, hidAddImg)
else
-- self.currencyParam = params
self:_loadCurrencyBar(params, showBg, hidAddImg)
end
return true
end
end
return false
end
function UIManager:updateCurrentBattleType(battleType)
local uiObj = UIManager:getUIByIndex(UIManager.UI_PATH.MAINCITY_UI)
if uiObj and uiObj:getIsLoadedComplete() then
uiObj:updateCurrentBattleType(battleType)
end
end
function UIManager:updateBarsWhenCloseUI(uiObj)
if self.currencyBarBindUI == uiObj then -- 关闭的是跟顶部货币栏有关联的ui
self.currencyBarBindUI = nil
local updateFlag = false
for i = #self.uiList, 1, -1 do
if self:showCurrencyBar(self.uiList[i]) then
updateFlag = true
break
end
end
if not updateFlag then
if self.currencyBar then
self.currencyBar:setVisible(false)
end
end
end
end
function UIManager:refreshCurrencyBar()
if self.currencyBar then
self.currencyBar:refreshTextRightNow()
end
end
function UIManager:refreshCurrencyAddTx(itemId, num)
local topUI = self.uiList[#self.uiList]
if self.currencyBar and self.currencyBarBindUI == topUI then
self.currencyBar:refreshCurrencyAddTx(itemId, num)
end
end
function UIManager:showCurrencyAction(pos, imgNum)
local topUI = self.uiList[#self.uiList]
if self.currencyBar and self.currencyBarBindUI == topUI then
self.currencyBar:showCurrencyAction(pos, imgNum)
end
end
function UIManager:showChatBtn(isFirstEnter)
if self.uiRoot then
if self.chatBtn then
self.chatBtn:getLuaComponent(GConst.TYPEOF_LUA_CLASS.CHAT_BTN_COMP):show(isFirstEnter)
else
if self.isShowChat ~= nil then
return
end
self.isShowChat = true
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/chat/chat_btn.prefab", self.mainCanvas, function(prefab)
self.chatBtn = prefab
self.chatBtn:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).overrideSorting = true
self.chatBtn:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).sortingOrder = UI_MAX_ORDER
local comp = self.chatBtn:addLuaComponent(GConst.TYPEOF_LUA_CLASS.CHAT_BTN_COMP)
if self.isShowChat then
comp:show(isFirstEnter)
else
comp:hide()
end
self.isShowChat = nil
end)
end
end
end
function UIManager:hideChatBtn()
if self.uiRoot then
if self.chatBtn then
self.chatBtn:getLuaComponent(GConst.TYPEOF_LUA_CLASS.CHAT_BTN_COMP):hide()
elseif self.isShowChat then
self.isShowChat = false
end
end
end
-- 切换语言后刷新一些缓存的界面
function UIManager:refreshOnChangeLanguage()
if self.currencyBar then
self.currencyBar:refreshText()
end
local MessageBox = require "app/ui/common/message_box"
if self.messageBox then
MessageBox:refreshText(false)
end
if self.topMsgBox then
MessageBox:refreshText(true)
end
ModuleManager.ToastManager:refreshText()
ModuleManager.TaskToastManager:refreshText()
end
if EDITOR_MODE then
UIManager._editorUpdateUISwallowOrder = UIManager._updateUISwallowOrder
function UIManager:_updateUISwallowOrder()
self:_editorUpdateUISwallowOrder()
if self.mainCanvas:getTransform().hierarchyCapacity > MAIN_CANVAS_HIERARCHY_CAPACITY then
Logger.logTodo("current main ui canvas hierarchyCount is:%d", self.mainCanvas:getTransform().hierarchyCapacity)
end
end
end
if NOT_PUBLISH then
UIManager._releaseEnableTouch = UIManager.enableTouch
function UIManager:enableTouch()
if self._debugEnableTouchFuncMap == nil then
self._debugEnableTouchFuncMap = {
[SceneManager.onFinished] = true,
[BaseUI.enableUITouch] = true,
[BaseScene.enableTouch] = true,
[UIManager.onLoadingUICompletelyClosed] = true,
[UIManager.hideWaitNet] = true
}
end
local currFunc = debug.getinfo(2, "f").func
if self._debugEnableTouchFuncMap[currFunc] == nil then
Logger.logFatal("you can not call UIManager:enableTouch directly")
end
self:_releaseEnableTouch()
end
UIManager._releaseDisableTouch = UIManager.disableTouch
function UIManager:disableTouch()
if self._debugDisableTouchFuncMap == nil then
self._debugDisableTouchFuncMap = {
[SceneManager.changeScene] = true,
[BaseUI.disableUITouch] = true,
[BaseScene.disableTouch] = true,
[UIManager.showLoading] = true,
[UIManager.showWaitNet] = true,
[UIManager.showWaitPay] = true
}
end
local currFunc = debug.getinfo(2, "f").func
if self._debugDisableTouchFuncMap[currFunc] == nil then
Logger.logFatal("you can not call UIManager:disableTouch directly")
end
self:_releaseDisableTouch()
end
end
function UIManager:onPressAndroidBackspace()
if self.uiRoot == nil then
return
end
if self.disableTouchCount > 0 then
return
end
if DataManager == nil then
return
end
if DataManager.TutorialData:getIsInTutorial() then
return
end
if DataManager.TutorialData:getIsFuncTutorial() then
return
end
if self.topMsgBox and self.topMsgBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled then
if self.topMsgBox._closeByAndroidBackspace then
local MessageBox = require "app/ui/common/message_box"
local uiMap = self.topMsgBox:genAllChildren()
MessageBox:closeAndClear(self.topMsgBox, uiMap)
end
return
end
if self.messageBox and self.messageBox:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled then
if self.messageBox._closeByAndroidBackspace then
local MessageBox = require "app/ui/common/message_box"
local uiMap = self.messageBox:genAllChildren()
MessageBox:closeAndClear(self.messageBox, uiMap)
end
return
end
if #self.uiList <= 0 then
return
end
local topUI = self.uiList[#self.uiList]
if topUI:isClosed() then
return
end
if topUI.root == nil then
return
end
if topUI.root:isDestroyed() then
return
end
if not topUI:isVisible() then
return
end
if not topUI:getIsShowComplete() then
return
end
topUI:onPressBackspace()
end
return UIManager