697 lines
26 KiB
Lua
697 lines
26 KiB
Lua
---@class BP_PlayerPawn_C:BP_UGCPlayerPawn_C
|
||
---@field BreachWidget UWidgetComponent
|
||
---@field ParticleSystem UParticleSystemComponent
|
||
---@field CameraSocket USceneComponent
|
||
---@field WeaponActorSocket USceneComponent
|
||
---@field WeaponParticleArray TMap:TEnumAsByte<EWeaponClassType>,UParticleSystem
|
||
--Edit Below--
|
||
UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom')
|
||
UGCGameSystem.UGCRequire('Script.Common.ue_struct_custom')
|
||
UGCGameSystem.UGCRequire('Script.Global.Global')
|
||
|
||
local BP_PlayerPawn = {
|
||
IsRunOnServer = false,
|
||
|
||
WeaponActor = nil,
|
||
|
||
IsInArena = false, --是否在场内
|
||
|
||
IsInTrueDamage = false, --是否在真实伤害状态
|
||
|
||
DashDuration = -1, --冲刺持续时间
|
||
CachedCharacterMovementGravityScale = 1.5, --缓存玩家重力参数
|
||
IsDashTo = false, --冲刺状态开关
|
||
LaunchCharacterForce = 10000, --冲刺力度 决定要冲刺多远
|
||
LaunchDir = nil, --冲刺方向
|
||
|
||
EnergyData = { Max = 0, Cur = 0 }, --能量值(为了同一帧同步所以合并)
|
||
|
||
bHasApplyedAttribute = false, --是否已有初始属性
|
||
AttributeUpdateInterval = 0, --属性更新计时器
|
||
|
||
bCanBeControlledByMonsters = true, --可被怪物控制
|
||
|
||
WeaponParticles = {}, --武器特效
|
||
|
||
BossAttackCount = 0, --Boss被攻击次数(用作播放特效)
|
||
|
||
bIsAlive = true, --玩家是否活着
|
||
|
||
SkillSystemComponent = nil, --技能系统
|
||
TestTimerHandler = nil;
|
||
|
||
ItemActorClass = nil,
|
||
};
|
||
|
||
BP_PlayerPawn.OnReceiveDamageDelegate = Delegate.New()
|
||
BP_PlayerPawn.OnWeaponSpawnedDelegate = Delegate.New()
|
||
|
||
--设置同步的属性
|
||
function BP_PlayerPawn:GetReplicatedProperties()
|
||
return
|
||
"WeaponActor",
|
||
"EnergyData",
|
||
"BossAttackCount",
|
||
"IsInArena"
|
||
end
|
||
|
||
function BP_PlayerPawn:GetAvailableServerRPCs()
|
||
return
|
||
-- "DrawDebugSphere",
|
||
-- "DrawDebugLine",
|
||
-- "DrawDebugBox",
|
||
-- "Client_MulticastRPC_PlaySkillEffect",
|
||
-- "Client_MulticastRPC_PlayEffect",
|
||
-- "Client_MulticastRPC_PlayDirectionalEffect",
|
||
-- "Client_MulticastRPC_PlayEffectAtLocation",
|
||
-- "Client_MulticastRPC_RemoveSkillEffect",
|
||
-- "Client_MulticastRPC_RemoveAllSkillEffect"
|
||
end
|
||
|
||
function BP_PlayerPawn:ReceiveBeginPlay()
|
||
BP_PlayerPawn.SuperClass.ReceiveBeginPlay(self)
|
||
|
||
self.IsRunOnServer = UGCGameSystem.IsServer()
|
||
|
||
--禁止掉落伤害
|
||
self.bTemperoryDisableFallingDamage = true
|
||
--缓存当前重力
|
||
self.CachedCharacterMovementGravityScale = self.STCharacterMovement.GravityScale
|
||
self.ItemActorClass = UE.LoadClass(BPClassPath.PickupItemClass)
|
||
|
||
EventSystem.SetTimer(self, function()
|
||
--self:TestPawn();
|
||
end, 30)
|
||
|
||
if self:HasAuthority() then
|
||
self:BindServerEvent()
|
||
|
||
if self.SkillSystemComponent == nil then
|
||
local SkillSystemComponentClass = require("Script.SimpleSkill.SkillSystemComponent")
|
||
self.SkillSystemComponent = SkillSystemComponentClass.New(self)
|
||
end
|
||
else
|
||
self:BindClientEvent()
|
||
|
||
local CommandManager = require('Script.Manager.CommandQueneManager')
|
||
CommandManager:AddInitCommand(self, self.Client_Init)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:TestPawn()
|
||
if self:HasAuthority() == false then
|
||
end
|
||
--local PlayerState = self:GetPlayerStateSafety()
|
||
--PlayerState:AddExp(10000)
|
||
end
|
||
|
||
function BP_PlayerPawn:ReceiveEndPlay()
|
||
if self:HasAuthority() then
|
||
self:UnbindServerEvent()
|
||
else
|
||
self:UnbindClientEvent()
|
||
end
|
||
|
||
BP_PlayerPawn.SuperClass.ReceiveEndPlay(self)
|
||
end
|
||
|
||
function BP_PlayerPawn:ReceiveTick(DeltaTime)
|
||
BP_PlayerPawn.SuperClass.ReceiveTick(self, DeltaTime)
|
||
|
||
if self.IsRunOnServer then
|
||
self:ServerTick(DeltaTime)
|
||
self.SkillSystemComponent:OnTick(DeltaTime)
|
||
else
|
||
if self.bHasInitClient == nil and self.PlayerKey ~= 0 then
|
||
local CommandManager = require('Script.Manager.CommandQueneManager')
|
||
CommandManager.bPlayerPawnReady = true
|
||
self.bHasInitClient = true
|
||
UE.Log("[BP_PlayerPawn] *** BP_PlayerPawn Tick Init Ready PlayerKey:%s", self.PlayerKey)
|
||
end
|
||
|
||
self:ClientTick(DeltaTime)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_Init()
|
||
self:ClientOnHPChanged(UGCPawnAttrSystem.GetHealth(self), UGCPawnAttrSystem.GetHealthMax(self), 0)
|
||
self:OnRep_EnergyData()
|
||
end
|
||
|
||
---@field UGC_PreTakeDamageEvent:fun(Damage:float,EventInstigator:AController,DamageEvent:FDamageEvent,DamageCauser:AActor):float
|
||
function BP_PlayerPawn:UGC_PreTakeDamageEvent(Damage, EventInstigator, DamageEvent, DamageCauser)
|
||
UE.Log("[BP_PlayerPawn:UGC_PreTakeDamageEvent] Damage = %d", Damage)
|
||
return Damage
|
||
end
|
||
|
||
function BP_PlayerPawn:ServerTick(DeltaTime)
|
||
--自动回复逻辑
|
||
if UGCGameSystem.GameState.bHasApplyedAttribute then
|
||
self.AttributeUpdateInterval = self.AttributeUpdateInterval + DeltaTime
|
||
if self.AttributeUpdateInterval >= 1.0 then
|
||
local PlayerState = self:GetPlayerStateSafety()
|
||
--成长属性
|
||
PlayerState:GrowthAttributes()
|
||
--每秒增加杀敌点
|
||
PlayerState:GrowthKillPoint()
|
||
--刷新战斗力计算结果
|
||
PlayerState:RefreshCombatPoint()
|
||
--每秒回复
|
||
PlayerState:RecoverPlayerPawn()
|
||
--每秒杀敌点
|
||
PlayerState:AttributeAdditionPerSecond()
|
||
|
||
self.AttributeUpdateInterval = 0
|
||
end
|
||
end
|
||
|
||
--冲刺逻辑
|
||
if self.DashDuration > 0 then
|
||
self.DashDuration = self.DashDuration - DeltaTime
|
||
if self.DashDuration <= 0 then
|
||
self.DashDuration = -1
|
||
self.LaunchDir = nil
|
||
self:EnableDashTo(false)
|
||
end
|
||
|
||
if self.LaunchDir then
|
||
self:LaunchCharacter(VectorHelper.MulNumber(self.LaunchDir, self.LaunchCharacterForce * DeltaTime), true, false)
|
||
|
||
if self.CharacterMovement.MovementMode ~= EMovementMode.MOVE_Falling then
|
||
self.CharacterMovement:SetMovementMode(EMovementMode.MOVE_Falling)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:ClientTick(DeltaTime)
|
||
end
|
||
|
||
function BP_PlayerPawn:BindServerEvent()
|
||
self.OnCharacterHpChange:Add(BP_PlayerPawn.ServerOnHPChanged, self)
|
||
self.OnDeath:Add(BP_PlayerPawn.ServerOnSelfDeath, self)
|
||
end
|
||
|
||
function BP_PlayerPawn:BindClientEvent()
|
||
EventSystem:AddListener(EventType.ClientUpdateWeapon, BP_PlayerPawn.OnUpdateWeapon, self)
|
||
self.OnCharacterHpChange:Add(BP_PlayerPawn.ClientOnHPChanged, self)
|
||
end
|
||
|
||
function BP_PlayerPawn:UnbindServerEvent()
|
||
self.OnDeath:Remove(BP_PlayerPawn.ServerOnSelfDeath, self)
|
||
self.OnCharacterHpChange:Remove(BP_PlayerPawn.ServerOnHPChanged, self)
|
||
end
|
||
|
||
function BP_PlayerPawn:UnbindClientEvent()
|
||
EventSystem:RemoveListener(EventType.ClientUpdateWeapon, BP_PlayerPawn.OnUpdateWeapon, self)
|
||
self.OnCharacterHpChange:Remove(BP_PlayerPawn.ClientOnHPChanged, self)
|
||
end
|
||
|
||
function BP_PlayerPawn:ServerOnSelfDeath(DeadPawn, KillerController, DamageCauser, KillingHitInfo, KillingHitImpulseDir, KillingHitDamageTypeID, DamageTypeClass, IsHeadShotDamage)
|
||
if DeadPawn.PlayerKey == self.PlayerKey then
|
||
if UE.IsValid(KillerController) and UE.IsValid(KillerController.Pawn) then
|
||
EventSystem:SendEvent(EventType.PlayerPawnDead, self.PlayerKey, KillerController.Pawn)
|
||
end
|
||
UE.Log("[BP_PlayerPawn:ServerOnSelfDeath] PlayerKey=%d",self.PlayerKey)
|
||
local PlayerKey = UGCPawnAttrSystem.GetPlayerKeyInt64(self)
|
||
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
|
||
local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey)
|
||
|
||
PlayerState.BackupEnergyData = TableHelper.DeepCopyTable(self.EnergyData)
|
||
self.bIsAlive = false
|
||
|
||
if self.SkillSystemComponent then
|
||
self.SkillSystemComponent:RemoveAllSkill()
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "Client_MulticastRPC_RemoveAllSkillEffect", self)
|
||
end
|
||
|
||
if DamageCauser and UE.IsValid(DamageCauser) then
|
||
local MonsterType = GameDataManager.GetMonsterTypeByID(DamageCauser.ID)
|
||
if MonsterType == EMonsterType.Boss or MonsterType == EMonsterType.Common then
|
||
if MonsterType == EMonsterType.Boss then
|
||
DamageCauser.KilledPlayerNum = DamageCauser.KilledPlayerNum + 1
|
||
end
|
||
PlayerController.IsDeadInArena = true
|
||
else
|
||
PlayerController.IsDeadInArena = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:ServerOnHPChanged(CurHP, MaxHP, PrevHP)
|
||
UE.Log("[BP_PlayerPawn:ServerOnHPChanged] PlayerKey = %d, CurHP = %.1f, MaxHP = %.1f, PrevHP = %.1f", UGCPawnAttrSystem.GetPlayerKeyInt64(self), CurHP, MaxHP, PrevHP)
|
||
end
|
||
|
||
function BP_PlayerPawn:ClientOnHPChanged(CurHP, MaxHP, PrevHP)
|
||
local PlayerKey = UGCPawnAttrSystem.GetPlayerKeyInt64(self)
|
||
EventSystem:SendEvent(EventType.OnPlayerHPChanged, PlayerKey, CurHP, MaxHP, PrevHP)
|
||
|
||
UE.Log("[BP_PlayerPawn:ClientOnHPChanged] PlayerKey = %d, CurHP = %.1f, MaxHP = %.1f, PrevHP = %.1f", PlayerKey, CurHP, MaxHP, PrevHP)
|
||
end
|
||
|
||
function BP_PlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater)
|
||
return true
|
||
end
|
||
|
||
function BP_PlayerPawn:GetPickupCollision()
|
||
return self.PickupCollision
|
||
end
|
||
|
||
-- 获取武器组件
|
||
function BP_PlayerPawn:GetWeaponComponent()
|
||
return self.WeaponActor
|
||
end
|
||
|
||
function BP_PlayerPawn:IsFullHealth()
|
||
local MaxHP = UGCPawnAttrSystem.GetHealthMax(self)
|
||
local CurHP = UGCPawnAttrSystem.GetHealth(self)
|
||
return math.isNearlyEqual(MaxHP, CurHP) and MaxHP > 0
|
||
end
|
||
|
||
function BP_PlayerPawn:IsFullEnergy()
|
||
local MaxEnergy = self.EnergyData.Max
|
||
local CurEnergy = self.EnergyData.Cur
|
||
return math.isNearlyEqual(MaxEnergy, CurEnergy) and MaxEnergy > 0
|
||
end
|
||
|
||
function BP_PlayerPawn:IsSelfAlive()
|
||
return self.bIsAlive
|
||
end
|
||
|
||
function BP_PlayerPawn:OnRep_EnergyData()
|
||
if EventSystem and EventType then
|
||
local Cur = self.EnergyData.Cur
|
||
local Max = self.EnergyData.Max
|
||
UE.Log("[BP_PlayerPawn:OnRep_Energy] Cur = %2.2f, Max = %2.2f", Cur, Max)
|
||
EventSystem:SendEvent(EventType.OnPlayerEnergyChanged, self.PlayerKey, Cur, Max)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:OnRep_WeaponActor()
|
||
UE.Log("[BP_PlayerPawn:OnRep_WeaponActor] PlayerKey=%d, Changed", self.PlayerKey)
|
||
EventSystem.SetTimer(self, function()
|
||
if self.WeaponActor ~= nil and UE.IsValid(self.WeaponActor) then
|
||
self.WeaponActor:OnRep_CurrentWeaponId()
|
||
end
|
||
end, 0.2)
|
||
end
|
||
|
||
function BP_PlayerPawn:OnRep_BossAttackCount()
|
||
if self.WeaponActor == nil then
|
||
return
|
||
end
|
||
local WeaponId = self.WeaponActor.CurrentWeaponId
|
||
local WT = self.WeaponActor:GetWeaponTypeByWeaponId(WeaponId)
|
||
if WT == EWeaponClassType.WT_ShooterRifle
|
||
or WT == EWeaponClassType.WT_AssaultRifle
|
||
or WT == EWeaponClassType.WT_ShotGun
|
||
or WT == EWeaponClassType.WT_MachineGun
|
||
then
|
||
self:PlaySingleWeaponEffect(self.PlayerKey, WT)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:DashTo(Dir, Duration, DashForce)
|
||
self.LaunchCharacterForce = DashForce
|
||
self.DashDuration = Duration
|
||
self.LaunchDir = Dir
|
||
self:EnableDashTo(true)
|
||
end
|
||
|
||
function BP_PlayerPawn:EnableDashTo(IsOn)
|
||
if IsOn then
|
||
self.STCharacterMovement.GravityScale = 0
|
||
else
|
||
self.STCharacterMovement.GravityScale = self.CachedCharacterMovementGravityScale
|
||
end
|
||
end
|
||
|
||
|
||
--- 玩家处理伤害函数
|
||
---@param DamageAmount float
|
||
---@param DamageEvent FDamageEvent
|
||
---@param EventInstigator AController
|
||
---@param DamageCauser AActor
|
||
function BP_PlayerPawn:BP_CharacterModifyDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser)
|
||
self.OnReceiveDamageDelegate(self, DamageAmount, EventInstigator, DamageCauser)
|
||
|
||
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(UGCPawnAttrSystem.GetPlayerKeyInt64(self))
|
||
-- 获取 闪避
|
||
if PlayerState:Dodge() > 0 then
|
||
math.randomseed(KismetSystemLibrary.GetGameTimeInSeconds(self))
|
||
local Val = math.random() -- (0, 1)
|
||
if Val <= PlayerState:Dodge() then
|
||
-- 此时闪避
|
||
UE.Log("[BP_PlayerPawn:BP_CharacterModifyDamage] 闪避了一次")
|
||
return 0
|
||
end
|
||
end
|
||
|
||
local Val = BP_PlayerPawn.SuperClass:BP_CharacterModifyDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser)
|
||
|
||
-- 处理玩家的 defence
|
||
DamageAmount = PlayerState:GetDamage(DamageCauser, Val)
|
||
UE.Log("[BP_PlayerPawn:BP_CharacterModifyDamage] PlayerKey=%d, 当前受到伤害=%.2f", self.PlayerKey, DamageAmount)
|
||
|
||
-- 处理反弹伤害
|
||
PlayerState:GetReverseDamage(DamageCauser, DamageAmount)
|
||
|
||
-- 检查是否有护盾
|
||
local Amount = PlayerState:DealShield(DamageAmount)
|
||
|
||
return Amount
|
||
end
|
||
|
||
--玩家进行吸血
|
||
function BP_PlayerPawn:VampBlood(InNum)
|
||
if InNum <= 0 then
|
||
return
|
||
end
|
||
-- 获取玩家吸血效率
|
||
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(UGCPawnAttrSystem.GetPlayerKeyInt64(self))
|
||
local Val = PlayerState:SuckBlood(InNum)
|
||
-- 回复血量
|
||
self:RecoverCurHP(Val, 0)
|
||
UE.Log("[BP_PlayerPawn:VampBlood] Vamp = %.2f", Val)
|
||
end
|
||
|
||
--传过来一个怪物收到的真实伤害
|
||
function BP_PlayerPawn:DealRealDamage(InMonster, InNum)
|
||
-- 处理吸血
|
||
self:VampBlood(InNum)
|
||
|
||
-- 可以处理飘字等
|
||
-- 飘字 UGC_GetDamageNumberConfigIndex,可以检查一下
|
||
if GameDataManager.GetMonsterTypeByID(InMonster.ID) == EMonsterType.Boss then
|
||
self.BossAttackCount = self.BossAttackCount + 1
|
||
end
|
||
end
|
||
|
||
-- Server
|
||
function BP_PlayerPawn:SetMaxHealth(InMaxHealth)
|
||
UGCPawnAttrSystem.SetHealthMax(self, InMaxHealth)
|
||
UE.Log("[BP_PlayerPawn:SetMaxHealth] PlayerKey = %d, InMaxHP = %2.2f", self.PlayerKey, InMaxHealth)
|
||
end
|
||
|
||
-- Server
|
||
function BP_PlayerPawn:SetMaxEnergy(InMaxEnergy)
|
||
self.EnergyData.Max = InMaxEnergy
|
||
self.EnergyData.Cur = InMaxEnergy
|
||
UE.Log("[BP_PlayerPawn:SetMaxEnergy] PlayerKey = %d, Max = %2.2f, Cur = %2.2f", self.PlayerKey, self.EnergyData.Max, self.EnergyData.Cur)
|
||
end
|
||
|
||
-- Server & Client
|
||
function BP_PlayerPawn:GetCurEnergy()
|
||
return self.EnergyData.Cur
|
||
end
|
||
|
||
-- Server
|
||
function BP_PlayerPawn:ConsumeEnergy(InDelta)
|
||
local CurEnergy = math.clamp(self.EnergyData.Cur - InDelta, 0, self.EnergyData.Cur)
|
||
self.EnergyData.Cur = CurEnergy
|
||
end
|
||
|
||
-- Server 回复血量
|
||
function BP_PlayerPawn:RecoverCurHP(Value, Percent)
|
||
local MaxHP = UGCPawnAttrSystem.GetHealthMax(self)
|
||
local CurHP = UGCPawnAttrSystem.GetHealth(self)
|
||
if math.isNearlyEqual(MaxHP, CurHP) then
|
||
UE.Log("[BP_PlayerPawn:RecoverCurHP] Full HP")
|
||
return
|
||
end
|
||
|
||
local Delta = Value + MaxHP * Percent
|
||
local NewCurHP = CurHP + Delta
|
||
NewCurHP = math.clamp(NewCurHP, 0, MaxHP)
|
||
|
||
UE.Log("[BP_PlayerPawn:RecoverCurHP] PlayerKey = %d, Value = %2.2f, CurHP = %2.2f, Real = %2.2f", self.PlayerKey, Delta, CurHP, MaxHP - NewCurHP)
|
||
UGCPawnAttrSystem.SetHealth(self, NewCurHP)
|
||
end
|
||
|
||
-- Server
|
||
function BP_PlayerPawn:RecoverCurEnergy(Value, Percent)
|
||
if UE.IsValid(self) == false then
|
||
print(string.format('[BP_PlayerPawn:RecoverCurEnergy] 本身就有问题'))
|
||
end
|
||
|
||
if self.EnergyData == nil then
|
||
print(string.format('[BP_PlayerPawn:RecoverCurEnergy] 莫名其妙 Energy == nil'))
|
||
end
|
||
|
||
if self.EnergyData.Max == nil then
|
||
print(string.format('[BP_PlayerPawn:RecoverCurEnergy] 莫名其妙 Max Energy == nil'))
|
||
end
|
||
|
||
if self.EnergyData.Cur == nil then
|
||
print(string.format('[BP_PlayerPawn:RecoverCurEnergy] 莫名其妙 Cur Energy == nil'))
|
||
end
|
||
|
||
local MaxEnergy = self.EnergyData.Max
|
||
local CurEnergy = self.EnergyData.Cur
|
||
if math.isNearlyEqual(MaxEnergy, CurEnergy) and MaxEnergy > 0 then
|
||
UE.Log("[BP_PlayerPawn:RecoverCurEnergy] PlayerKey = %d, Full Energy", self.PlayerKey)
|
||
return
|
||
end
|
||
|
||
local Delta = Value + MaxEnergy * Percent
|
||
local NewCurEnergy = CurEnergy + Delta
|
||
NewCurEnergy = math.clamp(NewCurEnergy, 0, MaxEnergy)
|
||
UE.Log("[BP_PlayerPawn:RecoverCurEnergy] PlayerKey = %d, Value = %2.2f, CurHP = %2.2f, Real = %2.2f", self.PlayerKey, Delta, CurEnergy, MaxEnergy - NewCurEnergy)
|
||
self.EnergyData.Cur = NewCurEnergy
|
||
end
|
||
|
||
---玩家重生后初始化数据的逻辑
|
||
function BP_PlayerPawn:OnPlayerRespawned(OwnerPlayerState, OwnerPlayerController)
|
||
if (not UE.IsValid(OwnerPlayerState)) or (not UE.IsValid(OwnerPlayerController)) then
|
||
UE.LogError("[BP_PlayerPawn:OnPlayerRespawned] invalid PS or PC")
|
||
return
|
||
end
|
||
|
||
---Attribute init
|
||
print(string.format('[BP_PlayerPawn:OnPlayerRespawned] 设置玩家 Energy 的值'))
|
||
self:SetMaxEnergy(OwnerPlayerState.BackupEnergyData.Max)
|
||
|
||
OwnerPlayerState:ApplyAttributes()
|
||
|
||
---SkillSystem init
|
||
if self.SkillSystemComponent == nil then
|
||
local SkillSystemComponentClass = require("Script.SimpleSkill.SkillSystemComponent")
|
||
self.SkillSystemComponent = SkillSystemComponentClass.New(self)
|
||
end
|
||
|
||
local SkillListCopy = TableHelper.DeepCopyTable(OwnerPlayerController.ActiveSkillNameList)
|
||
for Slot, SkillInfo in pairs(SkillListCopy) do
|
||
self:GiveSkill(SkillInfo.SkillName, Slot, SkillInfo.SkillLevel)
|
||
end
|
||
|
||
---清空上次死亡上传的备份数据
|
||
OwnerPlayerState.BackupEnergyData = {}
|
||
|
||
---Weapon init
|
||
local OwnedWeapons = OwnerPlayerState:GetWeapons()
|
||
local CurWeaponId = -1
|
||
if not table.isEmpty(OwnedWeapons) then
|
||
CurWeaponId = OwnedWeapons[1].WeaponId
|
||
end
|
||
|
||
if self.WeaponActor == nil then
|
||
AsyncLoadTools:LoadObject(BPClassPath.WeaponBaseActor,
|
||
function(WeaponClass)
|
||
if UE.IsValid(self) and UE.IsValid(WeaponClass) and UE.IsValid(OwnerPlayerState) then
|
||
local Weapon = UGCGameSystem.SpawnActor(self, WeaponClass, self:K2_GetActorLocation(), self:K2_GetActorRotation(), VectorHelper.ScaleOne(), nil)
|
||
Weapon:SetWeaponID(CurWeaponId)
|
||
Weapon:SetOwnerCharacter(self)
|
||
self.WeaponActor = Weapon
|
||
self.OnWeaponSpawnedDelegate(self)
|
||
end
|
||
end)
|
||
else
|
||
self.WeaponActor:SetWeaponID(CurWeaponId)
|
||
end
|
||
|
||
end
|
||
|
||
--仅切换枪的时候再做操作
|
||
function BP_PlayerPawn:OnUpdateWeapon(InWeaponId, InOldId, InPlayerKey)
|
||
-- 因为不需要重复播放
|
||
if InOldId == InWeaponId then
|
||
return
|
||
end
|
||
|
||
if InPlayerKey ~= self.PlayerKey then
|
||
return
|
||
end
|
||
|
||
local WeaponType = GameDataManager.GetWeaponType(InWeaponId)
|
||
if WeaponType == nil then
|
||
UE.Log("[BP_WeaponPawnBase:CheckWeaponByWeaponId] Data is nil")
|
||
return
|
||
else
|
||
self:ClearParticles()
|
||
self:ShowParticle(false)
|
||
-- 选择对应的特效,并在玩家身上播放
|
||
local WeaponParticle = self.WeaponParticleArray[WeaponType]
|
||
if WeaponParticle ~= nil then
|
||
self.ParticleSystem:SetTemplate(WeaponParticle)
|
||
if WeaponType == EWeaponClassType.WT_SubmachineGun or WeaponType == EWeaponClassType.WT_Sniper then
|
||
-- 持久显示
|
||
local Text = ''
|
||
if WeaponType == EWeaponClassType.WT_ShooterRifle then
|
||
Text = 'spine_03'
|
||
end
|
||
self.WeaponParticles[WeaponType] = GameplayStatics.SpawnEmitterAttached(WeaponParticle, self.Mesh, Text, Vector.New(0, 0, 0), VectorHelper.RotZero(), VectorHelper.ScaleOne(), EAttachLocation.SnapToTarget, false)
|
||
else
|
||
--当攻击的时候显示一次,因此不在这里显示
|
||
end
|
||
|
||
UE.Log("[BP_PlayerPawn:OnUpdateWeapon] 播放特效, Type = %d", WeaponType)
|
||
end
|
||
self:ShowParticle(true)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:PlaySingleWeaponEffect(InPlayerKey, InWeaponType)
|
||
UE.Log("[BP_PlayerPawn:PlaySingleWeaponEffect] 开始播放特效")
|
||
if InPlayerKey ~= self.PlayerKey then
|
||
return
|
||
end
|
||
UE.Log("[BP_PlayerPawn:PlaySingleWeaponEffect] 当前武器类型:%d", InWeaponType)
|
||
if InWeaponType == nil then
|
||
UE.Log("[BP_WeaponPawnBase:CheckWeaponByWeaponId] 找不到 WeaponType, 请检查一下")
|
||
return
|
||
else
|
||
local WeaponParticle = self.WeaponParticleArray[InWeaponType]
|
||
if WeaponParticle ~= nil then
|
||
UE.Log("[BP_PlayerPawn:PlaySingleWeaponEffect] 有武器特效")
|
||
local EffectParticle = GameplayStatics.SpawnEmitterAttached(WeaponParticle, self.Mesh, "", Vector.New(0, 0, 0), VectorHelper.RotZero(), VectorHelper.ScaleOne(), EAttachLocation.SnapToTarget, true)
|
||
EventSystem.SetTimer(self, function()
|
||
if UE.IsValid(EffectParticle) then
|
||
EffectParticle:K2_DestroyComponent()
|
||
end
|
||
end, 1)
|
||
else
|
||
UE.Log("[BP_PlayerPawn:PlaySingleWeaponEffect] 找不到武器特效")
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 清除玩家身上的特效
|
||
function BP_PlayerPawn:ShowParticle(InShow)
|
||
-- 设置隐藏即可
|
||
self.ParticleSystem:SetHiddenInGame(InShow, false)
|
||
end
|
||
|
||
function BP_PlayerPawn:ClearParticles()
|
||
for _, v in pairs(self.WeaponParticles) do
|
||
v:K2_DestroyComponent(self)
|
||
end
|
||
|
||
self.WeaponParticles = {}
|
||
end
|
||
|
||
function BP_PlayerPawn:IsInMainArea()
|
||
return self.IsInArena
|
||
end
|
||
|
||
function BP_PlayerPawn:IsInExerciseRoom()
|
||
return not self.IsInArena
|
||
end
|
||
|
||
function BP_PlayerPawn:OnRep_IsInArena()
|
||
-- 进行
|
||
if UE.IsValid(self.WeaponActor) then
|
||
self.WeaponActor:PlayerInArena(self.IsInArena)
|
||
end
|
||
end
|
||
|
||
------------------------------- **************** 技能激活 **************** -----------------------------------
|
||
|
||
---@param SkillNameList ESkillName[]
|
||
function BP_PlayerPawn:GiveSkillWithSkillNameList(SkillNameList)
|
||
self.SkillSystemComponent:GiveSkillWithList(SkillNameList)
|
||
end
|
||
|
||
---@param SkillName ESkillName
|
||
---@param SlotID ESkillSlot
|
||
---@param SkillLevel int
|
||
---@return number 返回-1则添加技能失败,返回0则代表当前slot无技能,其余正常情况返回技能ID
|
||
function BP_PlayerPawn:GiveSkill(SkillName, SlotID, SkillLevel)
|
||
return self.SkillSystemComponent:GiveSkill(SkillName, SlotID, SkillLevel)
|
||
end
|
||
|
||
function BP_PlayerPawn:TryActiveSkillBySlot(SkillSlot)
|
||
if self.SkillSystemComponent ~= nil then
|
||
self.SkillSystemComponent:TryActiveSkillBySlot(SkillSlot)
|
||
else
|
||
UE.Log("SkillSystemComponent of PlayerPawn is nil")
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:RemoveSkill(SkillName)
|
||
if self.SkillSystemComponent ~= nil then
|
||
self.SkillSystemComponent:RemoveSkill(SkillName)
|
||
end
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_MulticastRPC_PlayEffect(InstanceId, EffectId, CasterActor, ActorList, Duration, SpawnLocationType, BoneName)
|
||
if (not UE.IsValid(CasterActor)) then
|
||
UE.Log("[Client_MulticastRPC_PlayEffect] invalid CasterActor")
|
||
return
|
||
end
|
||
local EffectSystemManager = require('Script.Manager.EffectSystemManager')
|
||
EffectSystemManager.PlayEffect(InstanceId, EffectId, CasterActor, ActorList, Duration, SpawnLocationType, BoneName)
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_MulticastRPC_PlayDirectionalEffect(InstanceId, EffectId, CasterActor, DestActor, Duration, Rotation)
|
||
if (not UE.IsValid(CasterActor)) then
|
||
UE.Log("[Client_MulticastRPC_PlayDirectionalEffect] invalid CasterActor")
|
||
return
|
||
end
|
||
local EffectSystemManager = require('Script.Manager.EffectSystemManager')
|
||
EffectSystemManager.PlayDirectionalEffect(InstanceId, EffectId, CasterActor, DestActor, Duration, Rotation)
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_MulticastRPC_PlayEffectAtLocation(InstanceId, EffectId, CasterActor, Location, Rotation, Duration)
|
||
if (not UE.IsValid(CasterActor)) then
|
||
UE.Log("[Client_MulticastRPC_PlayEffectAtLocation] invalid CasterActor")
|
||
return
|
||
end
|
||
local EffectSystemManager = require('Script.Manager.EffectSystemManager')
|
||
EffectSystemManager.PlayEffectAtLocation(InstanceId, EffectId, CasterActor, Location, Rotation, Duration)
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_MulticastRPC_RemoveSkillEffect(SkillName, InstanceId, CasterActor)
|
||
if (not UE.IsValid(CasterActor)) then
|
||
UE.Log("[Client_MulticastRPC_RemoveSkillEffect] invalid CasterActor")
|
||
return
|
||
end
|
||
local EffectSystemManager = require('Script.Manager.EffectSystemManager')
|
||
EffectSystemManager.RemoveSkillEffectByInstanceId(SkillName, InstanceId, CasterActor)
|
||
end
|
||
|
||
function BP_PlayerPawn:Client_MulticastRPC_RemoveAllSkillEffect(CasterActor)
|
||
if (not UE.IsValid(CasterActor)) then
|
||
UE.Log("[Client_MulticastRPC_RemoveAllSkillEffect] invalid CasterActor")
|
||
return
|
||
end
|
||
local EffectSystemManager = require('Script.Manager.EffectSystemManager')
|
||
EffectSystemManager.RemoveAllEffectOfActor(CasterActor)
|
||
end
|
||
|
||
------------------------------- **************** Debug **************** -----------------------------------
|
||
function BP_PlayerPawn:DrawDebugSphere(Center, Color, Radius)
|
||
STExtraGameplayStatics.ClientDrawDebugSphere(Center, Radius, 10, Color, 10, 1)
|
||
end
|
||
|
||
|
||
function BP_PlayerPawn:DrawDebugLine(Start, End, Color)
|
||
STExtraGameplayStatics.ClientDrawDebugLine(Start, End, Color, 10, 1)
|
||
end
|
||
|
||
|
||
function BP_PlayerPawn:DrawDebugBox(Center, Extent, Color, Rotation)
|
||
STExtraGameplayStatics.ClientDrawDebugBox(Center, Extent, Color, Rotation, 1, 2)
|
||
end
|
||
|
||
return BP_PlayerPawn; |