---@class BP_AttackPoint_C:AActor ---@field Sphere USphereComponent ---@field P_AttackPoint UParticleSystemComponent ---@field DefaultSceneRoot USceneComponent --Edit Below-- local BP_AttackPoint = { -- 是否激活 IsActive = false; -- 占领的时间 LastProgress = 0; -- 开始占领的时间 StartOccupyTime = 0; -- 正在占领中 IsOccupying = false; -- 是否成功占领 IsSuccessfullyOccupied = false; -- 检测的帧数 FPS = 5.; } function BP_AttackPoint:GetReplicatedProperties() return "IsActive" ,"LastProgress" ,"StartOccupyTime" ,"IsOccupying" ,"IsSuccessfullyOccupied" end function BP_AttackPoint:ReceiveBeginPlay() BP_AttackPoint.SuperClass.ReceiveBeginPlay(self) if UGCGameSystem.IsServer() then else self.WidgetId = UGCWidgetManagerSystem.AddObjectPositionUI( self, UGCGameSystem.GetUGCResourcesFullPath('Asset/UI/StatusUI/MarkPlayerUI/WB_MarkAttackPoint.WB_MarkAttackPoint_C'), {X = 0, Y = 0, Z = 100}, true, false, false ) if self.UpdateWidgetHandle == nil then self.UpdateWidgetHandle = UGCEventSystem.SetTimerLoop(self, self.UpdateWidget, 0.2) end end end function BP_AttackPoint:UpdateWidget() local TargetWidget = UGCWidgetManagerSystem.GetObjectPositionUI(self, self.WidgetId) if UE.IsValid(TargetWidget) then TargetWidget:UpdateInfo(self) end end --[[ function BP_AttackPoint:ReceiveTick(DeltaTime) BP_AttackPoint.SuperClass.ReceiveTick(self, DeltaTime) end --]] function BP_AttackPoint:ReceiveEndPlay() if UGCGameSystem.IsServer() then self:SetActiveAttackPoint(false) else if self.UpdateWidgetHandle then UGCEventSystem.StopTimer(self.UpdateWidgetHandle) end end BP_AttackPoint.SuperClass.ReceiveEndPlay(self) end --[[ function BP_AttackPoint:GetAvailableServerRPCs() return end --]] function BP_AttackPoint:GetActive() return self.IsActive end function BP_AttackPoint:SetActiveAttackPoint(InIsActive) if InIsActive ~= self.IsActive then self.IsActive = InIsActive if self.IsActive then -- 初始化 self.LastProgress = 0; self.IsOccupying = false; self.IsSuccessfullyOccupied = false; -- 设置Loop if self.UpdateHandle == nil then self.UpdateHandle = UGCEventSystem.SetTimerLoop(self, self.UpdateAttackPointProgress, 1./self.FPS) end else if self.UpdateHandle then UGCEventSystem.StopTimer(self.UpdateHandle) self.UpdateHandle = nil end end end end function BP_AttackPoint:UpdateAttackPointProgress() local AttackTeamID = UGCGameSystem.GameState:GetAttackTeam() local TeamPlayers = UGCTeamSystem.GetPlayerKeysByTeamID(AttackTeamID) local SelfPos = self:K2_GetActorLocation() local TargetRadius = self.Sphere:GetScaledSphereRadius() UGCLogSystem.Log("[BP_AttackPoint_UpdateAttackPointProgress] TargetRadius:%s, AttackTeamID:%s", tostring(TargetRadius), tostring(AttackTeamID)) UGCLogSystem.LogTree("[BP_AttackPoint_UpdateAttackPointProgress]", TeamPlayers) local IsInRange = false -- 判断进攻方玩家是否在范围内 for i, v in pairs(TeamPlayers) do local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(v) if UE.IsValid(PlayerPawn) and PlayerPawn:IsAlive() and not UGCPawnSystem.HasPawnState(PlayerPawn, EPawnState.Dying) then local PawnPos = PlayerPawn:K2_GetActorLocation() local Dis = VectorHelper.GetDistance(SelfPos, PawnPos) UGCLogSystem.Log("[BP_AttackPoint_UpdateAttackPointProgress] Length:%s", tostring(Dis)) if Dis <= TargetRadius and PawnPos.Z >= SelfPos.Z then IsInRange = true break end end end UGCLogSystem.Log("[BP_AttackPoint_UpdateAttackPointProgress] IsInRange:%s", tostring(IsInRange)) -- 设置是否有玩家在范围内 if IsInRange then self:PlayerEnterAttackPoint() else self:PlayerLeaveAttackPoint() end -- 判断是否占点成功 if not self.IsSuccessfullyOccupied then if self:CheckIsSuccessfullyOccupied() then -- 成功后发送通知 UGCEventSystem.SendEvent(EventEnum.UpdateSuccessfullyOccupied) -- 关闭占点 self:SetActiveAttackPoint(false) end end end function BP_AttackPoint:PlayerEnterAttackPoint() if not self.IsOccupying then self.IsOccupying = true self.StartOccupyTime = UGCGameSystem.GameState:GetServerGameTime() end end function BP_AttackPoint:PlayerLeaveAttackPoint() if self.IsOccupying then self.LastProgress = self:GetProgress() self.IsOccupying = false end end -- 获取占领进度 返回秒 function BP_AttackPoint:GetProgress() if self.IsOccupying then return self.LastProgress + (UGCGameSystem.GameState:GetServerGameTime() - self.StartOccupyTime) else return self.LastProgress end end function BP_AttackPoint:CheckIsSuccessfullyOccupied() if self.IsSuccessfullyOccupied then return true end return self:GetProgress() >= ProjectConfig.AttackPointTime end return BP_AttackPoint