require('Script.Global.WidgetManager.WidgetConfig') WidgetManager = WidgetManager or {} -- 是否初始化 WidgetManager.HasInitialized = false -- 是否是主UI WidgetManager.MainControlPanel = nil WidgetManager.PlayerInfoPanel = nil ---@type table WidgetManager.AllPanel = {} WidgetManager.OwnerController = nil WidgetManager.PlayerHeadSculpture = {} -- 玩家头像 {URL = UTexture2DDynamic*, ...} WidgetManager.WeaponImage = {} -- 武器图片 {URL = UTexture2DDynamic*, ...} ---@param OwnerController APlayerController function WidgetManager:Init(OwnerController) if UE.IsValid(OwnerController) then self.OwnerController = OwnerController end self:InitBaseUI(); local Types = {}; for Name, UIType in pairs(WidgetConfig.EUIType) do if UIType > WidgetConfig.EUIType.Default then table.insert(Types, { UIType = UIType, Name = Name, }); end end table.sort(Types, function(a, b) return a.UIType < b.UIType; end); for i = 1, #Types do self:LoadUI(Types[i].UIType); end self.HasInitialized = true; end function WidgetManager:UnInit() self:Release() end function WidgetManager:ShowOrClosePanel(UIType, IsShow) if UGCGameSystem.IsServer() then return end UGCLogSystem.Log("[WidgetManager:ShowOrClosePanel] UIType: %d", UIType) if IsShow then self:ShowPanel(UIType); else self:ClosePanel(UIType); end end function WidgetManager:InitBaseUI() WidgetConfig.HideDefaultUI(true); end WidgetManager.WidgetFuncs = {}; ---@param UIType int32 ---@param Func fun(Widget: UUserWidget) ---@return UUserWidget function WidgetManager:LoadUI(UIType, Func, Params) if UIType == nil then return nil end local Config = WidgetConfig.HUDConfig[UIType] if Config == nil then UGCLogSystem.Log("[WidgetManager:LoadUI] InValid UIType = %d config, skipped!", UIType) return nil; end UGCLogSystem.LogTree(string.format("[WidgetManager:LoadUI] Params ="), Params) if self.AllPanel[UIType] ~= nil and UE.IsValid(self.AllPanel[UIType]) then if Func then Func(self.AllPanel[UIType], table.unpackTable(Params)); end return self.AllPanel[UIType]; end -- 检查是否正在创建过程中 if WidgetConfig.HUDConfig[UIType].HadLoad then -- 先存放一下 if self.WidgetFuncs[UIType] == nil then self.WidgetFuncs[UIType] = {}; end table.insert(self.WidgetFuncs[UIType], { Func = Func, Params = Params, }); return ; end local UIPathName = Config.Path; if WidgetConfig.DirectLoad[UIType] then if LocalIsGlobalSpectator and WidgetConfig.SpectorConfig[UIType] then local Class = UE.LoadClass(Config.Path) return self:LoadPanelInternal(UIType, Class, Func, Params) else local Class = UE.LoadClass(Config.Path) return self:LoadPanelInternal(UIType, Class, Func, Params) end else UE.AsyncLoadClass_Cached(Config.Path, function(UIClass) self:LoadPanelInternal(UIType, UIClass, Func, Params); end); WidgetConfig.HUDConfig[UIType].HadLoad = true; end return nil; end function WidgetManager:LoadPanelInternal(UIType, UIClass, Func, Params) local Config1 = WidgetConfig.HUDConfig[UIType] local UILayer = Config1.Layer; if UILayer == nil then UILayer = WidgetConfig.EUILayerGroup.Medium; end if self.AllPanel[UIType] ~= nil then -- 先执行其他的 if not table.isEmpty(self.WidgetFuncs[UIType]) then for i = 1, #self.WidgetFuncs[UIType] do local Item = self.WidgetFuncs[UIType][i] if Item then Item.Func(self.AllPanel[UIType], table.unpackTable(Item.Params)); end end end if Func then Func(self.AllPanel[UIType], table.unpackTable(Params)); end return ; end local UIWidget = UserWidget.NewWidgetObjectBP(LocalPlayerController, UIClass); if UIWidget ~= nil then -- 查看是否需要添加到自定义面板上 if Config1.bAddToTouch then UGCWidgetManagerSystem.AddChildToTochButton(UIWidget); end if WidgetConfig.AddedLayerConfig[UIType] and (LocalIsFriendSpectator or LocalIsGlobalSpectator) then UILayer = WidgetConfig.AddedLayerConfig[UIType] end UIWidget:AddToViewport(UILayer); UIWidget:SetVisibility(ESlateVisibility.Collapsed); UIWidget.UIType = UIType; table.func(UIWidget, "LuaInit"); -- 进行初始化 if self.AllPanel[UIType] == nil then self.AllPanel[UIType] = UIWidget; end end if not table.isEmpty(self.WidgetFuncs[UIType]) then for i = 1, #self.WidgetFuncs[UIType] do local Item = self.WidgetFuncs[UIType][i]; if Item then Item.Func(UIWidget, table.unpackTable(Item.Params)); end end end if Func then Func(UIWidget, table.unpackTable(Params)); end return UIWidget; end --- 显示 UI ---@param UIType int32 ---@param NeedCloseSameLayerPanel bool 是否关闭其他相同类型的UI ---@tparam table function WidgetManager:ShowPanel(UIType, NeedCloseSameLayerPanel, ...) UGCLogSystem.Log("[WidgetManager:ShowPanel] UIType = %s", tostring(UIType)); if UIType == nil or UIType == WidgetConfig.EUIType.Default then return end -- 检查是否显示 if self:IsVisiblePanel(UIType) then return ; end local Params = { ... } if NeedCloseSameLayerPanel == nil then NeedCloseSameLayerPanel = true end local Func = function(Widget, ...) if Widget ~= nil and UE.IsValid(Widget) then if NeedCloseSameLayerPanel then self:CloseSameLayerPanel(UIType) end UGCLogSystem.Log("[WidgetManager:ShowPanel] Show UI: " .. tostring(UIType)); table.func(Widget, 'Show'); Widget:SetVisibility(ESlateVisibility.SelfHitTestInvisible); if select("#", ...) > 0 then table.func(Widget, "InitFromParam", ...); end table.func(Widget, 'OnShowPanel', ...); else UGCLogSystem.Log("[WidgetManager_ShowPanel] Show UI Failed: " .. tostring(UIType)) end end local Panel = self:GetPanel(UIType, Func, Params); end ---@param UIType int32 ---@param WorldPosition Vector3D @UI生成的三维世界坐标 function WidgetManager:ShowUIWithWorldPosition(UIType, WorldPosition) if WorldPosition == nil then UGCLogSystem.LogError("[WidgetManager] WorldPosition is nil") return end self:ShowPanel(UIType); end ---@return int32 function WidgetManager:GetPanelLayer(UIType) return WidgetConfig.HUDConfig[UIType].Layer end --- 关闭同层级的所有UI ---@param InUIType int32 function WidgetManager:CloseSameLayerPanel(InUIType) local CurLayer = WidgetConfig.HUDConfig[InUIType].Layer for UIType, Config in pairs(WidgetConfig.HUDConfig) do if UIType ~= InUIType and Config.Layer == CurLayer then self:ClosePanel(UIType) end end end ---@param UIType int32 function WidgetManager:ClosePanel(UIType) if not self:PanelIsValid(UIType) then --UGCLogSystem.Log("[WidgetManager:ClosePanel] 执行") return end local Panel = self.AllPanel[UIType] table.func(Panel, 'Hide') Panel:SetVisibility(ESlateVisibility.Collapsed) table.func(Panel, 'OnClosePanel') if WidgetConfig.HUDConfig[UIType].bShowOnce then self:DestroyPanel(UIType); end end ---@param UIType int32 function WidgetManager:DestroyPanel(UIType) if not self:PanelIsValid(UIType) then return end local Panel = self.AllPanel[UIType] if Panel.UIType ~= UIType then return; end Panel:RemoveFromParent(); self.AllPanel[UIType] = nil; WidgetConfig.HUDConfig[UIType] = nil; end function WidgetManager:CloseAllPanel() for UIType, Panel in pairs(self.AllPanel) do self:ClosePanel(UIType) end end function WidgetManager:DestroyAllPanel() for UIType, Panel in pairs(self.AllPanel) do self:DestroyPanel(UIType) end end ---@param UIType int32 ---@return bool 是否存在UI function WidgetManager:PanelIsValid(UIType) if UIType == nil then return false; end local Panel = self.AllPanel[UIType] return Panel ~= nil and UE.IsValid(Panel) end ---获取UI ---@param UIType int32 ---@param Func fun(Widget:UUserWidget) ---@return UUserWidget 获取UI function WidgetManager:GetPanel(UIType, Func, Params) local Panel = self.AllPanel[UIType]; if Panel ~= nil and UE.IsValid(Panel) then if Func then Func(Panel, table.unpackTable(Params)); end return Panel; else self.AllPanel[UIType] = nil; -- 防止没清空 return self:LoadUI(UIType, Func, Params) end end --- UI是否显示 ---@param UIType int32 ---@return bool function WidgetManager:IsVisiblePanel(UIType) if self:PanelIsValid(UIType) then return self.AllPanel[UIType]:IsVisible() end return false end ---@param UIType int32 function WidgetManager:VisiblePanel(UIType) if self:PanelIsValid(UIType) then self.AllPanel[UIType]:SetVisibility(ESlateVisibility.SelfHitTestInvisible) end end ---@param UIType int32 function WidgetManager:HidePanel(UIType) if self:PanelIsValid(UIType) then self.AllPanel[UIType]:SetVisibility(ESlateVisibility.Collapsed) end end ---@param InStr string function WidgetManager:ShowTips(InStr) UGCWidgetManagerSystem.ShowTipsUI(InStr); end function WidgetManager.HideReturnToLobbyButton() UGCLogSystem.Log("[WidgetManager.HideReturnToLobbyButton] 执行") local InGameMgr = GameFrontendHUD:GetLogicManagerByName("ingame"); local WatchGameUIObj_InGameMgr = GameBusinessManager.GetWidgetFromName(InGameMgr, "WatchGame_UIBP_C"); if WatchGameUIObj_InGameMgr then WatchGameUIObj_InGameMgr.Button_BackToLobby:SetVisibility(ESlateVisibility.Collapsed); end local WatchGameUI = GetUIObject(bp_battleresult, "WatchGame_UIBP_C"); if WatchGameUI then UGCLogSystem.Log("[WidgetManager.HideReturnToLobbyButton] 隐藏起来") WatchGameUI.Button_BackToLobby:SetVisibility(ESlateVisibility.Collapsed); WatchGameUI.GridPanel_1:SetVisibility(ESlateVisibility.Hidden); end local WatchGame_UIBPG = UGCWidgetManagerSystem.GetGlobalOBUI(); if WatchGame_UIBPG then WatchGame_UIBPG.Button_BackToLobby:SetVisibility(ESlateVisibility.Collapsed); end end return WidgetManager