--[[------------------------------------------UI管理器------------------------------------------------------]]-- UIManager = UIManager or { } UIManager.HasInitialized = false UIManager.MainControlPanel = nil UIManager.PlayerInfoPanel = nil UIManager.OpenedWidgetTable = {} UIManager.SameLevelWidgetTable = {} UIManager.PreCachedWidgetTable = {} UIManager.TriggeredGuideTable = {} UIManager.AllPanel = {} function UIManager:Init() require('Script.Global.UIConfig') self:Bind() self:InitBaseUI() self:PreLoadUIAsset() self.HasInitialized = true self:ShowPanel(EUIType.Main) self:OnWaitPlayerJoinTimeChange(UGCGameSystem.GameState.GameStage) self:OnGameStageChange(UGCGameSystem.GameState.GameStage) end function UIManager:UnInit() self:UnBind() self:Release() end function UIManager:Bind() if UIManager.HasInitialized then return end EventSystem:AddListener(EventType.OnGameStageChanged, UIManager.OnGameStageChange, self) EventSystem:AddListener(EventType.RequestShowPanel, UIManager.ShowPanel, self) EventSystem:AddListener(EventType.RequestClosePanel, UIManager.ClosePanel, self) EventSystem:AddListener(EventType.GameEnd, UIManager.OnGameEnd, self) EventSystem:AddListener(EventType.ShowNotice, UIManager.ShowNotice, self) EventSystem:AddListener(EventType.OnWaitPlayerJoinTimeChanged, UIManager.OnWaitPlayerJoinTimeChange, self) end function UIManager:UnBind() EventSystem:RemoveListener(EventType.RequestShowPanel, UIManager.ShowPanel, self) EventSystem:RemoveListener(EventType.RequestClosePanel, UIManager.ClosePanel, self) EventSystem:RemoveListener(EventType.GameEnd, UIManager.OnGameEnd, self) EventSystem:RemoveListener(EventType.ShowNotice, UIManager.ShowNotice, self) EventSystem:RemoveListener(EventType.OnWaitPlayerJoinTimeChanged, UIManager.OnWaitPlayerJoinTimeChange, self) end function UIManager:Release() for _, Panel in pairs(self.AllPanel) do if UE.IsValid(Panel) then Panel:RemoveFromParent() end end self.AllPanel = nil end function UIManager:InitBaseUI() self.MainControlPanel = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C") if self.MainControlPanel ~= nil then local MainControlBaseUI = self.MainControlPanel.MainControlBaseUI; MainControlBaseUI.Image_IngameLogo:AddAdvancedCollapsedCount(1) --局内游戏Logo MainControlBaseUI.Image_0:AddAdvancedCollapsedCount(1) --指南针指针 MainControlBaseUI.NavigatorPanel:AddAdvancedCollapsedCount(1) --指南针界面 MainControlBaseUI.SurviveInfoPanel:AddAdvancedCollapsedCount(1) --存活人数 MainControlBaseUI.CanvasPanel_BackpackPanel:AddAdvancedCollapsedCount(1) --背包按钮 MainControlBaseUI.CanvasPanel_HelmetArmor:AddAdvancedCollapsedCount(1) --头盔、护甲按钮 MainControlBaseUI.CanvasPanel_FreeCamera:AddAdvancedCollapsedCount(1) --自由视角眼睛 MainControlBaseUI.CanvasPanelSurviveKill:AddAdvancedCollapsedCount(1) --剩余人数、淘汰数 MainControlBaseUI.SignalReceivingAreaTIPS_UIBP:AddAdvancedCollapsedCount(1) --信号区提示 MainControlBaseUI.CircleChasingProgress:AddAdvancedCollapsedCount(1) --刷圈进度 MainControlBaseUI.PlayerInfoSocket:AddAdvancedCollapsedCount(1) --玩家血条 -- 隐藏小地图 MainControlBaseUI.CanvasPanel_MiniMapAndSetting:AddAdvancedCollapsedCount(1) --玩家血条 MainControlBaseUI.IsNeedTeamPanel = false --不显示队友面板 local ShootingUIPanel = self.MainControlPanel.ShootingUIPanel ShootingUIPanel:AddAdvancedCollapsedCount(1) --不显示战斗界面 end self.PlayerInfoPanel = GameBusinessManager.GetWidgetFromName(ingame, "PlayerInfoPanel_C") if self.PlayerInfoPanel ~= nil then local PlayerInfoPanel = self.PlayerInfoPanel.VerticalLifeInfo PlayerInfoPanel.VerticalLifeInfo:AddAdvancedCollapsedCount(1) --玩家血条和能量条 end end function UIManager:OnGameStageChange(GameStage) if GameStage == EGameStage.GameEnd then self:CloseAllPanel(true) self:GetPanel(EUIType.Notice):CloseRemainGeneralNotice() self:GetPanel(EUIType.ForceGuide):SetVisibility(ESlateVisibility.Collapsed) self:ShowPanel(EUIType.Settlement) EventSystem.SetTimer(UGCGameSystem.GameState, function() --停止检测DS连接 if NetUtil then NetUtil.StopCheckDSActive(); end --忽略DS链接报错 if BattleResult then BattleResult.IgnoreDSError = true end end, 1.0) end end function UIManager:OnGameEnd(GameResultData) -- UE.Log("[UIManager:OnGameEnd]") -- self:CloseAllPanel(true) -- self:GetPanel(EUIType.Notice):CloseRemainGeneralNotice() -- self:GetPanel(EUIType.ForceGuide):SetVisibility(ESlateVisibility.Collapsed) -- EventSystem.SetTimer(UGCGameSystem.GameState, function() -- self:ShowPanel(EUIType.Settlement, GameResultData); -- --停止检测DS连接 -- if NetUtil then -- NetUtil.StopCheckDSActive(); -- end -- --忽略DS链接报错 -- if BattleResult then -- BattleResult.IgnoreDSError = true -- end -- end, 1.0) end function UIManager:LoadUI(Config) local Widget = self:CreateUserWidget(Config.WidgetClassPath) if Widget == nil or UE.IsValid(Widget) == false then UE.LogError("[UIManager:LoadUI] invalid config: path=%s, root=%s", tostring(Config.WidgetClassPath), tostring(Config.Root)) return nil end self.UIRoot:SetUIRoot(Widget, Config.Root) if Widget['Hide'] ~= nil then --如果继承自UAEUserWidget的UI Widget:Hide() else Widget:SetVisibility(ESlateVisibility.Collapsed) end return Widget end function UIManager:CreateUserWidget(WidgetClassPath) return UserWidget.NewWidgetObjectBP(GameDataManager.GetLocalPlayerController(), UE.LoadClass(WidgetClassPath)) end function UIManager:PreLoadUIAsset() if self.UIRoot == nil then self:InitUIRoot() end for UIType, Config in pairs(UIConfig.General) do local CachedPanel = self.AllPanel[UIType] if CachedPanel == nil or UE.IsValid(CachedPanel) == false then local Widget = self:LoadUI(Config) Widget.UIName = UIType self.AllPanel[UIType] = Widget end end end function UIManager:InitUIRoot() self.UIRoot = self:CreateUserWidget(UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/UI_Root.UI_Root_C')) if self.UIRoot and UE.IsValid(self.UIRoot) then self.UIRoot:AddToViewport(10000) UE.Log("[UIManager:InitUIRoot] UIRoot Initialized") end end function UIManager:ShowPanel(UIType, ...) if UIManager.HasInitialized == false then UE.Log("[UIManager:ShowPanel] UIManager.HasInitialized == false") return end if UIType == nil or UIType == EUIType.Default then UE.Log("[UIManager:ShowPanel] Invalid UIType") return end if self.UIRoot == nil then self:InitUIRoot() end if self.UIRoot and UE.IsValid(self.UIRoot) and (not self.UIRoot:IsInViewport()) then self.UIRoot:AddToViewport(10000) end local Widget = self.AllPanel[UIType] if Widget == nil or UE.IsValid(Widget) == false then UE.Log("[UIManager:ShowPanel] invalid Widget, UIType=%d", UIType) return end local RootName = Widget.MyRoot if RootName == nil then RootName = UIRoot.MiddleRoot end if select("#", ...) > 0 then if Widget["InitFromParam"] ~= nil then Widget:InitFromParam(...) end end self:HandleOpenWidget(Widget, RootName) EventSystem:SendEvent(EventType.OnWidgetShowed, UIType) end function UIManager:HandleOpenWidget(Widget, RootName) if Widget == nil then return end local GuideAndNoticeRoot = { UIRoot.BattleRoot, UIRoot.BattleGuideRoot, UIRoot.BattleNoticeRoot, UIRoot.CommonGuideRoot, UIRoot.CommonNoticeRoot } if not table.hasValue(GuideAndNoticeRoot, RootName) then local CurSameLevelWidget = self.SameLevelWidgetTable[RootName] if CurSameLevelWidget ~= nil and Widget ~= CurSameLevelWidget then self:SetWidgetVisible(CurSameLevelWidget, false) EventSystem:SendEvent(EventType.OnWidgetClosed, CurSameLevelWidget.UIName) table.removeKey(self.OpenedWidgetTable, CurSameLevelWidget.UIName) end self.SameLevelWidgetTable[RootName] = Widget end self.OpenedWidgetTable[Widget.UIName] = Widget self:SetWidgetVisible(Widget, true) end function UIManager:HandleCloseWidget(Widget) if self.SameLevelWidgetTable[Widget.MyRoot] == Widget then self.SameLevelWidgetTable[Widget.MyRoot] = nil end self:SetWidgetVisible(Widget, false) self.OpenedWidgetTable[Widget.UIName] = nil end function UIManager:SetWidgetVisible(Widget, bIsVisible) if Widget == nil or UE.IsValid(Widget) == false then return end local VisibleFuncName = bIsVisible and "Show" or "Hide" local Visibility = bIsVisible and ESlateVisibility.SelfHitTestInvisible or ESlateVisibility.Collapsed local OnVisibilityChangedFuncName = bIsVisible and "OnShowPanel" or "OnClosePanel" if Widget[VisibleFuncName] ~= nil then --如果继承自UAEUserWidget的UI Widget[VisibleFuncName](Widget) else Widget:SetVisibility(Visibility) end if Widget[OnVisibilityChangedFuncName] ~= nil then Widget[OnVisibilityChangedFuncName](Widget) end end function UIManager:CloseWidgetByRoot(RootName) local CurLevelWidget = self.SameLevelWidgetTable[RootName] if CurLevelWidget == nil or UE.IsValid(CurLevelWidget) == false then return end self:HandleCloseWidget(CurLevelWidget) EventSystem:SendEvent(EventType.OnWidgetClosed, CurLevelWidget.UIName) end function UIManager:ClosePanel(UIType) local CloseWidget = self.OpenedWidgetTable[UIType] if CloseWidget == nil or UE.IsValid(CloseWidget) == false then return end self:HandleCloseWidget(CloseWidget) EventSystem:SendEvent(EventType.OnWidgetClosed, UIType) end function UIManager:DestroyPanel(UIType) local Panel = self.AllPanel[UIType] if Panel ~= nil and UE.IsValid(Panel) then Panel:RemoveFromParent() self.AllPanel[UIType] = nil self.OpenedWidgetTable[UIType] = nil EventSystem:SendEvent(EventType.OnWidgetClosed, UIType) end end function UIManager:CloseAllPanel(bRemainNotice) for UIType, _ in pairs(self.OpenedWidgetTable) do if bRemainNotice then if UIType ~= EUIType.Notice then self:ClosePanel(UIType) end else self:ClosePanel(UIType) end end end function UIManager:DestroyAllPanel(bRemainNotice) for UIType, _ in pairs(self.AllPanel) do if UIType == EUIType.SkillButton then self:ClosePanel(UIType) else if bRemainNotice then if UIType ~= EUIType.Notice then self:DestroyPanel(UIType) end else self:DestroyPanel(UIType) end end end end function UIManager:GetPanel(UIType) local Panel = self.AllPanel[UIType] if Panel ~= nil and UE.IsValid(Panel) then return Panel end return nil end function UIManager:IsVisiblePanel(UIType) return self.OpenedWidgetTable[UIType] ~= nil end function UIManager:VisiblePanel(UIType) local Panel = self.AllPanel[UIType] if Panel then self:HandleOpenWidget(Panel, Panel.MyRoot) end end function UIManager:HidePanel(UIType) self:ClosePanel(UIType) end function UIManager:ShowGeneralNotice(...) self:ShowPanel(EUIType.Notice, ECustomNoticeType.GeneralNotice, ...) end function UIManager:ShowNotice(InNoticeType, ...) self:ShowPanel(EUIType.Notice, InNoticeType, ...) end function UIManager:OnWaitPlayerJoinTimeChange(RemainTime) if RemainTime > 0 and UGCGameSystem.GameState.GameStage == EGameStage.WaitForPlayer then --self:ShowPanel(EUIType.Notice, ECustomNoticeType.InitialNotice, {}) end end function UIManager:ShowPlayerGuide(GuideWidgetType, GuideData, GuideRoot) if UIManager.HasInitialized == false then UE.Log("[UIManager][ShowPlayerGuide] UIManager.HasInitialized == false") return false end local GuideID = GuideData.ID if GuideID == nil or self.TriggeredGuideTable[GuideID] ~= nil then UE.Log("[UIManager][ShowPlayerGuide] invalid GuideID") return false end local GuideClassPath = UIConfig.Guide[GuideWidgetType] if GuideClassPath == nil then UE.Log("[UIManager][ShowPlayerGuide] invalid GuideClassPath. GuideID = %d", GuideID) return false end local WidgetComponent = self:GetPanelComponentByWidgetName(GuideData.LinkedUIType, GuideData.LinkedComponent) if WidgetComponent == nil or UE.IsValid(WidgetComponent) == false then UE.Log("[UIManager][ShowPlayerGuide] invalid WidgetComponent. GuideID = %d, UIType = %d, ComponentName = %s", GuideID, GuideData.LinkedUIType, GuideData.LinkedComponent) return false end local GuideClass = UE.LoadClass(GuideClassPath) local GuideWidget = UserWidget.NewWidgetObjectBP(UGCGameSystem.GameState, GuideClass) self.UIRoot:SetUIRoot(GuideWidget, GuideRoot) local Data = { UIConfig = WidgetComponent, TextConfig = {TextType = GuideData.GuideTextType, Text = GuideData.GuideText} } GuideWidget:SetGuideActionInfo(Data) self.TriggeredGuideTable[GuideID] = GuideWidget return true end function UIManager:RemovePlayerGuide(GuideID) local GuideWidget = self.TriggeredGuideTable[GuideID] if GuideWidget == nil or UE.IsValid(GuideWidget) == false then return end GuideWidget:RemoveFromParent() self.TriggeredGuideTable[GuideID] = nil end function UIManager:RemoveAllPlayerGuide() for GuideID, GuideWidget in pairs(self.TriggeredGuideTable) do if GuideWidget and UE.IsValid(GuideWidget) then GuideWidget:RemoveFromParent() self.TriggeredGuideTable[GuideID] = nil end end end function UIManager:GetPanelComponentByWidgetName(InUIType, ComponentName) if not UIManager:IsVisiblePanel(InUIType) then return nil end local UIPanel = self:GetPanel(InUIType) if UIPanel == nil or UE.IsValid(UIPanel) == false then return nil end local ComponentNamesTable = string.split(ComponentName, ".") for _, value in ipairs(ComponentNamesTable) do if UIPanel and UE.IsValid(UIPanel) then UIPanel = UIPanel[value] else return nil end end return UIPanel end --- 异步加载一张图给UImage对象 ---@param UIImageObj UImage ---@param ResPath string function UIManager.LoadTexture(UIImageObj, ResPath) local softObjPath = KismetSystemLibrary.MakeSoftObjectPath(ResPath); if softObjPath == nil then UE.LogError("[UIManager.LoadTexture] LoadTexture Path load failed:%s", ResPath); return; end STExtraBlueprintFunctionLibrary.GetAssetByAssetReferenceAsync( softObjPath, ObjectExtend.CreateDelegate(UGCGameSystem.GameState, function (texture) if texture ~= nil then UIImageObj:SetBrushFromTexture(texture); else UE.LogError("[UIManager.LoadTexture] LoadTexture nil:%s", ResPath); end end), true ); end return UIManager