176 lines
6.6 KiB
Lua
176 lines
6.6 KiB
Lua
---@class BP_AvoidingSpikeStick_C:AActor
|
|
---@field TrailingFX UParticleSystemComponent
|
|
---@field StaticMesh1 UStaticMeshComponent
|
|
---@field StaticMesh UStaticMeshComponent
|
|
---@field SM_Stick UStaticMeshComponent
|
|
---@field RotatorCmp USceneComponent
|
|
---@field DefaultSceneRoot USceneComponent
|
|
---@field BeginRotSpeed float
|
|
---@field EndRotSpeed float
|
|
--Edit Below--
|
|
local BP_AvoidingSpikeStick = {
|
|
PlayMaxTime = 0.;
|
|
PlayTime = 0.;
|
|
StartTime = 0.;
|
|
bIsPlaying = false;
|
|
LastRotCmpRight = {X = 1, Y = 1, Z =1};
|
|
LastRotCmpForward = {X = 1, Y = 1, Z =1};
|
|
CenterPos = {X = 0, Y = 0, Z =0};
|
|
StickZ = 0;
|
|
};
|
|
|
|
|
|
function BP_AvoidingSpikeStick:ReceiveBeginPlay()
|
|
self.SuperClass.ReceiveBeginPlay(self);
|
|
self:InitTrap()
|
|
end
|
|
|
|
function BP_AvoidingSpikeStick:InitTrap()
|
|
self.PlayMaxTime = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.AvoidingSpikeStick].MaxGameTime
|
|
|
|
self.CenterPos = self.RotatorCmp:K2_GetComponentLocation()
|
|
self.StickZ = self.SM_Stick:K2_GetComponentLocation().Z
|
|
self.LastRotCmpForward = self.RotatorCmp:GetForwardVector()
|
|
self.LastRotCmpRight = self.RotatorCmp:GetRightVector()
|
|
|
|
if UGCGameSystem.IsServer() then
|
|
-- UGCSystemLibrary.BindBeginOverlapFunc(self.SM_Stick, self.StickOverlapPlayer, self)
|
|
else
|
|
self.HitParticle = UE.LoadObject(MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.AvoidingSpikeStick].GameParam.HitParticlePath)
|
|
end
|
|
end
|
|
|
|
function BP_AvoidingSpikeStick:StartPlay()
|
|
if self.bIsPlaying == false then
|
|
self.bIsPlaying = true
|
|
self.StartTime = UGCGameSystem.GameState:GetServerGameTime()
|
|
DOREPONCE(self, "StartTime")
|
|
DOREPONCE(self, "bIsPlaying")
|
|
end
|
|
end
|
|
|
|
function BP_AvoidingSpikeStick:StopPlay()
|
|
self.bIsPlaying = false
|
|
end
|
|
|
|
function BP_AvoidingSpikeStick:ReceiveTick(DeltaTime)
|
|
self.SuperClass.ReceiveTick(self, DeltaTime);
|
|
if self.bIsPlaying then
|
|
local NowServerTime = UGCGameSystem.GameState:GetServerGameTime()
|
|
local TimeDifference = NowServerTime - self.StartTime
|
|
local NowSpeed = self.BeginRotSpeed + (self.EndRotSpeed - self.BeginRotSpeed) * TimeDifference / self.PlayMaxTime
|
|
local RotYaw = TimeDifference * (NowSpeed + self.BeginRotSpeed) / 2
|
|
if UGCGameSystem.IsServer() then
|
|
self.RotatorCmp:K2_SetRelativeRotation({Roll = 0., Pitch = 0., Yaw = RotYaw})
|
|
self:CheckStickHitPlayer()
|
|
--local HitResult = self.SM_Stick:K2_SetRelativeRotation({Roll = 0., Pitch = 90., Yaw = RotYaw}, true)
|
|
--local HitActor = HitResult.Actor:Get()
|
|
--if HitActor then
|
|
-- UGCLogSystem.Log("[BP_AvoidingSpikeStick_ReceiveTick] ActorName:%s", KismetSystemLibrary.GetObjectName(HitActor))
|
|
-- if HitActor.PlayerKey then
|
|
-- UGCEventSystem.SendEvent(EventEnum.StickOverlapPlayer, HitActor.PlayerKey)
|
|
-- end
|
|
--
|
|
--end
|
|
else
|
|
|
|
self:CheckStickCrossingLocalPlayer()
|
|
self.RotatorCmp:K2_SetRelativeRotation({Roll = 0., Pitch = 0., Yaw = RotYaw})
|
|
end
|
|
end
|
|
end
|
|
|
|
--- 检测两帧棍棒扫过的区域内是否有玩家
|
|
function BP_AvoidingSpikeStick:CheckStickHitPlayer()
|
|
local RotCmpForward = self.RotatorCmp:GetForwardVector()
|
|
local RotCmpRight = self.RotatorCmp:GetRightVector()
|
|
RotCmpForward.Z = 0.
|
|
local AllPawn = UGCGameSystem.GetAllPlayerPawn()
|
|
for i, PlayerPawn in pairs(AllPawn) do
|
|
if PlayerPawn.PlayerKey then
|
|
if self:CheckCrossingPlayer(PlayerPawn, RotCmpForward, RotCmpRight) then
|
|
local PawnPos = PlayerPawn:K2_GetActorLocation()
|
|
-- 通过判断棍棒高度是否在玩家当前的高度区间内进行判断是否击中
|
|
if PawnPos.Z - 88.0 < self.StickZ and PawnPos.Z + 88.0 > self.StickZ then
|
|
-- UGCLogSystem.Log("[BP_AvoidingSpikeStick_ReceiveTick] PlayerKey:%s Hit", tostring(PlayerPawn.PlayerKey))
|
|
UGCEventSystem.SendEvent(EventEnum.StickOverlapPlayer, PlayerPawn.PlayerKey)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
self.LastRotCmpForward = RotCmpForward
|
|
self.LastRotCmpRight = RotCmpRight
|
|
end
|
|
|
|
--- 判断杆子越过本地玩家
|
|
function BP_AvoidingSpikeStick:CheckStickCrossingLocalPlayer()
|
|
local RotCmpForward = self.RotatorCmp:GetForwardVector()
|
|
local RotCmpRight = self.RotatorCmp:GetRightVector()
|
|
RotCmpForward.Z = 0.
|
|
local LocalPawn = UGCSystemLibrary.GetLocalPlayerPawn()
|
|
if UE.IsValid(LocalPawn) then
|
|
if self:CheckCrossingPlayer(LocalPawn, RotCmpForward, RotCmpRight) then
|
|
self:ClientStickCrossingLocalPlayerEffect()
|
|
end
|
|
end
|
|
self.LastRotCmpForward = RotCmpForward
|
|
self.LastRotCmpRight = RotCmpRight
|
|
|
|
end
|
|
|
|
--- 客户端扫过本地玩家触发特效或者音效
|
|
function BP_AvoidingSpikeStick:ClientStickCrossingLocalPlayerEffect()
|
|
SoundSystem.PlaySound(SoundSystem.ESound.BreakWind)
|
|
end
|
|
|
|
--- 判断杆子越过玩家
|
|
function BP_AvoidingSpikeStick:CheckCrossingPlayer(PlayerPawn, RotCmpForward, RotCmpRight)
|
|
local PawnPos = PlayerPawn:K2_GetActorLocation()
|
|
local ToPlayerDir = VectorHelper.Sub(PawnPos, self.CenterPos)
|
|
ToPlayerDir.Z = 0.
|
|
-- 判断该玩家是否在两帧划过的扇形内
|
|
-- 通过判断到玩家的向量与两帧的向前向量的余弦均为正 并且 该向量与两帧的向右向量的两余弦值的积为负
|
|
if VectorHelper.CosineValue(ToPlayerDir, RotCmpForward) > 0
|
|
and VectorHelper.CosineValue(ToPlayerDir, self.LastRotCmpForward) > 0
|
|
and VectorHelper.CosineValue(ToPlayerDir, RotCmpRight) * VectorHelper.CosineValue(ToPlayerDir, self.LastRotCmpRight) < 0
|
|
then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function BP_AvoidingSpikeStick:StickOverlapPlayer(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult)
|
|
if OtherActor and OtherActor.PlayerKey then
|
|
-- UGCEventSystem.SendEvent(EventEnum.StickOverlapPlayer, OtherActor.PlayerKey)
|
|
end
|
|
end
|
|
|
|
--[[
|
|
function BP_AvoidingSpikeStick:ReceiveEndPlay()
|
|
self.SuperClass.ReceiveEndPlay(self);
|
|
end
|
|
--]]
|
|
|
|
|
|
function BP_AvoidingSpikeStick:GetReplicatedProperties()
|
|
return
|
|
"StartTime",
|
|
"bIsPlaying"
|
|
end
|
|
|
|
|
|
--[[
|
|
function BP_AvoidingSpikeStick:GetAvailableServerRPCs()
|
|
return
|
|
end
|
|
--]]
|
|
|
|
function BP_AvoidingSpikeStick:ClientHitPlayerEffect(Pos)
|
|
UGCLogSystem.Log("[BP_AvoidingSpikeStick_ClientHitPlayerEffect]")
|
|
if self.HitParticle then
|
|
GameplayStatics.SpawnEmitterAtLocation(self, self.HitParticle,Pos, { Roll = 0, Pitch = 0, Yaw = 0 }, { X = 0.6, Y = 0.6, Z = 0.6 },true)
|
|
SoundSystem.PlaySound(SoundSystem.ESound.Impact)
|
|
end
|
|
end
|
|
|
|
return BP_AvoidingSpikeStick; |