---@class BP_ActiveMonsterBase_C:BP_MonsterBase_C ---@field DetailWidget UWidgetComponent ---@field WidgetComponent UWidgetComponent --Edit Below-- local MonsterBase = require('Script.Blueprint.Monster.BP_MonsterBase') local BP_ActiveMonsterBase = setmetatable( { --IsSelfDead = false; HasBegunPlay = false, KilledPlayerNum = 0, }, { __index = MonsterBase, __metatable = MonsterBase } ) BP_ActiveMonsterBase.MonsterWidgetIndex = 0; BP_ActiveMonsterBase.TalkWidgetTimer = nil; BP_ActiveMonsterBase.bHasInit = false; function BP_ActiveMonsterBase:ReceiveBeginPlayEx() if self:HasAuthority() == false then print(string.format("[BP_ActiveMonsterBase:ReceiveBeginPlayEx] 执行")) local Loc = { X = 0, Y = 0, Z = self.CapsuleComponent:GetScaledCapsuleHalfHeight() + 20 } self.WidgetComponent:K2_SetRelativeLocation(Loc) self.WidgetComponent:SetHiddenInGame(false) if UE.IsValid(self.WidgetComponent.Widget) then self.WidgetComponent.Widget:SetVisibility(ESlateVisibility.SelfHitTestInvisible); else self:NewHealthWidget(); end -- 设置仅显示在自己玩家的客户端 local WidgetPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/WBP_ActiveMonsterTalk.WBP_ActiveMonsterTalk_C') local DetailsLoc = { X = 0, Y = 0, Z = self.CapsuleComponent:GetScaledCapsuleHalfHeight() + 50 } self.MonsterWidgetIndex = UGCWidgetManagerSystem.AddObjectPositionUI(self, WidgetPath, DetailsLoc, true, true, true) self.TalkWidgetTimer = EventSystem.SetTimerLoop(self, function() local Widget = UGCWidgetManagerSystem.GetObjectPositionUI(self, self.MonsterWidgetIndex); if UE.IsValid(Widget) then Widget:SetTalkText(self:GetMonsterType()); EventSystem.StopTimer(self.TalkWidgetTimer) EventSystem.SetTimer(self, function() UGCWidgetManagerSystem.RemoveObjectPositionUI(self, self.MonsterWidgetIndex); end, 3.0) end end, 0.3) self.bHasInit = true else UnrealNetwork.CallUnrealRPC_Multicast(self, "Multi_BeginPlay") end end function BP_ActiveMonsterBase:Multi_BeginPlay() if not self.bHasInit then self:ReceiveBeginPlayEx() end end function BP_ActiveMonsterBase:ClientOnHealthChangedEx(CurrentHP, MaxHP) UE.Log("[BP_ActiveMonsterBase:ClientOnHealthChangedEx] %s: CurHealth=%.2f, MaxHealth=%.2f", KismetSystemLibrary.GetObjectName(self), CurrentHP, MaxHP) if not UE.IsValid(self.WidgetComponent.Widget) then -- 创建一个 Widget,然后添加进去 self:NewHealthWidget(); end self.WidgetComponent:SetVisibility(true) self.WidgetComponent.Widget:UpdateOwnerHealth(CurrentHP, MaxHP) end -- 创建一个 Widget function BP_ActiveMonsterBase:NewHealthWidget() print(string.format("[BP_ActiveMonsterBase:NewHealthWidget] 执行")) local Widget = UserWidget.NewWidgetObjectBP(GameDataManager.GetLocalPlayerController(), UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/WBP_BossHealth.WBP_BossHealth_C'))) self.WidgetComponent:SetWidget(Widget) Widget:SetVisibility(ESlateVisibility.SelfHitTestInvisible) end function BP_ActiveMonsterBase:ReceiveEndPlayEx() if not self:HasAuthority() then self:Cleanup() end end function BP_ActiveMonsterBase:ReceiveOnMonsterDeath() if not self:HasAuthority() then self:Cleanup() end end function BP_ActiveMonsterBase:HideWidget() if UE.IsValid(self.WidgetComponent.Widget) then self.WidgetComponent.Widget:SetVisibility(ESlateVisibility.Collapsed) end end function BP_ActiveMonsterBase:Cleanup() self.WidgetComponent:SetHiddenInGame(true) self:HideWidget(); if UE.IsValid(self.TalkWidgetTimer) then EventSystem.StopTimer(self.TalkWidgetTimer) end end return BP_ActiveMonsterBase;