222 lines
6.4 KiB
Lua
222 lines
6.4 KiB
Lua
---@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; |