---@class BP_BossMagical_C:BP_MonsterBoss_C ---@field UAESkillManager UUAESkillManagerComponent ---@field bIsReplica bool ---@field ReplicaParticle UParticleSystem --Edit Below-- local MonsterBoss = require('Script.Blueprint.Monster.BP_MonsterBoss') local BP_BossMagical = setmetatable( { PawnClass = nil, ID = 10006, MonsterName = "Boss", Replicas = {}, ReplicaNum = 4, Parent = nil, -- ReplicaClassPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/Monster/BP_BossMagical_Replica.BP_BossMagical_Replica_C'), ReplicaClassPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/Monster/BP_BossMagical.BP_BossMagical_C') }, { __index = MonsterBoss, __metatable = MonsterBoss } ); function BP_BossMagical:ReceiveBeginPlayEx() MonsterBoss.ReceiveBeginPlayEx(self) if self:HasAuthority()then EventSystem.SetTimer(self, function () UE.Log("[BP_BossMagical_ReceiveBeginPlay] bIsReplica: %s", tostring(self.bIsReplica)) if self.bIsReplica == false then EventSystem.SetTimer( self, function () -- body self:AddSkillMagicalReplica() end, 3. ) self:AddSkillAssassinate() else if UE.IsValid(self.Parent) == false then UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_RemoveWidget") self:K2_DestroyActor() end end end, 0.1 ) end end function BP_BossMagical:Multicast_InitReplica() local HealthWidget = self.HealthWidget.Widget if HealthWidget then if HealthWidget.HPProgressBar then HealthWidget.HPProgressBar:SetFillColorAndOpacity({R = 0, G = 0, B = 1, A = 1}) else UE.Log("[BP_BossMagical_InitReplica] HPProgressBar is nil") end else UE.Log("[BP_BossMagical_InitReplica] HealthWidget is nil") end end function BP_BossMagical:ReceiveEndPlayEx() MonsterBoss.ReceiveEndPlayEx(self) if self:HasAuthority()then else self:Multicast_RemoveWidget() end end function BP_BossMagical:Multicast_RemoveWidget() local HealthWidget = self.HealthWidget.Widget UE.Log("BP_BossMagical_ReceiveEndPlay HealthWidget is %s", tostring(HealthWidget ~= nil)) if HealthWidget then HealthWidget:SetVisibility(ESlateVisibility.Collapsed) HealthWidget:RemoveFromParent() end end function BP_BossMagical:GetAvailableServerRPCs() return "Multicast_SetActorTransform" end function BP_BossMagical:Multicast_SetActorTransform(Position, Rotator) log_tree("Multicast_SetActorTransform_Position = ", Position) log_tree("Multicast_SetActorTransform_Rotator = ", Rotator) self:K2_SetActorLocation(Position) self:K2_SetActorRotation(Rotator) end function BP_BossMagical:GetReplicaClass() if self.ReplicaClass == nil then self.ReplicaClass = UE.LoadClass(self.ReplicaClassPath) end return self.ReplicaClass end function BP_BossMagical:InitReplica(level, Parent) if level == nil then level = 1 end self.Parent = Parent if self:HasAuthority() and self.bIsReplica then self:UpdateMonsterLevel(self.MonsterName, level) UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_InitReplica") end end function BP_BossMagical:AddSkillMagicalReplica() self.SkillMagicalReplicaHandle = EventSystem.SetTimerLoop( self, function () self:ResetReplicas() end, 30. ) end function BP_BossMagical:ResetReplicas() local Crystal = UGCGameSystem.GameState:GetCrystal() if UE.IsValid(Crystal) then local CenterPosition = Crystal:K2_GetActorLocation() local Eightpoint = self:GetEightpoint(500) for i = 1, self.ReplicaNum do if UE.IsValid(self.Replicas[i]) then self.Replicas[i]:InitReplica(self.BossLevel, self) else local Targetposition = VectorHelper.Add(CenterPosition, Eightpoint[i]) CenterPosition.Z = self:K2_GetActorLocation().Z Targetposition.Z = self:K2_GetActorLocation().Z local TargetRotator = KismetMathLibrary.FindLookAtRotation(Targetposition, CenterPosition) local Replica = UGCGameSystem.SpawnActor(UGCGameSystem.GameState, self:GetReplicaClass(), Targetposition, TargetRotator, VectorHelper.ScaleOne(), nil) self.Replicas[i] = Replica Replica.bIsReplica = true Replica:InitReplica(self.BossLevel, self) UE.Log("[BP_BossMagical_ResetReplicas] SpawnFinish %d", i) end end end end function BP_BossMagical:AddSkillAssassinate() self.SkillAssassinateHandle = EventSystem.SetTimerLoop( self, function () local TargetPositions = self:GetMovablePosition() table.Rand(TargetPositions) local MoveIndex = 1 for k, v in pairs(self.Replicas) do if TargetPositions[MoveIndex] == nil then break end if UE.IsValid(v) then self:PlayAssassinate(v, TargetPositions[MoveIndex].Location, TargetPositions[MoveIndex].Rotation) MoveIndex = MoveIndex + 1 end end if TargetPositions[MoveIndex] then self:PlayAssassinate(self, TargetPositions[MoveIndex].Location, TargetPositions[MoveIndex].Rotation) end end, 20. ) end function BP_BossMagical:PlayAssassinate(TargetBossMagical, Location, Rotation) -- body TargetBossMagical:GetController():GetBlackboardComponent():SetValueAsBool("CanPlaySkillAssassinate", true) TargetBossMagical:K2_SetActorLocation(Location) TargetBossMagical:K2_SetActorRotation(Rotation) UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_SetActorTransform", Location, Rotation) EventSystem.SetTimer(TargetBossMagical, function () -- body if UE.IsValid(TargetBossMagical) and UE.IsValid(TargetBossMagical:GetController()) then TargetBossMagical:GetController():GetBlackboardComponent():SetValueAsBool("CanPlaySkillAssassinate", false) end end, 2 ) end function BP_BossMagical:GetEightpoint(Length) local Angle45Len = math.sqrt(2) / 2 return { Vector.New(Length, 0, 0), Vector.New(-Length, 0, 0), Vector.New(0, Length, 0), Vector.New(0, -Length, 0), Vector.New( Length * Angle45Len, Length * Angle45Len, 0), Vector.New(-Length * Angle45Len, Length * Angle45Len, 0), Vector.New( Length * Angle45Len, -Length * Angle45Len, 0), Vector.New(-Length * Angle45Len, -Length * Angle45Len, 0) } end function BP_BossMagical:GetMovablePosition() local ArenaPlayers = UGCGameSystem.GameState:GetPlayersInArena() local ResTransform = {} if not table.isEmpty(ArenaPlayers) then for _, ArenaPlayer in pairs(ArenaPlayers) do local PawnHelfHeight = ArenaPlayer.CapsuleComponent.CapsuleHalfHeight local Playerlocation = ArenaPlayer:K2_GetActorLocation() Playerlocation.Z = Playerlocation.Z + self.Capsule.CapsuleHalfHeight - PawnHelfHeight + 5 local EightLocation = self:GetEightpoint(350) for k, AddLocation in pairs(EightLocation) do local Beginlocation = VectorHelper.Add(Playerlocation, AddLocation) local ObjectTypes = {EObjectTypeQuery.ObjectTypeQuery1} local bHit, _ = KismetSystemLibrary.CapsuleTraceSingleForObjects( self, Beginlocation, Beginlocation, self.Capsule.CapsuleRadius, self.Capsule.CapsuleHalfHeight, ObjectTypes, false, nil, EDrawDebugTrace.None, nil, true, nil, nil, 20 ) if not bHit then -- 判断该位置是否存在地面 local DropLocation = UGCGameSystem.GameState:GetDropLocation(Beginlocation) if VectorHelper.GetDistance(DropLocation, Beginlocation) > 10 then Playerlocation.Z = Beginlocation.Z local TargetRotator = KismetMathLibrary.FindLookAtRotation(Beginlocation, Playerlocation) table.insert(ResTransform, {Location = VectorHelper.ToLuaTable(Beginlocation), Rotation = VectorHelper.RotToLuaTable(TargetRotator)}) end end end end end return ResTransform end function BP_BossMagical:ReceiveOnMonsterDeath() MonsterBoss.ReceiveOnMonsterDeath(self) if self:HasAuthority() then -- 本体死亡则销毁分身 if self.bIsReplica == false then if self.SkillAssassinateHandle then EventSystem.StopTimer(self.SkillAssassinateHandle) self.SkillAssassinateHandle = nil end if self.SkillMagicalReplicaHandle then EventSystem.StopTimer(self.SkillMagicalReplicaHandle) self.SkillMagicalReplicaHandle = nil end for k, v in pairs(self.Replicas) do UnrealNetwork.CallUnrealRPC_Multicast(v, "Multicast_RemoveWidget") if UE.IsValid(v) then v:K2_DestroyActor() end end end end end return BP_BossMagical;