2025-01-04 23:00:19 +08:00

222 lines
6.4 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---@class BP_RadiationCircle_C:AActor
---@field Sphere USphereComponent
---@field DefaultSceneRoot USceneComponent
---@field GunClass UClass
---@field BulletClass UClass
---@field GunMaxNum int32
---@field BulletMaxNum int32
---@field BulletLiftTime float
---@field BulletFlySpeed float
---@field SpawnGunSpeedCurve UCurveFloat
---@field MiniYawInterval float
--Edit Below--
---@class GunInfoItem
---@field Gun BP_FireGun_C
---@field bIsInUse boolean
---@field bIsVisible boolean
---@type BP_RadiationCircle_C
local BP_RadiationCircle = {
GunActors = {};
BulletActors = {};
GetGunIndex = 1;
GetBulletIndex = 1;
LastSpawnGunTime = 0;
MiniGameTime = 1;
StartTime = 0.;
bActive = false;
CenterPos = {X = 0, Y = 0, Z = 0};
RangeRadius = 0.;
-- 达标的Yaw旋转其对应的是火炮的Yaw旋转
QualifyYaws = {};
RemoveQualifyYawHandles = {};
RemoveQualifyYawID = 10000;
};
function BP_RadiationCircle:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
-- 加载一下场景中的东西
if UGCGameSystem.IsServer() then
self.MiniGameTime = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.AvoidBall].MaxGameTime
self.CenterPos = self:K2_GetActorLocation()
self.RangeRadius = self.Sphere:GetScaledSphereRadius()
UGCLogSystem.Log("[BP_RadiationCircle_ReceiveBeginPlay] CenterPos:%s, RangeRadius:%s", VectorHelper.ToString(self.CenterPos), tostring(self.RangeRadius))
-- UGCEventSystem.SetTimer(self, self.SpawnGunAndBullet, 5)
self:SpawnGunAndBullet();
end
end
function BP_RadiationCircle:ActiveGame()
self.StartTime = UGCSystemLibrary.GetGameTime()
self.bActive = true
UGCLogSystem.Log("[BP_RadiationCircle_ActiveGame]")
end
function BP_RadiationCircle:StopGame()
self.bActive = false
end
function BP_RadiationCircle:ClearGunAndBullet()
for i, v in pairs(self.GunActors) do
v:K2_DestroyActor()
end
for i, v in pairs(self.BulletActors) do
v:K2_DestroyActor()
end
self.BulletActors = {}
self.GunActors = {}
end
function BP_RadiationCircle:SpawnGunAndBullet()
for i = 1, self.GunMaxNum do
local Gun = UGCGameSystem.SpawnActor(self, self.GunClass, {X = 0, Y = 0, Z = -1000}, VectorHelper.RotZero(), VectorHelper.ScaleOne(), nil)
self.GunActors[#self.GunActors + 1] = Gun
end
for i = 1, self.BulletMaxNum do
local Bullet = UGCGameSystem.SpawnActor(self, self.BulletClass, {X = 0, Y = 0, Z = -1000}, VectorHelper.RotZero(), VectorHelper.ScaleOne(), nil)
self.BulletActors[#self.BulletActors + 1] = Bullet
end
end
function BP_RadiationCircle:GetNextGun()
local Res = self.GunActors[self.GetGunIndex]
self.GetGunIndex = (self.GetGunIndex % #self.GunActors) + 1
return Res
end
function BP_RadiationCircle:GetNextBullet()
local Res = self.BulletActors[self.GetBulletIndex]
self.GetBulletIndex = (self.GetBulletIndex % #self.BulletActors) + 1
return Res
end
function BP_RadiationCircle:GetNextTargetPawn()
local AllPawns = UGCGameSystem.GetAllPlayerPawn()
local Random = math.random(1, #AllPawns)
return AllPawns[Random]
end
function BP_RadiationCircle:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
-- 这是服务器
if UGCGameSystem.IsServer() and self.bActive then
local NowTime = UGCSystemLibrary.GetGameTime()
local ShotInterval = self.SpawnGunSpeedCurve:GetFloatValue((NowTime - self.StartTime) / self.MiniGameTime)
self.LastSpawnGunTime = self.LastSpawnGunTime + DeltaTime;
if self.LastSpawnGunTime >= ShotInterval then
self.LastSpawnGunTime = 0;
self:ExeGunFire();
end
end
end
-- 激活炮台开炮
function BP_RadiationCircle:ExeGunFire()
local TargetPawn = self:GetNextTargetPawn()
if TargetPawn == nil then
UGCLogSystem.LogError("[BP_RadiationCircle_ExeGunFire] TargetPawn is nil")
return
end
local Gun = self:GetNextGun()
local Bullet = self:GetNextBullet()
local PawnPos = TargetPawn:K2_GetActorLocation()
local GunPos, GunRot = self:GetGunTargetPosAndRot(PawnPos, KismetMathLibrary.RandomBool())
Gun:FireBullet(GunPos, GunRot, Bullet)
end
--- 获取炮台激活点位
---@param IsReverse 是否反向半径
function BP_RadiationCircle:GetGunTargetPosAndRot(PawnPos, IsReverse)
local MulReverseNum = (IsReverse and -1 or 1)
local Dir = VectorHelper.Sub(PawnPos, self.CenterPos)
--Dir.Z = 0
local DirRot = KismetMathLibrary.MakeRotFromX(Dir)
-- 获取合格的Yaw方向为的是防止出现穿模
local TargetYaw = self:GetQualifyYaw(DirRot.Yaw)
self.QualifyYaws[#self.QualifyYaws + 1] = TargetYaw
local HandleID = self:GetNewID()
self.RemoveQualifyYawHandles[HandleID] = UGCEventSystem.SetTimer(self, function()
table.removeValue(self.QualifyYaws, TargetYaw, true)
self.RemoveQualifyYawHandles[HandleID] = nil
end, 3.)
Dir = VectorHelper.MulNumber(KismetMathLibrary.GetForwardVector({Roll = 0, Pitch = 0, Yaw = TargetYaw}), MulReverseNum)
-- Dir = VectorHelper.MulNumber(Dir, 1./ VectorHelper.Length(Dir) * MulReverseNum)
local TargetRot = VectorHelper.RotToLuaTable(KismetMathLibrary.MakeRotFromX(VectorHelper.MulNumber(Dir, -1)))
-- local TargetRot = {Roll = 0, Pitch = 0, Yaw = (IsReverse and TargetYaw or (360 - TargetYaw))}
local TargetPos = VectorHelper.ToLuaTable(VectorHelper.Add(self.CenterPos, VectorHelper.MulNumber(Dir, self.RangeRadius)))
TargetPos.Z = self.CenterPos.Z
return TargetPos, TargetRot
end
function BP_RadiationCircle:GetQualifyYaw(TargetYaw)
local CheckInterval = self.MiniYawInterval / 2
local TempIsQualify
local TempYaw = 0
for i = 0, math.floor(180 / CheckInterval) do
TempIsQualify = true
TempYaw = TargetYaw + i * CheckInterval
for _, Yaw in pairs(self.QualifyYaws) do
if math.abs(Yaw - TempYaw) < self.MiniYawInterval then
TempIsQualify = false
break
end
end
if TempIsQualify then
return TempYaw
end
TempIsQualify = true
TempYaw = TargetYaw - i * CheckInterval
for _, Yaw in pairs(self.QualifyYaws) do
if math.abs(Yaw - TempYaw) < self.MiniYawInterval then
TempIsQualify = false
break
end
end
if TempIsQualify then
return TempYaw
end
end
return TargetYaw
end
function BP_RadiationCircle:GetNewID()
self.RemoveQualifyYawID = self.RemoveQualifyYawID + 1
return self.RemoveQualifyYawID
end
function BP_RadiationCircle:ReceiveEndPlay()
for i, v in pairs(self.RemoveQualifyYawHandles) do
UGCEventSystem.StopTimer(v)
end
if UGCGameSystem.IsServer() then
self:ClearGunAndBullet()
end
self.SuperClass.ReceiveEndPlay(self);
end
function BP_RadiationCircle:GetReplicatedProperties()
return
end
--[[
function BP_RadiationCircle:GetAvailableServerRPCs()
return
end
--]]
return BP_RadiationCircle;