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

1381 lines
59 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 UGCPlayerPawn_C:BP_UGCPlayerPawn_C
---@field P_HookFire_R UParticleSystemComponent
---@field P_HookFire_L UParticleSystemComponent
---@field P_HookFly_R UParticleSystemComponent
---@field P_HookFly_L UParticleSystemComponent
---@field SM_Gear_R UStaticMeshComponent
---@field SM_Gear_L UStaticMeshComponent
--Edit Below--
---@type UGCPlayerPawn_C
local UGCPlayerPawn = {
---@field ModifyDamageDelegation fun(DamageAmount:float,DamageEvent:FDamageEvent,EventInstigator:AController,DamageCauser:AActor):float
ModifyDamageDelegation = {};
-- MechanismEnergy = 0; -- 玩家拥有的能量
CachedSTCharacterMovementGravityScale = 1.0;
BaseCapsuleHalfHeight = 88.0;
BaseCapsuleRadius = 40;
CachedSTCharacterMovementGravityScale = 1.;
DashDuration = -1;
VelocityClampBase = 1200;
VelocityClamp = 1200;
bCanActiveSkill = false;
BaseJumpZVelocity = 443.0;
};
function UGCPlayerPawn:GetReplicatedProperties()
return
"DashImpulseEnergy",
"HookEnergy",
"LaunchEnergy"
end
-- 关闭盒子掉落
function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater)
return true
end
function UGCPlayerPawn:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
--- 设置翻墙功能
self.bVaultIsOpen = true
--- 设置滑铲功能
self.IsOpenShovelAbility = true
self.CachedSTCharacterMovementGravityScale = self.STCharacterMovement.GravityScale;
UGCEventSystem.SendEvent(EventEnum.PlayerBeginPlay, self)
--- 获取初始胶囊体信息
self.BaseCapsuleHalfHeight = self.CapsuleComponent.CapsuleHalfHeight
self.BaseCapsuleRadius = self.CapsuleComponent.CapsuleRadius
self.BaseJumpZVelocity = UGCPawnAttrSystem.GetJumpZVelocity(self)
if self:HasAuthority() then
self:AddEvent()
self:InitParam()
--- 循环判断当前武器配置是否正确,多则删、少则补
if UGCGameSystem.GameState:GetGameStateType() == CustomEnum.EGameState.Playing then
-- self.LoopCheckGradientWeaponHandle = UGCEventSystem.SetTimerLoop(self, self.CheckGradientWeapon, 1.)
--- 循环判断是否给予初始近战武器有则移除Handle没有则进行循环
-- self.AddDefaultMeleeWeaponHandle = UGCEventSystem.SetTimerLoop(self, self.AddDefaultMeleeWeapon, 1.)
end
if UE.IsValid(self:GetController()) then
self:ReceivePossessed(self:GetController())
UGCLogSystem.Log("[UGCPlayerPawn_ReceiveBeginPlay] Controller Is Valid")
end
--- 技能的初始化
self:SkillInit()
else
end
end
function UGCPlayerPawn:ReceiveEndPlay()
self:RemoveEvent()
self:SkillEndPlay()
self.SuperClass.ReceiveEndPlay(self);
end
function UGCPlayerPawn:CheckGradientWeapon()
WeaponGradientManager.UpdatePlayerGradientWeaponMatching(
self.PlayerKey,
UGCGameSystem.GameState:GetPlayerWeaponGrade(self.PlayerKey),
UGCGameSystem.GameState:GetPlayerDefaultMeleeWeaponByPlayerKey(self.PlayerKey)
)
end
function UGCPlayerPawn:AddDefaultMeleeWeapon()
local MeleeWeaponID = UGCGameSystem.GameState:GetPlayerDefaultMeleeWeaponByPlayerKey(self.PlayerKey)
if UGCBackPackSystem.GetItemCount(self, MeleeWeaponID) > 0 then
UGCEventSystem.StopTimer(self.AddDefaultMeleeWeaponHandle)
self.AddDefaultMeleeWeaponHandle = nil
else
UGCBackPackSystem.AddItem(self, MeleeWeaponID, 1)
end
end
function UGCPlayerPawn:InitParam()
-- self:SetMechanismEnergy(GlobalConfigs.GameSetting.InitEnergy)
end
function UGCPlayerPawn:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
self:TickSkill(DeltaTime)
if not UGCGameSystem.IsServer() then
self:ClientMustBeExeBeginPlay()
end
self.CharacterMovement.Velocity = KismetMathLibrary.ClampVectorSize(self.CharacterMovement.Velocity, 0, self:GetVelocityClamp())
end
function UGCPlayerPawn:GetVelocityClamp()
return self.VelocityClamp
end
function UGCPlayerPawn:SetVelocityClamp(NewVelocityClamp)
self.VelocityClamp = NewVelocityClamp
end
--- 客户端必定执行的BeginPlay
function UGCPlayerPawn:ClientMustBeExeBeginPlay()
if self.DoOnceMustBeExeBeginPlay then return end
self.DoOnceMustBeExeBeginPlay = true
UGCEventSystem.SendEvent(EventEnum.PlayerPossessed)
--- 技能的初始化
self:SkillInit()
UGCPawnAttrSystem.SetCanSwitchFPP(self, true)
end
function UGCPlayerPawn:AddEvent()
if self:HasAuthority() then
self.DeadNotifyDelegate:Add(self.PlayerDeadCallBack, self)
self.DamageNotifyDelegate:Add(self.PlayerInjury, self)
else
end
end
function UGCPlayerPawn:RemoveEvent()
if self:HasAuthority() then
self.DeadNotifyDelegate:Remove(self.PlayerDeadCallBack, self)
self.DamageNotifyDelegate:Remove(self.PlayerInjury, self)
if self.LoopCheckGradientWeaponHandle then
UGCEventSystem.StopTimer(self.LoopCheckGradientWeaponHandle)
self.LoopCheckGradientWeaponHandle = nil
end
if self.AddDefaultMeleeWeaponHandle then
UGCEventSystem.StopTimer(self.AddDefaultMeleeWeaponHandle)
self.AddDefaultMeleeWeaponHandle = nil
end
else
end
end
function UGCPlayerPawn:ReceivePossessed(NewController)
self.SuperClass.ReceivePossessed(self, NewController);
UGCLogSystem.Log("[UGCPlayerPawn_ReceivePossessed] PlayerKey:%s", tostring(NewController.PlayerKey))
UGCEventSystem.SendEvent(EventEnum.PlayerPossessed, NewController.PlayerKey)
-- UGCSendRPCSystem.RPCEvent(NewController.PlayerKey, EventEnum.PlayerPossessed, NewController.PlayerKey)
if GlobalConfigs.GameSetting.ReadyCanNotMove and UGCGameSystem.GameState:GetReadyTime() > 0 then
UGCLogSystem.Log("[UGCPlayerPawn_ReceivePossessed] Set SpeedScale")
self:SetCanActionable(false)
else
self:SetCanActionable(true)
end
-- UGCSendRPCSystem.ActorRPCNotify(nil, self, "InitHook", NewController.PlayerKey)
end
function UGCPlayerPawn:SetCanActionable(IsActionable)
self:SetCanActiveSkill(IsActionable)
--local SpeedScale = (IsActionable and 1. or 0.01)
--UGCPawnAttrSystem.SetSpeedScale(self, SpeedScale)
-- UGCPawnSystem.DisabledPawnState(self, EPawnState.Move, not IsActionable);
UGCSystemLibrary.SetPlayerPawnMoveable(self, IsActionable)
end
function UGCPlayerPawn:SetCanActiveSkill(IsActive)
self.bCanActiveSkill = IsActive
end
-------------------------------------------------- Delegate --------------------------------------------------
---@param DamageInfo FDamageInfoCollection
---@return VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue uint, uint, int, EDamageType, bool, float, float
function UGCPlayerPawn:GetDamageInfoCollectionInfo(DamageInfo)
local CauserController = DamageInfo.Instigator
local WeaponID = -1
local CauserKey = CauserController and CauserController.PlayerKey or -1
local VictimKey = self.PlayerKey
local CauserItemID = DamageInfo.CauserItemID
--- 近战投掷、投掷手雷
if CauserItemID then
WeaponID = CauserItemID
end
UGCLogSystem.Log("[UGCPlayerPawn_GetDamageInfoCollectionInfo] WeaponID:%d", WeaponID)
local Distance = 0.
if CauserController and CauserController.Pawn then
Distance = VectorHelper.GetDistance(self:K2_GetActorLocation(), CauserController.Pawn:K2_GetActorLocation())
end
local IsHeadShotDamage = (DamageInfo.Hit.BoneName == "head")
return VictimKey, CauserKey, WeaponID, DamageInfo.DamageType, IsHeadShotDamage, Distance, DamageInfo.Damage
end
---@param DamageInfo FDamageInfoCollection
function UGCPlayerPawn:PlayerDeadCallBack(DamageInfo)
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
local DeadPS = UGCGameSystem.GetPlayerStateByPlayerKey(VictimKey)
local Assister = -1
if DeadPS then
Assister = DeadPS:GetAssister(CauserKey, GlobalConfigs.GameSetting.AssistDamage)
end
UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue, Assister)
UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue, Assister)
end
---@param DamageInfo FDamageInfoCollection
---@param ReturnValue float
function UGCPlayerPawn:PlayerInjury(DamageInfo)
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
self.PlayerState:UpdatePlayerInjuryInfo(VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
UGCEventSystem.SendEvent(EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
UGCSendRPCSystem.RPCEvent(CauserKey, EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
end
------------------------------------------------ Delegate End ------------------------------------------------
function UGCPlayerPawn:AddMechanismEnergy(InEnergy)
self:SetMechanismEnergy(self:GetMechanismEnergy() + InEnergy)
end
function UGCPlayerPawn:GetMechanismEnergy()
return self.MechanismEnergy
end
function UGCPlayerPawn:SetMechanismEnergy(NewEnergy)
self.MechanismEnergy = (NewEnergy > 0 and NewEnergy or 0)
end
------------------------------------------------ ModifyDamage ------------------------------------------------
function UGCPlayerPawn:UGC_TakeDamageOverrideEvent(Damage, DamageType, EventInstigator, DamageCauser, Hit)
local DamageAmount = Damage
UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] InDamageAmount:%s", tostring(DamageAmount))
if EventInstigator and EventInstigator.PlayerKey then
local CauserTeamID = UGCPlayerStateSystem.GetTeamID(EventInstigator.PlayerKey)
local SelfTeamID = UGCPlayerStateSystem.GetTeamID(self.PlayerKey)
if DamageType == EDamageType.UGCPointDamage then
DamageAmount = (CauserTeamID == SelfTeamID and MechanismConfig.MechanismFriendlyInjuryRatio * DamageAmount or DamageAmount)
else
if EventInstigator.PlayerKey == self.PlayerKey then
--- 对自己的伤害
if GlobalConfigs.GameSetting.bEnableSelfHarm then
DamageAmount = GlobalConfigs.GameSetting.SelfHarmInjuryRatio * DamageAmount
else
DamageAmount = 0
end
else
--- 伤害设置(友方、敌方)
DamageAmount = (CauserTeamID == SelfTeamID and GlobalConfigs.GameSetting.FriendlyInjuryRatio * DamageAmount or DamageAmount)
end
end
elseif DamageCauser and DamageCauser:GetOwner() then
UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] DamageCauser:GetOwner():%s", KismetSystemLibrary.GetObjectName(DamageCauser:GetOwner()))
local TargetPlayerKey = DamageCauser:GetOwner().PlayerKey
if TargetPlayerKey then
local CauserTeamID = UGCPlayerStateSystem.GetTeamID(TargetPlayerKey)
local SelfTeamID = UGCPlayerStateSystem.GetTeamID(self.PlayerKey)
DamageAmount = (CauserTeamID == SelfTeamID and GlobalConfigs.GameSetting.FriendlyInjuryRatio * DamageAmount or DamageAmount)
end
else
--- 掉落伤害
DamageAmount = GlobalConfigs.GameSetting.bEnableDropDamage and DamageAmount or 0.
end
UGCLogSystem.Log("[UGCPlayerPawn_UGC_TakeDamageOverrideEvent] ModifyDamageAmount:%s", tostring(DamageAmount))
return DamageAmount
end
---------------------------------------------- ModifyDamage End ----------------------------------------------
function UGCPlayerPawn:ScalePlayer(NewScale)
if UGCGameSystem.IsServer() then
self:SetPlayerScale_N(NewScale)
UGCLogSystem.Log("[UGCPlayerPawn_ScalePlayer]")
UGCSendRPCSystem.ActorRPCNotify(nil, self, "SetPlayerScale_N", NewScale)
UGCLogSystem.Log("[UGCPlayerPawn_ScalePlayer] Finish")
end
end
function UGCPlayerPawn:SetPlayerScale_N(NewScale)
UGCLogSystem.Log("[UGCPlayerPawn_SetPlayerScale_N]")
local HalfHeight = self.BaseCapsuleHalfHeight * NewScale
self.Mesh:SetWorldScale3D({X = NewScale, Y = NewScale, Z = NewScale})
self.CapsuleComponent:SetCapsuleHalfHeight(HalfHeight, true)
self.CapsuleComponent:SetCapsuleRadius(self.BaseCapsuleRadius * NewScale, true)
self.Mesh:K2_SetRelativeLocation({X = 0, Y = 0, Z = HalfHeight})
UGCLogSystem.Log("[UGCPlayerPawn_SetPlayerScale_N] Finish")
end
---------------------------------------------------------- TurnOffGravityScale ----------------------------------------------------------
--- 关闭重力影响
---@param On bool
function UGCPlayerPawn:TurnOffGravityScale(On)
if On then
-- self:SetGravityScaleAuthorized(0.01); -- 参考钩爪技能内部实现
self.STCharacterMovement.GravityScale = 0;
--self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Flying);
else
-- self:SetGravityScaleAuthorized(self.CachedGravityScaleAuthorized); -- ,不能用这个函数,底层恢复有问题
self.STCharacterMovement.GravityScale = self.CachedSTCharacterMovementGravityScale;
--self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling);
end
end
-------------------------------------------------------- TurnOffGravityScale End --------------------------------------------------------
------------------------------------------------------- LaunchSkill -------------------------------------------------------
----------------------------------------------------- LaunchSkill End -----------------------------------------------------
UGCPlayerPawn.LaunchZSpeed = 2000
--- Launch的消耗限制
UGCPlayerPawn.LaunchEnergy = 0.
UGCPlayerPawn.LaunchEnergyCost = 100.
UGCPlayerPawn.LaunchEnergyRecoverySpeed = 20.
UGCPlayerPawn.LaunchMaxEnergy = 200
UGCPlayerPawn.bJumpingOnTheGround = false
function UGCPlayerPawn:LaunchSkill()
if UGCGameSystem.IsServer() then
if not self.bCanActiveSkill then
return
end
end
if not GlobalConfigs.IsDebug then
if self:CheckLaunch() then
if self.bJumpingOnTheGround and self.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Walking then
UGCSendRPCSystem.RPCEvent(self.PlayerKey, EventEnum.AddTip, TipConfig.TipType.LaunchFailure)
return
end
self.LaunchEnergy = self.LaunchEnergy - self.LaunchEnergyCost
else
return
end
end
-- Test
-- self.CharacterMovement.Velocity = VectorHelper.VectorZero()
-- TestEnd
local AddSpeed = {X = 0, Y = 0, Z = self.LaunchZSpeed}
--if self.CharacterMovement.Velocity.Z < 0 then
-- AddSpeed = Vector.New(0, 0, self.LaunchZSpeed - self.CharacterMovement.Velocity.Z)
-- self.CharacterMovement:AddImpulse(AddSpeed, true)
--elseif self.CharacterMovement.Velocity.Z == 0 then
-- self.CharacterMovement:AddImpulse(AddSpeed, true)
--else
-- self.CharacterMovement:AddImpulse(AddSpeed, true)
--end
-- 和平在移动方面做了处理无法全部使用AddImpulse或者直接设置速度因此采用增加最大跳跃次数和初次跳跃采用设置速度的方式进行。
local IsWalking = false
if self.CharacterMovement.MovementMode == EMovementMode.MOVE_Walking then
IsWalking = true
self.CharacterMovement.MovementMode = EMovementMode.MOVE_Falling
self.CharacterMovement.Velocity = { X = self.CharacterMovement.Velocity.X, Y = self.CharacterMovement.Velocity.Y, Z = self.LaunchZSpeed }
else
if self.JumpCurrentCount == self.JumpMaxCount then
self.JumpMaxCount = self.JumpMaxCount + 1
end
UGCPawnAttrSystem.SetJumpZVelocity(self, self.LaunchZSpeed)
self:Jump()
UGCEventSystem.SetTimer(self, function() UGCPawnAttrSystem.SetJumpZVelocity(self, self.BaseJumpZVelocity) end, 0.01)
end
UGCSendRPCSystem.ActorRPCNotify(nil, self, "ClientLaunch", self.PlayerKey, AddSpeed, self.JumpMaxCount, IsWalking)
-- UGCSendRPCSystem.ActorRPCNotify(nil, self, "ClientLaunchEffect", self.PlayerKey)
end
function UGCPlayerPawn:ClientLaunch(PlayerKey, InAddSpeed, InJumpMaxCount, IsWalking)
self:ClientLaunchEffect(PlayerKey)
if IsWalking then
self.CharacterMovement.MovementMode = EMovementMode.MOVE_Falling
self.CharacterMovement.Velocity = { X = self.CharacterMovement.Velocity.X, Y = self.CharacterMovement.Velocity.Y, Z = self.LaunchZSpeed }
else
self.JumpMaxCount = InJumpMaxCount
self:Jump()
end
end
function UGCPlayerPawn:CheckLaunch()
return UGCGameSystem.GameState:GetEnablePlayerSkill(CustomEnum.EPlayerSkill.Launch) and self.LaunchEnergy >= self.LaunchEnergyCost
end
function UGCPlayerPawn:LaunchTick(DeltaTime)
self:AddLaunchEnergy(DeltaTime)
-- 这里通过设置玩家的跳跃按键的碰撞来限制玩家使用跳跃的最大次数,保证了弹射的使用
if self.CharacterMovement.MovementMode == EMovementMode.MOVE_Walking then
self.JumpMaxCount = 2
-- UGCPawnAttrSystem.SetJumpZVelocity(self, self.BaseJumpZVelocity)
if not UGCGameSystem.IsServer() then
if self.JumpBtn == nil then
self.JumpBtn = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C").ShootingUIPanel.CustomJumpBtn
end
self.JumpBtn:SetVisibility(ESlateVisibility.Visible)
end
else
-- UGCPawnAttrSystem.SetJumpZVelocity(self, self.LaunchZSpeed)
if not UGCGameSystem.IsServer() then
if self.JumpBtn == nil then
self.JumpBtn = GameBusinessManager.GetWidgetFromName(ingame, "MainControlPanelTochButton_C").ShootingUIPanel.CustomJumpBtn
end
self.JumpBtn:SetVisibility(ESlateVisibility.HitTestInvisible)
end
end
end
function UGCPlayerPawn:AddLaunchEnergy(DeltaTime)
self.LaunchEnergy = math.clamp(self.LaunchEnergy + DeltaTime * self.LaunchEnergyRecoverySpeed, 0, self.LaunchMaxEnergy)
end
function UGCPlayerPawn:ClientLaunchEffect(InPlayerKey)
if InPlayerKey == UGCSystemLibrary.GetLocalPlayerKey() then
SoundSystem.PlaySound(SoundSystem.ESound.Impulse)
end
self.P_HookFly_L:SetActive(true, true)
self.P_HookFly_R:SetActive(true, true)
self:AddFlyEffect(2.5)
end
function UGCPlayerPawn:AddFlyEffect(Time)
if self.FlyEffectHandle then
UGCEventSystem.StopTimer(self.FlyEffectHandle)
end
self.FlyEffectHandle = UGCEventSystem.SetTimer(self, function()
self.P_HookFly_L:SetActive(false, false)
self.P_HookFly_R:SetActive(false, false)
self.FlyEffectHandle = nil
end, Time)
end
------------------------------------------------------- DashImpulseSkill -------------------------------------------------------
UGCPlayerPawn.MinDashVelocity = 2400
UGCPlayerPawn.MaxDashVelocity = 3600
--- 冲量强度 /s
UGCPlayerPawn.ImpulseStrength = 10000
--- 移动范围(帧计算会有一点偏差)超过范围自动停止
UGCPlayerPawn.TargetDashLength = 1500
--- 最大冲刺时长
UGCPlayerPawn.DashMaxTime = 0.5
--- Dash的消耗限制
UGCPlayerPawn.DashImpulseEnergy = 0.
UGCPlayerPawn.DashImpulseEnergyCost = 100.
UGCPlayerPawn.EnergyRecoverySpeed = 20.
UGCPlayerPawn.DashImpulseMaxEnergy = 200
function UGCPlayerPawn:InitDashImpulse()
if (self.bInitedDashImpulse == nil or (not self:GetDashImpulseOverlapComponent():IsActive()) ) and UGCGameSystem.IsServer() then
self.bInitedDashImpulse = true
self.BP_PawnAuxiliaryOverlapCap:SetActive(true)
self:GetDashImpulseOverlapComponent():SetActive(true)
-- Pawn增加的碰撞盒都没效果
self:GetDashImpulseOverlapComponent().OnComponentBeginOverlap:Add(self.DashCollisionCapsuleBeginOverlap, self)
UGCLogSystem.Log("[UGCPlayerPawn_InitDashImpulse] Finish DashCollisionCapsuleIsActive:%s", tostring(self:GetDashImpulseOverlapComponent():IsActive()))
end
end
function UGCPlayerPawn:GetDashImpulseOverlapComponent()
return self.BP_PawnAuxiliaryOverlapCap.ChildActor.Capsule
end
function UGCPlayerPawn:DashCollisionCapsuleBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult)
UGCLogSystem.Log("[UGCPlayerPawn_DashCollisionCapsuleBeginOverlap] OtherActor:%s", KismetSystemLibrary.GetObjectName(OtherActor))
self:StopDashImpulse()
end
--- 冲量冲刺
---@param ForwardDir FVector 为nil则使用玩家向前向量作为方向
---@param InStartDashPos FVector 调用时无需传入
function UGCPlayerPawn:DashImpulse(ForwardDir, InStartDashPos)
--local CameraForward = self:GetController().PlayerCameraManager:GetActorForwardVector()
if self.ImpulseDashing then
return
end
if UGCGameSystem.IsServer() then
if not self.bCanActiveSkill then
return
end
end
if self:CheckDashImpulse() then
self.DashImpulseEnergy = self.DashImpulseEnergy - self.DashImpulseEnergyCost
else
return
end
-- self:InitDashImpulse()
self:SetCanActiveSkill(false)
self.ImpulseDashing = true
self:TurnOffGravityScale(true)
self:SetVelocityClamp(self.MaxDashVelocity)
if ForwardDir == nil then
self.ImpulseDir = VectorHelper.ToLuaTable(self:GetActorForwardVector())
else
self.ImpulseDir = ForwardDir
end
-- 给予一个初始冲量
UGCLogSystem.Log("[UGCPlayerPawn_DashImpulse] ImpulseDir:%s", VectorHelper.ToString(self.ImpulseDir))
self.CharacterMovement.Velocity = VectorHelper.MulNumber(self.ImpulseDir, VectorHelper.Length(self.CharacterMovement.Velocity))
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(self.ImpulseDir, self.ImpulseStrength * 0.4), true)
-- 给予一个初始速度
-- self.CharacterMovement.Velocity = VectorHelper.MulNumber(self.ImpulseDir, 1200)
if UGCGameSystem.IsServer() then
self.StartDashPos = VectorHelper.ToLuaTable(self:K2_GetActorLocation())
else
-- self.StartDashPos = InStartDashPos
self:DashEffect()
end
--self.StopImpulseDashHandle = UGCEventSystem.SetTimer(self, self.StopDashImpulse, self.DashMaxTime)
if UGCGameSystem.IsServer() then
UGCSendRPCSystem.ActorRPCNotify(nil, self, "DashImpulse", self.ImpulseDir)
self.StopImpulseDashHandle = UGCEventSystem.SetTimer(self, function()
self.StopImpulseDashHandle = nil
self:StopDashImpulse()
end, self.DashMaxTime)
end
end
function UGCPlayerPawn:DashEffect()
if self.PlayerKey == UGCSystemLibrary.GetLocalPlayerKey() then
SoundSystem.PlaySound(SoundSystem.ESound.Impulse)
end
self:AddFlyEffect(2.5)
end
function UGCPlayerPawn:StopDashImpulse()
if not self.ImpulseDashing then
return
end
self:TurnOffGravityScale(false)
self.CharacterMovement.Velocity = VectorHelper.VectorZero()
self:SetVelocityClamp(self.VelocityClampBase)
if UGCGameSystem.IsServer() then
if self.StopImpulseDashHandle then
UGCEventSystem.StopTimer(self.StopImpulseDashHandle)
self.StopImpulseDashHandle = nil
end
UGCSendRPCSystem.ActorRPCNotify(nil, self, "StopDashImpulse")
end
self.ImpulseDashing = false
self:SetCanActiveSkill(true)
end
function UGCPlayerPawn:AddDashImpulseEnergy(DeltaTime)
self.DashImpulseEnergy = math.clamp(self.DashImpulseEnergy + DeltaTime * self.EnergyRecoverySpeed, 0, self.DashImpulseMaxEnergy)
end
function UGCPlayerPawn:CheckDashImpulse()
return UGCGameSystem.GameState:GetEnablePlayerSkill(CustomEnum.EPlayerSkill.Dash) and self.DashImpulseEnergy >= self.DashImpulseEnergyCost
end
function UGCPlayerPawn:DashImpulseTick(DeltaTime)
self:AddDashImpulseEnergy(DeltaTime)
if self.ImpulseDashing then
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(self.ImpulseDir, self.ImpulseStrength * DeltaTime), true)
if self.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Falling then
self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling);
end
-- self.CharacterMovement.Velocity = KismetMathLibrary.ClampVectorSize(self.CharacterMovement.Velocity, self.MinDashVelocity, self.MaxDashVelocity)
self.CharacterMovement.Velocity = VectorHelper.MulNumber(self.ImpulseDir, math.clamp(VectorHelper.Length(self.CharacterMovement.Velocity), self.MinDashVelocity, self.MaxDashVelocity))
if UGCGameSystem.IsServer() then
if VectorHelper.Length(VectorHelper.Sub(self:K2_GetActorLocation(), self.StartDashPos)) > self.TargetDashLength then
self:StopDashImpulse()
end
end
end
end
----------------------------------------------------- DashImpulseSkill End -----------------------------------------------------
------------------------------------------------------- DashImpulseSkill2 -------------------------------------------------------
UGCPlayerPawn.Dash2_ForwardStrength = 4000
UGCPlayerPawn.Dash2_UpStrength = 500
function UGCPlayerPawn:DashImpulse2(DashDir)
if UGCGameSystem.IsServer() then
DashDir = VectorHelper.ToLuaTable(self:GetActorForwardVector())
UGCSendRPCSystem.ActorRPCNotify(nil, self, "DashImpulse2", DashDir)
end
self:SetVelocityClamp(4800)
--self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(DashDir, self.Dash2_ForwardStrength), true)
self.CharacterMovement:AddImpulse({X = 0., Y = 0., Z = math.clamp(self.Dash2_UpStrength - self.CharacterMovement.Velocity.Z, 0, 1e5)}, true)
UGCEventSystem.SetTimer(self, function()
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(DashDir, self.Dash2_ForwardStrength), true)
--self.CharacterMovement:AddImpulse({X = 0., Y = 0., Z = math.clamp(self.Dash2_UpStrength - self.CharacterMovement.Velocity.Z, 0, 1e5)}, true)
end, 0.1)
UGCEventSystem.SetTimer(self, function()
self:SetVelocityClamp(self.VelocityClampBase)
end, 2)
end
----------------------------------------------------- DashImpulseSkill2 End -----------------------------------------------------
----------------------------------------------------------- HookSkill -----------------------------------------------------------
--- 正在执行钩锁技能
UGCPlayerPawn.bHooking = false
--- 钩锁飞行时间
UGCPlayerPawn.HookFlyTime = 0.2
--- 推动玩家最大持续时间
UGCPlayerPawn.PullPlayerMaxTime = 4.
--- 第二次检测钩锁附着点时球体的半径
UGCPlayerPawn.SmartAimMediumTraceRadius = 300.
--- 第三次检测钩锁附着点时球体的半径
UGCPlayerPawn.SmartAimLargeTraceRadius = 700.
--- 单钩的第二次检测
UGCPlayerPawn.OneHookSecondTraceRadius = 100.
--- 检测距离
UGCPlayerPawn.HookMaxDis = 6000.
UGCPlayerPawn.TwoHookTraceMaxDis = 30000.
UGCPlayerPawn.SmallSphereStartDis = 800
UGCPlayerPawn.BigSphereStartDis = 1500
UGCPlayerPawn.OneHookSecondTraceStartDis = 300
--- 是否为双发的钩锁,单发则从准星位置发射
UGCPlayerPawn.EnableTwoHook = true
--- 正在拉动玩家
UGCPlayerPawn.bHookPullingPlayer = false
--- Hook在玩家身上发射出去的插槽名字
--UGCPlayerPawn.HookSocketName_R = "thigh_r"
--UGCPlayerPawn.HookSocketName_L = "thigh_l"
UGCPlayerPawn.HookSocketName_Mid = "spine_01"
UGCPlayerPawn.GearPropertyName_R = "SM_Gear_R"
UGCPlayerPawn.GearPropertyName_L = "SM_Gear_L"
UGCPlayerPawn.GearSocketName = "HookStart"
--- 绘制检测线条
UGCPlayerPawn.bEnableDrawDebug = false
UGCPlayerPawn.bEnableDrawDebug_Client = false
--- 给予的初始冲量
UGCPlayerPawn.StartHookPullImpulse = 3200
--- 给予的持续冲量/s
UGCPlayerPawn.HookPullImpulse = 3000
--- 速度范围
UGCPlayerPawn.MinPullVelocity = 1800
UGCPlayerPawn.MaxPullVelocity = 3000
--- 通过判断自动停止Pull
UGCPlayerPawn.bAutoStopHookPush = true
--- 单条钩锁模式时,结束后给予的向上冲量
UGCPlayerPawn.SimpleHookUpImpulse = 700
--- 单条钩锁模式时,结束后给予的向上冲量的触发距离的阈值,玩家距离目标位置小于此阈值则触发自动停止拉动且向上给予冲量
UGCPlayerPawn.UpImpulseDistanceThreshold = 100
--- 表示按下Hook技能后还启用了拉力
UGCPlayerPawn.EnabledHookPull = false
--- Hook的消耗限制
UGCPlayerPawn.HookEnergy = 0.
UGCPlayerPawn.HookEnergyCost = 100.
UGCPlayerPawn.HookEnergyRecoverySpeed = 1000.
UGCPlayerPawn.HookMaxEnergy = 100
--function UGCPlayerPawn:SetEnableTwoHook(InEnableTwoHook)
-- if UGCGameSystem.IsServer() then
-- if not self.bHooking and self.EnableTwoHook ~= InEnableTwoHook then
-- self.EnableTwoHook = InEnableTwoHook
-- UGCSendRPCSystem.ActorRPCNotify(nil, self,"SetEnableTwoHook", InEnableTwoHook)
-- end
-- else
-- if self.EnableTwoHook ~= InEnableTwoHook then
-- self.EnableTwoHook = InEnableTwoHook
-- if self.PlayerKey == UGCSystemLibrary.GetLocalPlayerKey() then
-- UGCEventSystem.SendEvent(EventEnum.HookNumChange, InEnableTwoHook)
-- end
-- end
-- if self.EnableTwoHook == false then
-- WidgetManager:ClosePanel(WidgetConfig.EUIType.HookTrace)
-- end
-- end
--end
function UGCPlayerPawn:GetHook(IsRight, InPlayerKey)
local TargetHook = self.LeftHook
if IsRight then
TargetHook = self.RightHook
end
if not UE.IsValid(TargetHook) then
local AllHook = GameplayStatics.GetAllActorsOfClass(self, ObjectPathTable.BP_Hook_Class, {})
UGCLogSystem.Log("[UGCPlayerPawn_GetHook] #AllHook:%s, IsRight:%s, InPlayerKey:%s", tostring(#AllHook), tostring(IsRight), tostring(InPlayerKey))
local NoOwnerHook = nil
for i, v in pairs(AllHook) do
local PlayerKey, TempIsRight = v:GetOwnerPlayer()
if InPlayerKey == PlayerKey and TempIsRight == IsRight then
return v
elseif PlayerKey == nil and NoOwnerHook == nil then
NoOwnerHook = v
end
end
if NoOwnerHook then
NoOwnerHook:SetPlayerKey(InPlayerKey, IsRight)
return NoOwnerHook
end
end
return TargetHook
end
function UGCPlayerPawn:InitHook()
--if self.DoOnceInitHook then return end
--self.DoOnceInitHook = true
---@field K2_AttachToComponent:fun(Parent:USceneComponent,SocketName:FName,LocationRule:EAttachmentRule,RotationRule:EAttachmentRule,ScaleRule:EAttachmentRule,bWeldSimulatedBodies:bool):bool
UGCLogSystem.Log("[UGCPlayerPawn_InitHook]")
self.SM_Gear_L:SetVisibility(true, true)
self.SM_Gear_R:SetVisibility(true, true)
self.SM_Gear_L:SetHiddenInGame(false);
self.SM_Gear_R:SetHiddenInGame(false);
self.SM_Gear_L:K2_AttachToComponent(self.Mesh, self.HookSocketName_Mid, EAttachmentRule.KeepRelative, EAttachmentRule.KeepRelative, EAttachmentRule.KeepRelative, true)
self.SM_Gear_R:K2_AttachToComponent(self.Mesh, self.HookSocketName_Mid, EAttachmentRule.KeepRelative, EAttachmentRule.KeepRelative, EAttachmentRule.KeepRelative, true)
self.SM_Gear_L:K2_SetRelativeLocation({X=-5,Y=-10,Z=22})
self.SM_Gear_L:K2_SetRelativeRotation({Pitch=0,Yaw=-90,Roll=90})
self.SM_Gear_R:K2_SetRelativeLocation({X=-5,Y=-10,Z=-22})
self.SM_Gear_R:K2_SetRelativeRotation({Pitch=0,Yaw=-90,Roll=90})
UGCLogSystem.Log("[UGCPlayerPawn_InitHook] End")
end
function UGCPlayerPawn:DetachHookMesh()
--UGCLogSystem.Log("[UGCPlayerPawn_DetachHookMesh]")
--self.SM_Gear_L:DetachFromParent(true, true)
--self.SM_Gear_R:DetachFromParent(true, true)
end
function UGCPlayerPawn:AddHookEnergy(DeltaTime)
self.HookEnergy = math.clamp(self.HookEnergy + DeltaTime * self.HookEnergyRecoverySpeed, 0, self.HookMaxEnergy)
end
function UGCPlayerPawn:CheckCanHook()
return UGCGameSystem.GameState:GetEnablePlayerSkill(CustomEnum.EPlayerSkill.Hook) and self.HookEnergy >= self.HookEnergyCost
end
function UGCPlayerPawn:HookSkill(CameraForward, InIsTwoHook)
UGCLogSystem.Log("[UGCPlayerPawn_HookSkill]")
if (not UGCGameSystem.IsServer()) or self.bHooking or (not self.bCanActiveSkill) then
return
end
if self:CheckCanHook() then
self.HookEnergy = self.HookEnergy - self.HookEnergyCost
else
return
end
self.AutoStopHookHandle = UGCEventSystem.SetTimer(self, self.StopHookSkill, self.PullPlayerMaxTime)
self:SetCanActiveSkill(false)
self.EnableTwoHook = InIsTwoHook
self.bHooking = true
self.SmartAimLeftFound, self.SmartAimLocationLeft = self:FindHookAttachmentPoint(false, CameraForward)
--UGCLogSystem.Log("[UGCPlayerPawn_HookSkill] SmartAimLocationLeft:%s", VectorHelper.ToString(self.SmartAimLocationLeft))
if self.EnableTwoHook then
self.SmartAimRightFound, self.SmartAimLocationRight = self:FindHookAttachmentPoint(true, CameraForward)
--UGCLogSystem.Log("[UGCPlayerPawn_HookSkill] SmartAimLocationRight:%s", VectorHelper.ToString(self.SmartAimLocationRight))
end
UGCSendRPCSystem.ActorRPCNotify(nil, self, "FireHook", self.EnableTwoHook, self.SmartAimLeftFound, self.SmartAimLocationLeft, self.SmartAimRightFound, self.SmartAimLocationRight)
if self.SmartAimLeftFound or (self.EnableTwoHook and self.SmartAimRightFound) then
--- 待钩锁勾住时拉动玩家
self.EnableHookPullPlayerHandle = UGCEventSystem.SetTimer(self, self.EnableHookPullPlayer, self.HookFlyTime)
end
end
function UGCPlayerPawn:StopHookSkill()
UGCLogSystem.Log("[UGCPlayerPawn_StopHookSkill]")
if not UGCGameSystem.IsServer() or not self.bHooking or self.SetNotHookingHandle then
return
end
UGCLogSystem.Log("[UGCPlayerPawn_StopHookSkill] Start")
if self.AutoStopHookHandle then
UGCEventSystem.StopTimer(self.AutoStopHookHandle)
self.AutoStopHookHandle = nil
end
self:SetCanActiveSkill(true)
if self.EnableHookPullPlayerHandle then
UGCEventSystem.StopTimer(self.EnableHookPullPlayerHandle)
self.EnableHookPullPlayerHandle = nil
end
--- 停止拉动玩家
self:DisableHookPullPlayer()
UGCLogSystem.Log("[UGCPlayerPawn_StopHookSkill] DisableHookPullPlayer Finish")
--- 收回钩锁
UGCSendRPCSystem.ActorRPCNotify(nil, self, "RecoverHook")
--- 待钩锁收回后设置bHooking = false
self.SetNotHookingHandle = UGCEventSystem.SetTimer(self, function()
self.bHooking = false
self.SetNotHookingHandle = nil
end, self.HookFlyTime)
end
function UGCPlayerPawn:EnableHookPullPlayer()
-- UGCLogSystem.Log("[UGCPlayerPawn_EnableHookPullPlayer]")
self:SetVelocityClamp(self.MaxPullVelocity)
self.EnabledHookPull = true
self.EnableHookPullPlayerHandle = nil
self.bHookPullingPlayer = true
self:TurnOffGravityScale(true)
-- local PullDir = self:GetHookPullDir()
self:GetHookPullDir()
self.StartPullDir = table.DeepCopy(self.HookPullDir)
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(self.HookPullDir, self.StartHookPullImpulse), true)
self.CharacterMovement.Velocity = VectorHelper.MulNumber(self.HookPullDir, VectorHelper.Length(self.CharacterMovement.Velocity))
if UGCGameSystem.IsServer() then
UGCSendRPCSystem.ActorRPCNotify(nil, self, "EnableHookPullPlayer")
else
self:HookPullEffect()
end
end
function UGCPlayerPawn:DisableHookPullPlayer()
UGCLogSystem.Log("[UGCPlayerPawn_DisableHookPullPlayer]")
self:SetVelocityClamp(self.VelocityClampBase)
self.bHookPullingPlayer = false
self:TurnOffGravityScale(false)
--if not self.EnableTwoHook and self.EnabledHookPull then
if self.EnabledHookPull then
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber({ X = 0, Y = 0, Z = 1 }, self.SimpleHookUpImpulse), true)
end
self.EnabledHookPull = false
if UGCGameSystem.IsServer() then
UGCSendRPCSystem.ActorRPCNotify(nil, self, "DisableHookPullPlayer")
else
self:DisableHookPullEffect()
end
UGCLogSystem.Log("[UGCPlayerPawn_DisableHookPullPlayer] Finish")
end
--- 获取发射位置,仅客户端执行
function UGCPlayerPawn:GetHookFireStartPos(IsRight)
if IsRight then
return self.SM_Gear_R:GetSocketLocation(self.GearSocketName)
else
return self.SM_Gear_L:GetSocketLocation(self.GearSocketName)
end
end
function UGCPlayerPawn:GetHookMesh(IsRight)
if IsRight then
return self.SM_Gear_R
else
return self.SM_Gear_L
end
end
--- 发射钩抓
function UGCPlayerPawn:FireHook(InEnableTwoHook, InSmartAimLeftFound, InSmartAimLocationLeft, InSmartAimRightFound, InSmartAimLocationRight)
-- UGCLogSystem.Log("[UGCPlayerPawn_FireHook] PlayerKey:%s", tostring(self.PlayerKey))
self.EnableTwoHook = InEnableTwoHook
self.SmartAimLeftFound = InSmartAimLeftFound
self.SmartAimLocationLeft = InSmartAimLocationLeft
self.SmartAimRightFound = InSmartAimRightFound
self.SmartAimLocationRight = InSmartAimLocationRight
if not UE.IsValid(self.LeftHook) then
self.LeftHook = self:GetHook(false, self.PlayerKey)
end
if not UE.IsValid(self.RightHook) then
self.RightHook = self:GetHook(true, self.PlayerKey)
end
self.LeftHook:FireHook(self:GetHookFireStartPos(false), self.SmartAimLocationLeft, self.HookFlyTime, self, self.GearPropertyName_L, self.GearSocketName)
if not self.SmartAimLeftFound then
self.RecoverLeftHookHandle = UGCEventSystem.SetTimer(self, function()
self.LeftHook:RecoverHook()
self.RecoverLeftHookHandle = nil
end,
self.HookFlyTime
)
end
if self.EnableTwoHook then
self.RightHook:FireHook(self:GetHookFireStartPos(true), self.SmartAimLocationRight, self.HookFlyTime, self, self.GearPropertyName_R, self.GearSocketName)
if not self.SmartAimRightFound then
self.RecoverRightHookHandle = UGCEventSystem.SetTimer(self, function()
self.RightHook:RecoverHook()
self.RecoverRightHookHandle = nil
end,
self.HookFlyTime
)
end
end
self:FireHookEffect()
end
function UGCPlayerPawn:FireHookEffect()
if self.PlayerKey == UGCSystemLibrary.GetLocalPlayerKey() then
SoundSystem.PlaySound(SoundSystem.ESound.HookFire)
end
self.P_HookFire_L:SetActive(true, true)
if self.EnableTwoHook then
self.P_HookFire_R:SetActive(true, true)
end
end
function UGCPlayerPawn:HookPullEffect()
if self.PlayerKey == UGCSystemLibrary.GetLocalPlayerKey() then
SoundSystem.PlaySound(SoundSystem.ESound.Impulse)
end
self.P_HookFly_L:SetActive(true, true)
self.P_HookFly_R:SetActive(true, true)
end
function UGCPlayerPawn:DisableHookPullEffect()
self.P_HookFly_L:SetActive(false, false)
self.P_HookFly_R:SetActive(false, false)
end
function UGCPlayerPawn:RecoverHook()
if self.RecoverLeftHookHandle then
UGCEventSystem.StopTimer(self.RecoverLeftHookHandle)
self.RecoverLeftHookHandle = nil
end
self.LeftHook:RecoverHook()
if self.EnableTwoHook then
if self.RecoverRightHookHandle then
UGCEventSystem.StopTimer(self.RecoverRightHookHandle)
self.RecoverRightHookHandle = nil
end
self.RightHook:RecoverHook()
end
end
function UGCPlayerPawn:GetHookTraceStartPosition(IsRight)
return VectorHelper.ToLuaTable(self:K2_GetActorLocation())
end
function UGCPlayerPawn:GetTraceObjectTypes()
return {EObjectTypeQuery.ObjectTypeQuery1 }
end
--- 查询附着点
---@param IsRight bool
---@param CameraForward FVector
---@param FindDis float 查询的距离 默认为10000
---@param FindNum uint 旋转查询的次数 默认为3
---@return bool,FVector 是否检测到目标位置,抓钩目标的位置
function UGCPlayerPawn:FindHookAttachmentPoint(IsRight, CameraForward, FindDis, FindNum)
UGCLogSystem.Log("[UGCPlayerPawn_FindHookAttachmentPoint] " .. (IsRight and "Right" or "Left"))
if FindDis == nil then
FindDis = self.HookMaxDis
end
if FindNum == nil or FindNum <= 0 then
FindNum = 3
end
local CameraRotation = KismetMathLibrary.Conv_VectorToRotator(CameraForward)
local DetectDeflectionRotation = {Pitch=0.000000,Yaw=-11.000000,Roll=0.000000}
if self.EnableTwoHook then
if IsRight then
DetectDeflectionRotation.Yaw = 11.000000
end
else
FindNum = 1
DetectDeflectionRotation.Yaw = 0.000000
end
local TraceEndPos, FirstEndPos
local TraceStartPos = self:GetHookTraceStartPosition(IsRight)
UGCLogSystem.Log("[UGCPlayerPawn_FindHookAttachmentPoint] FindNum:%s", tostring(FindNum))
for i = 1, FindNum do
local TargetCombineRotator = table.DeepCopy(DetectDeflectionRotation)
TargetCombineRotator.Yaw = DetectDeflectionRotation.Yaw * i
local TargetRotation = KismetMathLibrary.ComposeRotators(CameraRotation, TargetCombineRotator)
local TraceDir = KismetMathLibrary.GetForwardVector(TargetRotation)
local TraceEndDir = VectorHelper.MulNumber(TraceDir, FindDis)
TraceEndPos = VectorHelper.Add(TraceStartPos, TraceEndDir)
if i == 1 then
FirstEndPos = table.DeepCopy(TraceEndPos)
end
--- 这里最多将触发3次检测 首次线条检测,未检测到则小球体检测,又未检测到则大球体检测
---@field LineTraceSingleForObjects fun(WorldContextObject:UObject,Start:FVector,End:FVector,ObjectTypes:ULuaArrayHelper,bTraceComplex:bool,ActorsToIgnore:ULuaArrayHelper,DrawDebugType:EDrawDebugTrace,OutHit:FHitResult,bIgnoreSelf:bool,TraceColor:FLinearColor,TraceHitColor:FLinearColor,DrawTime:float):bool,FHitResult
local bHit, HitResult = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, TraceEndPos, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
local IsSphere = false
local FinishSphereRadius = 0.
if not bHit then
if self.EnableTwoHook then
TraceEndDir = VectorHelper.MulNumber(TraceDir, self.TwoHookTraceMaxDis)
TraceEndPos = VectorHelper.Add(TraceStartPos, TraceEndDir)
IsSphere = true
local SmallSphereTraceStartPos = VectorHelper.Add(TraceStartPos, VectorHelper.MulNumber(TraceDir, self.SmallSphereStartDis))
---@field SphereTraceSingleForObjects fun(WorldContextObject:UObject,Start:FVector,End:FVector,Radius:float,ObjectTypes:ULuaArrayHelper,bTraceComplex:bool,ActorsToIgnore:ULuaArrayHelper,DrawDebugType:EDrawDebugTrace,OutHit:FHitResult,bIgnoreSelf:bool,TraceColor:FLinearColor,TraceHitColor:FLinearColor,DrawTime:float):bool,FHitResult
bHit, HitResult = TraceManager.SphereTraceSingleForObjects(self, TraceEndPos, SmallSphereTraceStartPos, self.SmartAimMediumTraceRadius, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
FinishSphereRadius = self.SmartAimMediumTraceRadius
if bHit then
local bLineHit, LineHitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, HitResult.ImpactPoint, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
UGCLogSystem.Log("[UGCPlayerPawn_FindHookAttachmentPoint] bLineHit:%s Distance:%s",tostring(bLineHit), tostring(LineHitResultInst.Distance))
if bLineHit and LineHitResultInst.Distance <= self.HookMaxDis then
return true, VectorHelper.ToLuaTable(LineHitResultInst.ImpactPoint)
else
bHit = false
end
end
if not bHit then
local BigSphereTraceStartPos = VectorHelper.Add(TraceStartPos, VectorHelper.MulNumber(TraceDir, self.BigSphereStartDis))
bHit, HitResult = TraceManager.SphereTraceSingleForObjects(self, TraceEndPos, BigSphereTraceStartPos, self.SmartAimLargeTraceRadius, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
FinishSphereRadius = self.SmartAimLargeTraceRadius
if bHit then
local bLineHit, LineHitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, HitResult.ImpactPoint, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
UGCLogSystem.Log("[UGCPlayerPawn_FindHookAttachmentPoint] 2 bLineHit:%s Distance:%s",tostring(bLineHit), tostring(LineHitResultInst.Distance))
if bLineHit and LineHitResultInst.Distance <= self.HookMaxDis then
return true, VectorHelper.ToLuaTable(LineHitResultInst.ImpactPoint)
else
bHit = false
end
end
end
else
local SmallSphereTraceStartPos = VectorHelper.Add(TraceStartPos, VectorHelper.MulNumber(TraceDir, self.OneHookSecondTraceStartDis))
---@field SphereTraceSingleForObjects fun(WorldContextObject:UObject,Start:FVector,End:FVector,Radius:float,ObjectTypes:ULuaArrayHelper,bTraceComplex:bool,ActorsToIgnore:ULuaArrayHelper,DrawDebugType:EDrawDebugTrace,OutHit:FHitResult,bIgnoreSelf:bool,TraceColor:FLinearColor,TraceHitColor:FLinearColor,DrawTime:float):bool,FHitResult
bHit, HitResult = TraceManager.SphereTraceSingleForObjects(self, SmallSphereTraceStartPos, TraceEndPos, self.OneHookSecondTraceRadius, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
end
end
if bHit then
-- UGCLogSystem.Log("[UGCPlayerPawn_FindHookAttachmentPoint]")
--- 防止球体检测过程前段中出现碰撞,进行二次线条检测
if IsSphere then
local bHitInst, HitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, HitResult.ImpactPoint, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
if bHitInst then
return true, VectorHelper.ToLuaTable(HitResultInst.ImpactPoint)
else
return true, VectorHelper.ToLuaTable(HitResult.ImpactPoint)
end
--if VectorHelper.Equal(HitResult.Location, HitResult.ImpactPoint) then
-- local ActorPos = HitResult.Actor:Get():K2_GetActorLocation()
-- local EndPos = VectorHelper.Add(HitResult.ImpactPoint, KismetMathLibrary.ClampVectorSize(VectorHelper.Sub(HitResult.ImpactPoint, ActorPos), FinishSphereRadius))
-- local bHitInst, HitResultInst = TraceManager.LineTraceSingleForObjects(self, HitResult.ImpactPoint, EndPos, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug)
-- if bHitInst then
-- return true, VectorHelper.ToLuaTable(HitResultInst.ImpactPoint)
-- else
-- return true, VectorHelper.ToLuaTable(EndPos)
-- end
--else
-- return true, VectorHelper.ToLuaTable(HitResult.ImpactPoint)
--end
--if bHitInst then
-- return true, VectorHelper.ToLuaTable(HitResultInst.ImpactPoint)
--else
-- return true, VectorHelper.ToLuaTable(HitResult.ImpactPoint)
--end
-- return true, VectorHelper.ToLuaTable(HitResult.ImpactPoint)
else
return true, VectorHelper.ToLuaTable(HitResult.ImpactPoint)
end
end
end
return false, VectorHelper.ToLuaTable(FirstEndPos)
end
UGCPlayerPawn.bClientLastTracePointIsRight = false
UGCPlayerPawn.ClientHookTraceNum_R = 1
UGCPlayerPawn.ClientHookTraceNum_L = 1
UGCPlayerPawn.ClientHookTraceFrequency = 20
UGCPlayerPawn.ClientHookLastTraceIntervalTime = 0
function UGCPlayerPawn:SetClientHookTraceNum(IsRight, NewNum)
if IsRight then
self.ClientHookTraceNum_R = NewNum
else
self.ClientHookTraceNum_L = NewNum
end
end
function UGCPlayerPawn:ClientFindPoint()
if self.ClientTracing then return end
self.ClientTracing = true
local IsRight = self.bClientLastTracePointIsRight
if not GlobalConfigs.GameSetting.bIsTwoHook then return end
local TraceNum
if IsRight then
TraceNum = self.ClientHookTraceNum_R
else
TraceNum = self.ClientHookTraceNum_L
end
local LocalCamera = UGCSystemLibrary.GetLocalPlayerController().PlayerCameraManager
local CameraForward = LocalCamera:GetActorForwardVector()
local CameraRotation = KismetMathLibrary.Conv_VectorToRotator(CameraForward)
local TargetCombineRotator = {Pitch=0.000000,Yaw=-11.000000 * (TraceNum // 3 + 1) ,Roll=0.000000}
if IsRight then
TargetCombineRotator.Yaw = -TargetCombineRotator.Yaw
end
local TraceStartPos = self:K2_GetActorLocation()
local TargetRotation = KismetMathLibrary.ComposeRotators(CameraRotation, TargetCombineRotator)
local TraceDir = KismetMathLibrary.GetForwardVector(TargetRotation)
--UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] TraceStartPos:%s, TraceEndPos:%s", VectorHelper.ToString(TraceStartPos), VectorHelper.ToString(TraceEndPos))
local bHit, HitResult, FinishSphereRadius
local TraceState = TraceNum % 3
local TraceEndDir
if TraceState == 0 then
TraceEndDir = VectorHelper.MulNumber(TraceDir, self.HookMaxDis)
else
TraceEndDir = VectorHelper.MulNumber(TraceDir, self.TwoHookTraceMaxDis)
end
local TraceEndPos = VectorHelper.Add(TraceStartPos, TraceEndDir)
if TraceState == 0 then
bHit, HitResult = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, TraceEndPos, self:GetTraceObjectTypes(), {}, false)
elseif TraceState == 1 then
local SmallSphereTraceStartPos = VectorHelper.Add(TraceStartPos, VectorHelper.MulNumber(TraceDir, self.SmallSphereStartDis))
bHit, HitResult = TraceManager.SphereTraceSingleForObjects(self, TraceEndPos, SmallSphereTraceStartPos, self.SmartAimMediumTraceRadius, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
FinishSphereRadius = self.SmartAimMediumTraceRadius
if bHit then
local bLineHit, LineHitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, HitResult.ImpactPoint, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
if bLineHit and LineHitResultInst.Distance <= self.HookMaxDis then
HitResult = LineHitResultInst
else
bHit = false
end
end
elseif TraceState == 2 then
local BigSphereTraceStartPos = VectorHelper.Add(TraceStartPos, VectorHelper.MulNumber(TraceDir, self.BigSphereStartDis))
bHit, HitResult = TraceManager.SphereTraceSingleForObjects(self, TraceEndPos, BigSphereTraceStartPos, self.SmartAimLargeTraceRadius, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
FinishSphereRadius = self.SmartAimLargeTraceRadius
if bHit then
local bLineHit, LineHitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, HitResult.ImpactPoint, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
if bLineHit and LineHitResultInst.Distance <= self.HookMaxDis then
HitResult = LineHitResultInst
else
bHit = false
end
end
else
self:SetClientHookTraceNum(IsRight, 1)
return
end
--UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] IsRight:%s, TraceNum:%s, bHit:%s, ImpactPoint:%s", tostring(IsRight), tostring(TraceNum), tostring(bHit), VectorHelper.ToString(HitResult.ImpactPoint))
if bHit then
--if TraceState > 0 then
-- local bHitInst, HitResultInst = TraceManager.LineTraceSingleForObjects(self, HitResult.ImpactPoint, HitResult.Actor:Get():K2_GetActorLocation(), self:GetTraceObjectTypes(), {}, false)
-- if bHitInst then
-- HitResult = HitResultInst
-- end
--end
local TracePos = HitResult.ImpactPoint
if TraceState > 0 then
--local bHitInst, HitResultInst = TraceManager.LineTraceSingleForObjects(self, TraceStartPos, TracePos, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
--if bHitInst then
-- TracePos = HitResultInst.ImpactPoint
--end
--if VectorHelper.Equal(HitResult.Location, HitResult.ImpactPoint) then
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] ImpactPoint:%s, Location:%s", VectorHelper.ToString(HitResult.ImpactPoint), VectorHelper.ToString(HitResult.Location))
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] Is Equal")
-- local ActorPos = HitResult.Actor:Get():K2_GetActorLocation()
-- local EndPos = VectorHelper.Add(HitResult.ImpactPoint, KismetMathLibrary.ClampVectorSize(VectorHelper.Sub(HitResult.ImpactPoint, ActorPos), FinishSphereRadius))
-- local bHitInst, HitResultInst = TraceManager.LineTraceSingleForObjects(self, HitResult.ImpactPoint, EndPos, self:GetTraceObjectTypes(), {}, self.bEnableDrawDebug_Client)
-- if bHitInst then
-- TracePos = HitResultInst.ImpactPoint
-- else
-- TracePos = EndPos
-- end
--else
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] Is Not Equal")
--end
end
self:SetClientHookTraceNum(IsRight, 0)
local HookTraceWidget = WidgetManager:GetPanel(WidgetConfig.EUIType.HookTrace)
HookTraceWidget:UpdateTracePos(IsRight, true, TracePos)
--if TraceState > 0 then
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] ImpactPoint:%s, Location:%s", VectorHelper.ToString(HitResult.ImpactPoint), VectorHelper.ToString(HitResult.Location))
-- if VectorHelper.Equal(HitResult.ImpactPoint, HitResult.Location) then
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] Is Equal")
-- else
-- UGCLogSystem.Log("[UGCPlayerPawn_ClientFindPoint] Is Not Equal")
-- end
--end
else
if TraceNum == 8 then
self:SetClientHookTraceNum(IsRight, 0)
local HookTraceWidget = WidgetManager:GetPanel(WidgetConfig.EUIType.HookTrace)
HookTraceWidget:UpdateTracePos(IsRight, false)
else
self:SetClientHookTraceNum(IsRight, TraceNum + 1)
end
end
self.bClientLastTracePointIsRight = not self.bClientLastTracePointIsRight
self.ClientTracing = false
end
function UGCPlayerPawn:ClientTickHookTrace(DeltaTime)
if GlobalConfigs.GameSetting.bIsTwoHook and UGCGameSettingSystem.GetDeviceLevel() > 0 then
self.ClientHookLastTraceIntervalTime = self.ClientHookLastTraceIntervalTime + DeltaTime
if self.ClientHookLastTraceIntervalTime >= 1./ self.ClientHookTraceFrequency then
self.ClientHookLastTraceIntervalTime = self.ClientHookLastTraceIntervalTime - 1./ self.ClientHookTraceFrequency
self:ClientFindPoint()
end
end
end
function UGCPlayerPawn:GetHookPullDir()
if self.SmartAimLeftFound then
self.HookLeftDir = VectorHelper.Sub(self.SmartAimLocationLeft, self:K2_GetActorLocation())
self.HookLeftDir = VectorHelper.MulNumber(self.HookLeftDir, 1. / VectorHelper.Length(self.HookLeftDir))
else
self.HookLeftDir = VectorHelper.VectorZero()
end
self.HookRightDir = VectorHelper.VectorZero()
if self.EnableTwoHook and self.SmartAimRightFound then
self.HookRightDir = VectorHelper.Sub(self.SmartAimLocationRight, self:K2_GetActorLocation())
self.HookRightDir = VectorHelper.MulNumber(self.HookRightDir, 1. / VectorHelper.Length(self.HookRightDir))
end
self.HookPullDir = VectorHelper.Add(self.HookLeftDir, self.HookRightDir)
self.HookPullDir = VectorHelper.MulNumber(self.HookPullDir, 1. / VectorHelper.Length(self.HookPullDir))
return self.HookPullDir
end
--- 自动停止条件
function UGCPlayerPawn:AutoStopHookPullCondition()
if not UGCGameSystem.IsServer() or not self.bAutoStopHookPush then
return false
end
if VectorHelper.CosineValue(self.StartPullDir, self.HookPullDir) < 0 then
return true
end
if self.EnableTwoHook then
if VectorHelper.CosineValue(self.StartPullDir, self.HookLeftDir) < 0 then
return true
end
if VectorHelper.CosineValue(self.StartPullDir, self.HookRightDir) < 0 then
return true
end
else
if VectorHelper.Length(VectorHelper.Sub(self.SmartAimLocationLeft, self:K2_GetActorLocation())) <= self.UpImpulseDistanceThreshold then
return true
end
end
return false
end
function UGCPlayerPawn:TickPullPlayer(DeltaTime)
self:AddHookEnergy(DeltaTime)
if self.bHookPullingPlayer then
-- local PullDir = self:GetHookPullDir()
self:GetHookPullDir()
--- 自动停止拉动可以设置速度方向而更稳定
if self:AutoStopHookPullCondition() then
self:StopHookSkill()
return
end
-- Test
self.HookPullDir = self.StartPullDir
-- Test End
self.CharacterMovement:AddImpulse(VectorHelper.MulNumber(self.HookPullDir, self.HookPullImpulse * DeltaTime), true)
if self.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Falling then
self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling);
end
if self.bAutoStopHookPush then
self.CharacterMovement.Velocity = VectorHelper.MulNumber(self.HookPullDir, math.clamp(VectorHelper.Length(self.CharacterMovement.Velocity), self.MinPullVelocity, self.MaxPullVelocity))
else
self.CharacterMovement.Velocity = KismetMathLibrary.ClampVectorSize(self.CharacterMovement.Velocity, self.MinPullVelocity, self.MaxPullVelocity)
end
end
end
--------------------------------------------------------- HookSkill End ---------------------------------------------------------
--- 测试按键按下在服务器触发的函数
function UGCPlayerPawn:TestButtonFun(CameraForwardVector)
-- self:PlayerDashSkill(self:GetActorForwardVector(), 1, 5000)
-- self:PlayerDashSkill(CameraForwardVector, 1, 5000)
-- self:DashImpulse(CameraForwardVector, 8000, 1500, 0.8)
-- self:TestMoveComponentTo(CameraForwardVector)
end
function UGCPlayerPawn:TestButtonPressed(CameraForwardVector)
self:HookSkill(CameraForwardVector)
end
function UGCPlayerPawn:TestButtonReleased()
self:StopHookSkill()
end
--- Server的BeginPlay触发及Client的ClientMustBeExeBeginPlay触发
function UGCPlayerPawn:SkillInit()
if UGCGameSystem.IsServer() then
--self:InitDashImpulse()
else
self:InitHook()
end
end
function UGCPlayerPawn:SkillEndPlay()
if UGCGameSystem.IsServer() then
else
self:DetachHookMesh()
end
end
function UGCPlayerPawn:TickSkill(DeltaTime)
self:DashImpulseTick(DeltaTime)
-- self:TickDash(DeltaTime)
self:TickPullPlayer(DeltaTime)
self:LaunchTick(DeltaTime)
if UGCGameSystem.IsServer() then
else
if UGCSystemLibrary.GetLocalPlayerPawn() == self then
self:ClientTickHookTrace(DeltaTime)
end
end
end
function UGCPlayerPawn:GetAvailableServerRPCs()
return
end
return UGCPlayerPawn;