---@class UGCPlayerPawn_C:BP_UGCPlayerPawn_C ---@field ShapeMesh UStaticMeshComponent ---@field ShapeTransformCollision UCapsuleComponent ---@field ShapeTransformation UShapeTransformationComponent ---@field SpringArm USpringArmComponent ---@field BigCamera UCameraComponent --Edit Below-- ---@type UGCPlayerPawn_C local UGCPlayerPawn = {}; ---@type int32 UGCPlayerPawn.CameraAddLength = 20; ---@type UCameraComponent UGCPlayerPawn.CurrentCamera = nil; ---@type USpringArmComponent UGCPlayerPawn.CurrentSpringArm = nil; --- 是否受到过伤害 UGCPlayerPawn.bHadTokenDamage = false; ---@type table 这个是暂存用的 UGCPlayerPawn.BenefitTable = {}; UGCPlayerPawn.BaseJumpZVelocity = 443.0; function UGCPlayerPawn:ReceiveBeginPlay() self.SuperClass.ReceiveBeginPlay(self); self.bVaultIsOpen = DefaultSettings.OpenVault; self.IsOpenShovelAbility = DefaultSettings.OpenShovel; -- 因为无敌时间是 2 s,因此设置为 1.3 s UGCEventSystem.SetTimer(self, function() self:InitPawn(); end, 1); UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self) ---@type PlayerKDAItem1 local Kda = UGCGameSystem.GameState:GetPlayerKDA(self.PlayerKey) if Kda == nil or Kda.Dead == 0 then self:FirstBeginPlay(); else self:RespawnBeginPlay(Kda.Dead); end self.EquipWeaponComplete:Add(self.OnPlayerEquipWeapon, self) self.UnequipWeaponComplete:Add(self.OnPlayerUnequipWeapon, self) if IsClient then self.ScopeInComplete:Add(self.OnOpenScope, self) self.OnScopeOutDelegate:Add(self.OnOutScope, self) end self.BaseGravity = self.STCharacterMovement.GravityScale; self.CachedGravity = self.STCharacterMovement.GravityScale; self.BaseJumpZVelocity = UGCPawnAttrSystem.GetJumpZVelocity(self); --if self:GetPickupManagerComponent() then -- UGCLogSystem.Log("[UGCPlayerPawn:ReceiveBeginPlay] 添加上去") -- self:GetPickupManagerComponent().OnPickUpTarger:Add(self.OnPickUpItem, self); --end self.OnPlayerPickUp:Add(self.AfterPlayerPickUp, self) local BackComp = UGCBackPackSystem.GetBackpackComponent(self) if BackComp then BackComp.ItemUpdatedDelegate:Add(self.OnItemUpdate, self) end end function UGCPlayerPawn:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); self:DamageTick(DeltaTime); if DefaultSettings.EnableTest then end end function UGCPlayerPawn:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); if IsClient then self.ScopeInComplete:Remove(self.OnOpenScope, self) self.OnScopeOutDelegate:Remove(self.OnOutScope, self) end self.EquipWeaponComplete:Remove(self.OnPlayerEquipWeapon, self) self.UnequipWeaponComplete:Remove(self.OnPlayerUnequipWeapon, self) --if UGCEventSystem then -- UGCEventSystem.RemoveListener(EventTypes.ClientAlready, self.OnClientAlready, self) --end if GlobalTickTool then GlobalTickTool:RemoveAll(self) end if self.PickupManagerComponentRef then self.PickupManagerComponentRef.OnPickUpTarger:Remove(self.OnPickUpItem, self); end self.OnPlayerPickUp:Remove(self.AfterPlayerPickUp, self) end function UGCPlayerPawn:GetReplicatedProperties() return "CachedBodySize" , "CachedGravity" end function UGCPlayerPawn:GetAvailableServerRPCs() return "RespawnBeginPlay" , "OnPickUpItem" , "AfterPlayerPickUp" , "ReplacePartId" end function UGCPlayerPawn:ReceivePossessed(NewController) self.SuperClass.ReceivePossessed(self, NewController); if UGCGameSystem.GameState and UGCGameSystem.GameState.MiniGameManager then table.func(UGCGameSystem.GameState.MiniGameManager, "OnPlayerPossessed", self, NewController); end end --- 第一次进入游戏执行函数 function UGCPlayerPawn:FirstBeginPlay() end ---@param InDeadTimes int32 function UGCPlayerPawn:RespawnBeginPlay(InDeadTimes) -- 应用一下 if IsServer then --self:UseBenefit(true); else UnrealNetwork.CallUnrealRPC(LocalPlayerController, self, "RespawnBeginPlay", InDeadTimes); end end UGCPlayerPawn.BaseTargetOffset = {X=0,Y=0,Z=178.000000}; UGCPlayerPawn.BaseTargetArmLength = 220; function UGCPlayerPawn:InitPawn() if UGCGameSystem.GameState and GameState.MiniGameManager then table.func(GameState.MiniGameManager, "OnPawnInit", self); end if IsServer then self:EnablePickUp(DefaultSettings.EnableAutoPickUp); self:UseBenefit(true); ---@type PlayerKDAItem1 self:InitBenefit(); local KDA = GameState:GetPlayerKDA(self.PlayerKey) if (KDA.Dead) <= DefaultSettings.GiveWeaponTimes then self:AddInitItems(); end self:TestPawn(); else self:SetCurrentCamera(self.Camera, self.CustomSpringArm); end -- 获取玩家属性变化 local BodySize = UGCGameSystem.GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.BodySize); if BodySize ~= nil then if IsServer then self.CachedBodySize = BodySize; self:ChangeBody(BodySize); else self:ClientChangeBody(BodySize); end else if IsServer then self.CachedBodySize = 1; end end end ---@return bool 是否开启掉落盒子 function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater) return DefaultSettings.EnableDeadBox; end function UGCPlayerPawn:OnClientAlready() --if self:GetPickupManagerComponent() then -- -- 这个在手机上添加不上去 -- UGCLogSystem.Log("[UGCPlayerPawn:OnClientAlready] 添加上去") -- self:GetPickupManagerComponent().OnPickUpTarger:Add(self.OnPickUpItem, self); --end end ----------------------------------------- Camera ----------------------------------------- ---获取当前正在使用的 Camera ---@return UCameraComponent function UGCPlayerPawn:GetCamera() return self.CurrentCamera; end ---@return USpringArmComponent function UGCPlayerPawn:GetCurrentSpringArm() if self.CurrentSpringArm == nil then return self.CustomSpringArm; end return self.CurrentSpringArm; end ---@param InCamera UCameraComponent ---@param InArm USpringArmComponent function UGCPlayerPawn:SetCurrentCamera(InCamera, InArm) self.CurrentCamera = InCamera; self.CurrentSpringArm = InArm; end function UGCPlayerPawn:OnOpenScope() UGCLogSystem.Log("[UGCPlayerPawn:OnOpenScope] 开镜!") end function UGCPlayerPawn:OnOutScope(bIsBegin) UGCLogSystem.Log("[UGCPlayerPawn:OnOutScope] 关镜 bIsBegin = %s", tostring(bIsBegin)) end ----------------------------------------- 玩家伤害处理 ----------------------------------------- function UGCPlayerPawn:GetDamageParam() return GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.Damage); end function UGCPlayerPawn:PreInstigatedDamage(DamageAmount, DamageEvent, DamageCauser, Victim) UGCLogSystem.Log("[UGCPlayerPawn:PreInstigatedDamage] DamageAmount = %f", DamageAmount); return DamageAmount; end --- 玩家受到伤害修改事件 ---@field UGC_TakeDamageOverrideEvent fun(Damage:float,DamageType:EDamageType,EventInstigator:AController,DamageCauser:AActor,Hit:FHitResult):float ---@param Damage float ---@param DamageType EDamageType ---@param EventInstigator UGCPlayerController_C ---@param DamageCauser AActor ---@param Hit FHitResult function UGCPlayerPawn:UGC_TakeDamageOverrideEvent(Damage, DamageType, EventInstigator, DamageCauser, Hit) UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] DamageType = %s", tostring(DamageType)); if DefaultSettings.CloseDropDamage then if DamageType == EDamageType.FallingDamage then return 0; end end if EventInstigator ~= nil then local KillPlayerKey = EventInstigator.PlayerKey; local Killer = UGCGameSystem.GetPlayerPawnByPlayerKey(KillPlayerKey); --- 如果开启友伤 if not DefaultSettings.TeamDamage then local TeamId = UGCPlayerStateSystem.GetTeamID(KillPlayerKey); local SelfTeamId = UGCPlayerStateSystem.GetTeamID(self.PlayerKey) if TeamId == SelfTeamId then Damage = 0; end end --- 自己造成的伤害 self.PlayerState.DamagedPlayerList[KillPlayerKey] = UE.GetCurrentTime() + DefaultSettings.AssistContinueTime; -- 伤害处理 Damage = self:UseOneBenefit(DefaultSettings.EPawnBenefitType.Damage, true) * Damage; --local Shield = self:UseOneBenefit(DefaultSettings.EPawnBenefitType.Shield, true); --UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Shield = %f", Shield); --Damage = DefaultSettings.ShieldFunc(Damage, Shield); local KillerCurrSlot = UGCWeaponManagerSystem.GetCurrentWeaponSlot(Killer) if ESurviveWeaponPropSlot.SWPS_HandProp == KillerCurrSlot then UGCLogSystem.UGCLog("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] 使用拳头攻击"); else ---@type ASTExtraWeapon local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(Killer); if Weapon then UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Weapon = %s", UE.GetName(Weapon)); end end else --- 查看是否是毒圈上海 if DamageType == EDamageType.PoisonDamage then Damage = self:ApplyPoisonDamage(Damage) Damage = Damage == nil and 0 or Damage; UGCLogSystem.Log("[UGCPlayerPawn:UGC_TakeDamageOverrideEvent] Damage = %s", tostring(Damage)); end end if Damage > 0 then UGCEventSystem.SendEvent(EventTypes.PlayerInjury, self.PlayerKey, UE.IsValid(EventInstigator) and EventInstigator.PlayerKey or nil, Damage) end --UnrealNetwork.CallUnrealRPC(self.Controller, self, "ClientReceiveDamage", Damage, DamageType, EventInstigator, DamageCauser); --- 判断是不是平底锅的伤害,输出一下 return Damage; end ---@param Damage float ---@param DamageType EDamageType ---@param Causer AActor function UGCPlayerPawn:ClientReceiveDamage(Damage, DamageType, EventInstigator, Causer) end --- 应用毒圈伤害 function UGCPlayerPawn:ApplyPoisonDamage(InDamage) -- 检查体型是否已经很大 return InDamage; end --- 服务器/客户端收到伤害数据 ---@param Damage float ---@param DamageType UDamageType ---@param InstigatedBy UGCPlayerController_C ---@param DamageCauser AActor function UGCPlayerPawn:BPReceiveDamage(Damage, DamageType, InstigatedBy, DamageCauser) if GameState.MiniGameManager then table.func(GameState.MiniGameManager, "BPReceiveDamage", self, Damage, DamageType, EventInstigator, Causer); end if Damage > 0 then UGCEventSystem.SendEvent(EventTypes.PlayerInjury, self.PlayerKey, UE.IsValid(EventInstigator) and EventInstigator.PlayerKey or nil, Damage) end if Damage > 0 then self.bHadTokenDamage = true; end if DamageType == EDamageType.PoisonDamage then UGCEventSystem.SendEvent(EventTypes.PlayerPoisonDamage, self.PlayerKey, Damage); end end function UGCPlayerPawn:DamageTick(InTime) if IsServer then local Time = UE.GetCurrentTime() for i, v in pairs(self.PlayerState.DamagedPlayerList) do if v >= Time then self.PlayerState.DamagedPlayerList[i] = nil end end end end --- 当击杀其他玩家的时候 ---@param InVictimPlayerKey PlayerKey function UGCPlayerPawn:OnKillOther(InVictimPlayerKey) -- 让玩家体型增大 if self:IsAlive() then --self:AddBuff("ApplyKillChange", nil, 1, nil, nil); local Attr = GameState:GetPlayerAttribute(self.PlayerKey); self:UseBenefit(true); UGCPawnAttrSystem.SetHealth(self, UGCPawnAttrSystem.GetHealth(self) + 20); else end end ---@return bool 是否受到过伤害 function UGCPlayerPawn:HadTokenDamage() return self.bHadTokenDamage; end --- 武器攻击到什么东西的时候 ---@param ShootWeapon ASTExtraShootWeapon ---@param Bullet ASTExtraShootWeaponBulletBase ---@param HitInfo FHitResult function UGCPlayerPawn:UGC_WeaponBulletHitEvent(ShootWeapon, Bullet, HitInfo) --local HitActor = HitInfo.Actor:Get() local HitLoc = VectorHelper.ToString(HitInfo.Location) UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] HitLoc = %s", HitLoc); if IsServer then local ItemId = ShootWeapon:GetWeaponItemID(); if ItemId == 107001 then local DamageChannel = ECollisionChannel.ECC_Visibility; local bTakeDamage = UGCGameSystem.ApplyRadialDamage(75, 10, HitInfo.Location, 10, 200, 4, EDamageType.RadialDamage, {}, ShootWeapon, UGCGameSystem.GetPlayerControllerByPlayerKey(self.PlayerKey), DamageChannel, 107001 ); if bTakeDamage then -- 造成了伤害 UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] 造成了伤害") else UGCLogSystem.Log("[UGCPlayerPawn:UGC_WeaponBulletHitEvent] 没有造成伤害") end UnrealNetwork.CallUnrealRPC_Multicast(self, "Client_OnShootEmitter", VectorHelper.ToLuaTable(HitInfo.Location)); end end end function UGCPlayerPawn:Client_OnShootEmitter(Location) local Path = '/Game/Arts_Effect/ParticleSystems/Share/P_AH6_baozha_01.P_AH6_baozha_01'; UE.AsyncLoadObject_Cached(Path, function(TargetObject) GameplayStatics.SpawnEmitterAtLocation(self, TargetObject, Location, VectorHelper.RotZero(), VectorHelper.ScaleOne(), false); end) end ----------------------------------------- Benefit ----------------------------------------- function UGCPlayerPawn:InitBenefit() if DefaultSettings.UseDurableBenefit then self.BenefitTable = TableHelper.DeepCopyTable(self.PlayerState.BenefitTable) self:CheckBenefits(); end if table.isEmpty(self.BenefitTable) then for i, v in pairs(DefaultSettings.EPawnBenefitType) do self:ResetBenefitType(v); end end UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:InitBenefit] self.BenefitTable ="), self.BenefitTable) DOREPONCE(self, "BenefitTable") end function UGCPlayerPawn:CheckBenefits() if self.BenefitTable == nil then self.BenefitTable = {}; end for i = 1, table.getCount(DefaultSettings.EPawnBenefitType) do if self.BenefitTable[i] == nil then self:ResetBenefitType(i); end end end --- 重置玩家属性特征 function UGCPlayerPawn:ResetBenefitType(v) self.BenefitTable[v] = 0; end ---@param InType EPawnBenefitType ---@param InVal float function UGCPlayerPawn:AddBenefit(InType, InVal) InVal = self:GetBenefit(InType) + InVal self:SetBenefit(InType, InVal < 0 and 0 or InVal); end ---@param InVal float function UGCPlayerPawn:SetMaxHealth(InVal) --UGCLogSystem.Log("[UGCPlayerPawn:SetMaxHealth] 执行 InVal = %f", InVal) local CurrMax = UGCPawnAttrSystem.GetHealthMax(self); local NextMax = InVal * 100; if CurrMax == NextMax then return; end local Health = UGCPawnAttrSystem.GetHealth(self) local NextHealth = NextMax / CurrMax * Health; UGCPawnAttrSystem.SetHealthMax(self, NextMax); UGCPawnAttrSystem.SetHealth(self, NextHealth); end ---@param InVal float function UGCPlayerPawn:AddHealthMax(InVal) self:SetMaxHealth(UGCPawnAttrSystem.GetHealthMax(self) + InVal); end ---@param InVal float 增长的百分比 ---@param InLimit float 限制的百分比 function UGCPlayerPawn:AddLimitHealth(InVal, InLimit) local HealthMax = UGCPawnAttrSystem.GetHealthMax(self); local Health = UGCPawnAttrSystem.GetHealth(self); local Rate = Health / HealthMax; local UseSuccess = false; if Rate < InLimit then UGCPawnAttrSystem.SetHealth(self, math.min(InLimit * HealthMax)) UseSuccess = true; end return UseSuccess; end --- 应用 Benefit ---@param InType EPawnBenefitType ---@param InVal float function UGCPlayerPawn:SetBenefit(InType, InVal) if InVal == nil or InVal == 0 then return; end self.BenefitTable[InType] = InVal == nil and 0 or InVal; self:UseBenefit(true); DOREPONCE(self, "BenefitTable"); end ---@param InType EPawnBenefitType function UGCPlayerPawn:GetBenefit(InType) return self.BenefitTable[InType] == nil and 0 or self.BenefitTable[InType]; end function UGCPlayerPawn:GetTotalBenefit(InType) return self:GetBenefit(InType) + GameState:GetPlayerAttribute(self.PlayerKey, InType); end ---@param IsAddAttr bool 是否也加上 GameState 中的 PlayerAttribute ---@param InTable table function UGCPlayerPawn:UseBenefit(IsAddAttr, InTable) if InTable == nil then if table.isEmpty(self.BenefitTable) then self:InitBenefit(); end InTable = self.BenefitTable; end UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:UseBenefit] InTable ="), InTable) for InType, InVal in pairs(InTable) do self:UseOneBenefit(InType, IsAddAttr); end end ---@param InType EPawnBenefitType ---@param IsAddAttr bool ---@return float 具体改变的值 function UGCPlayerPawn:UseOneBenefit(InType, IsAddAttr) if table.isEmpty(self.BenefitTable) then self:InitBenefit(); end local InVal = self.BenefitTable[InType] local c = GameState:GetPlayerAttribute(self.PlayerKey, InType); if IsAddAttr then InVal = InVal + c end if InType == DefaultSettings.EPawnBenefitType.Damage or InType == DefaultSettings.EPawnBenefitType.Shield then elseif InType == DefaultSettings.EPawnBenefitType.Speed then if InVal > DefaultSettings.MaxBodySize then UGCPawnAttrSystem.SetSpeedScale(self, DefaultSettings.MaxBodySize); elseif InVal < 1 then UGCPawnAttrSystem.SetSpeedScale(self, 1); else UGCPawnAttrSystem.SetSpeedScale(self, InVal); end elseif InType == DefaultSettings.EPawnBenefitType.Jump then local AddVal = 0; if InVal > 1 then AddVal = (InVal - 1) * 178.0; end UGCPawnAttrSystem.SetJumpZVelocity(self, 443.0 + AddVal); self.CachedGravity = InVal; self.STCharacterMovement.GravityScale = self.CachedGravity; elseif InType == DefaultSettings.EPawnBenefitType.MaxHealth then self:SetMaxHealth(InVal); elseif InType == DefaultSettings.EPawnBenefitType.BodySize then self:ChangeBody(InVal); end return InVal; end function UGCPlayerPawn:OnRep_BenefitTable() if table.isEmpty(self.BenefitTable) then return end UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:OnRep_BenefitTable] self.BenefitTable ="), self.BenefitTable) UGCEventSystem.SendEvent(EventTypes.PlayerBenefitChange, self.PlayerKey, self.BenefitTable); end function UGCPlayerPawn:OnRep_CachedGravity() if self.CachedGravity ~= 0 then return; end self.STCharacterMovement.GravityScale = self.CachedGravity; end ---@type bool 是否是满血 function UGCPlayerPawn:IsFullHealth() return UGCPawnAttrSystem.GetHealth(self) == UGCPawnAttrSystem.GetHealthMax(self) end UGCPlayerPawn.CachedBodySize = 1; --- 改变体型,会有问题 function UGCPlayerPawn:ChangeBody(InVal) UGCLogSystem.Log("[UGCPlayerPawn:ChangeBody] InVal = %s", tostring(InVal)) if IsServer then if InVal > 2.5 then InVal = DefaultSettings.MaxBodySize end if self:GetActorScale3D().X == InVal then return; end self.CachedBodySize = InVal; self:SetActorScale3D(VectorHelper.MakeVector1(self.CachedBodySize)); end end function UGCPlayerPawn:OnRep_CachedBodySize() if UGCLogSystem then UGCLogSystem.Log("[UGCPlayerPawn:OnRep_CachedBodySize] CachedBodySize = %s, self.PlayerKey = %d", tostring(self.CachedBodySize), self.PlayerKey); end if self.CachedBodySize ~= nil then self:ClientChangeBody(self.CachedBodySize); else local BodySize = UGCGameSystem.GameState:GetPlayerAttribute(self.PlayerKey, DefaultSettings.EPawnBenefitType.BodySize); if BodySize then self.CachedBodySize = BodySize; self:ClientChangeBody(BodySize); else if UGCLogSystem then UGCLogSystem.Log("[UGCPlayerPawn:OnRep_CachedBodySize] BodySize = nil"); end end end end function UGCPlayerPawn:ClientChangeBody(InVal) if UGCLogSystem then UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] InVal = %f", InVal) end if InVal > 2.5 then InVal = DefaultSettings.MaxBodySize end self:SetActorScale3D({ X = InVal, Y = InVal, Z = InVal, }); --UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] self.BaseTargetOffset = %s", tostring(self.BaseTargetOffset)) self:GetCurrentSpringArm().TargetOffset = { X = self.BaseTargetOffset.X * InVal, Y = self.BaseTargetOffset.Y * InVal, Z = self.BaseTargetOffset.Z * InVal}; self:GetCurrentSpringArm().TargetArmLength = self.BaseTargetArmLength * InVal; -- local OldSize = self:GetActorScale3D().X; if OldSize < InVal and OldSize > 1 then --UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] ") if OldSize > 2 then UGCWidgetManagerSystem.ShowTipsUI(string.format('%s体型增至%0.1f!', GameState.PlayerDatas.AccountInfo[self.PlayerKey].PlayerName, InVal)); if LocalPlayerKey == self.PlayerKey then -- 说明是自己 UGCLogSystem.Log("[UGCPlayerPawn:ClientChangeBody] 开始变形"); end end end end --- 添加能量 function UGCPlayerPawn:AddEnergy(InVal) self:SetEnergy(self:GetEnergyCurrent() + InVal); end --- 设置能量 function UGCPlayerPawn:SetEnergy(InVal) self:SetCharacterEnergy(InVal); end --- 清空能量 function UGCPlayerPawn:ClearEnergy() self:SetCharacterEnergy(0.); end -------------------------------- 玩家物品处理 -------------------------------- --- 添加物品,如果是要添加武器,可以在后面的选项进行配置,可添加选项为 是否需要添加对应的配件 武器无限子弹配置 EFillBulletType (bool&EFillBulletType | EFillBulletType) ---@param InItemId int32 ---@param InItemCount int32 function UGCPlayerPawn:AddItem(InItemId, InItemCount, ...) UGCLogSystem.Log("[UGCPlayerPawn:AddItem] InItemId = %d", InItemId); ItemTool.AddItem(self, InItemId, InItemCount, ...); end --- 清空所有物品 function UGCPlayerPawn:ClearItems() ItemTool.ClearAllWeaponsAndProp(self, true, true, true, true, true); end function UGCPlayerPawn:Test_RemoveAttachment() ItemTool.ClearCurrentWeapon(self, true); end --- 添加初始物品 function UGCPlayerPawn:AddInitItems(Weapons) if table.isEmpty(Weapons) then Weapons = DefaultSettings.PlayerInitEquipment end if not table.isEmpty(Weapons) then for i, v in pairs(Weapons) do local ItemId = -1; if type(v[1]) == 'string' then local Item = EnglishNamedWeapon[v[1]] if Item == nil then ItemId = ItemNameTable[v[1]] == nil and ItemId or ItemNameTable[v[1]] else ItemId = Item.ItemId; end elseif type(v[1]) == 'number' then ItemId = v[1]; end local Params = {}; if #v > 1 then for c = 2, #v do Params[#Params + 1] = v[c]; end end UGCLogSystem.LogTree(string.format("[UGCPlayerPawn:AddInitItems] First = %s, Params =", v[1]), Params) if ItemId ~= -1 then self:AddItem(ItemId, table.unpackTable(Params)); end end end end ---@return EFillBulletType function UGCPlayerPawn:GetInfiniteType() local Type = self.PlayerState:GetInfiniteType(); UGCLogSystem.Log("[UGCPlayerPawn:GetInfiniteType] Type = %s", tostring(Type)) return Type end ---@param InType EFillBulletType function UGCPlayerPawn:SetInfiniteType(InType) UGCLogSystem.Log("[UGCPlayerPawn:SetInfiniteType] 执行 InType = %s", tostring(InType)) self.PlayerState:SetInfiniteType(InType); end --- 换弹 function UGCPlayerPawn:WeaponReload() ItemTool.Reload(self, false) end function UGCPlayerPawn:SetPlayerPickUpEnable(IsEnable) DefaultSettings.EnableAutoPickUp = IsEnable; self:EnablePickUp(IsEnable); end --- ---@param slot ESurviveWeaponPropSlot ---@overload fun(slot:ESurviveWeaponPropSlot) OnEquipWeapon function UGCPlayerPawn:OnEquipWeapon(slot) UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] slot = %s, ESurviveWeaponPropSlot.SWPS_HandProp = %d", tostring(slot), ESurviveWeaponPropSlot.SWPS_HandProp); if slot == ESurviveWeaponPropSlot.SWPS_HandProp then UGCLogSystem.Log("[UGCPlayerPawn:OnEquipWeapon] 切换成拳头") end local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, slot); UGCEventSystem.SendEvent(EventTypes.PlayerChangeWeapon, self, slot, Weapon); end function UGCPlayerPawn:OnWeaponEquipAttachment(AttachmentID) UGCLogSystem.Log("[UGCPlayerPawn:OnWeaponEquipAttachment] Attachment ID = %d", AttachmentID); end --- 当玩家拾取之后调用,这个是无论是怎么添加都会走,但是客户端只会走添加的 function UGCPlayerPawn:UGC_PlayerPickUpEvent() UGCLogSystem.Log("[UGCPlayerPawn:UGC_PlayerPickUpEvent] 执行") local Comp = UGCBackPackSystem.GetBackpackComponent(self) for i, v in pairs(ShootWeaponEnums) do local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, v); if Weapon then --local ItemId = Weapon:GetWeaponItemID() -- 查看之前是否有过 end end end function UGCPlayerPawn:OnPostEquipOrUnEquipWeapon(Weapon, bEquip) UGCLogSystem.Log("[UGCPlayerPawn:OnPostEquipOrUnEquipWeapon] 执行") if bEquip then UGCLogSystem.Log("[UGCPlayerPawn:OnPostEquipOrUnEquipWeapon] 玩家装备上 %s", UE.GetName(Weapon)); end end --- 玩家 ---@overload fun() OnUnEquipWeapon function UGCPlayerPawn:OnUnEquipWeapon() UGCLogSystem.Log("[UGCPlayerPawn:OnUnEquipWeapon] 玩家收起武器"); --GameState:ClearWrappers(); local Weapon = UGCWeaponManagerSystem.GetLastUsedWeapon(self) if Weapon then end end --- 当玩家获取武器之后执行 ---@param Weapon ASTExtraWeapon function UGCPlayerPawn:OnPostGetWeapon(Weapon) if UGCGameSystem.GameState then table.func(UGCGameSystem.GameState.MiniGameManager, "OnPlayerGetWeapon", self, Weapon) end end ---@param InHitActor AActor ---@param ImpactPosDistanceToWeapon float ---@param Player APawn function UGCPlayerPawn:OnBulletHitSomething(InHitActor, ImpactPosDistanceToWeapon, Player) if InHitActor then UGCLogSystem.Log("[UGCPlayerPawn:OnBulletHitSomething] 执行:击中了 %s", UE.GetName(InHitActor)); else UGCLogSystem.Log("[UGCPlayerPawn:OnBulletHitSomething] 执行:击中了空的"); end end ---@param DamageDetail FShootWeaponDamageEvent ---@param HitData FBulletHitInfoUploadData ---@param LocalHitData FLocalShootHitData function UGCPlayerPawn:OnWeaponShootHitSomething(DamageDetail, HitData, LocalHitData) -- 执行 UGCLogSystem.Log("[UGCPlayerPawn:OnWeaponShootHitSomething] 击中了 %s", VectorHelper.ToString(HitData.VictimLocation)) end --- 替换配件 ---@param InPartId int32 ---@param InType EWeaponPartType function UGCPlayerPawn:ReplacePartId(InPartId, InType) UGCLogSystem.Log("[UGCPlayerPawn:ReplacePartId] 替换 InPartId = %d", InPartId); -- 移除当前 local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self); if Weapon == nil then return; end if not ItemTool.IsShootWeapon(Weapon) then return; end local DefineID = ItemTool.GetDefineIDBySocketType(Weapon, ItemTool.GetWeaponAttachmentSocketType(InType)); if DefineID then UGCBackPackSystem.DropItemByInstanceID(self, DefineID.InstanceID, 1, true); end if InPartId ~= 0 then ItemTool.AddItem(self, InPartId, 1) end end ----------------------------------------- 玩家拾取 ----------------------------------------- ---@type BP_CustomItemBase_C UGCPlayerPawn.InPickSceneObj_Weapon = nil; UGCPlayerPawn.IsPickUping = false; --- 这个的作用是通过绑定 PickUpTarger 用的 function UGCPlayerPawn:SetInPickUp(InPick, InSceneObj) UGCLogSystem.Log("[UGCPlayerPawn:SetInPickUp] InPick = %s", tostring(InPick)) self.InPickSceneObj_Weapon = InPick and InSceneObj or nil; self.IsPickUping = InPick; end --- 开始拾取的回调 ---@param Target APickUpWrapperActor function UGCPlayerPawn:OnPickUpItem(Target) if IsServer then ---@type BP_WeaponItem_C local Owner = Target:GetOwner() if Owner ~= nil then self:SetInPickUp(true, Owner); if Target ~= nil then UGCLogSystem.Log("[UGCPlayerPawn:OnPickUpItem] Owner = %s, Wrapper Id = %d", UE.GetName(Owner), Target.DefineID.TypeSpecificID); end Owner:OnAutoItemUsed(self, Target == nil and nil or Target.DefineID.TypeSpecificID); end else UGCLogSystem.Log("[UGCPlayerPawn:OnPickUpItem] Target = %s", UE.GetName(Target)); -- 发送到服务器 UnrealNetwork.CallUnrealRPC(self:GetPlayerControllerSafety(), self, "OnPickUpItem", Target); end end -- 这是拾取物品之后调用的了,因此需要清空地面 function UGCPlayerPawn:AfterPlayerPickUp(SelfRef) UGCLogSystem.Log("[UGCPlayerPawn:AfterPlayerPickUp] 拾取之后执行") if IsServer then else UnrealNetwork.CallUnrealRPC(self:GetPlayerControllerSafety(), self, "AfterPlayerPickUp"); end end -------------------------------- 玩家技能 -------------------------------- --- 添加 Buff ---@param InIndex EBuffType ---@param InPlayerKey PlayerKey function UGCPlayerPawn:ApplyBuff(InIndex, InPlayerKey) if IsServer then if type(InIndex) == 'string' then self:AddBuff(InIndex, nil, 1, nil, nil); UGCLogSystem.Log("[UGCPlayerPawn:ApplyBuff] 执行 InIndex = %s", InIndex) UnrealNetwork.CallUnrealRPC_Multicast(self, "ApplyBuff", BuffTable.EBuffType[InIndex], self.PlayerKey); elseif type(InIndex) == 'number' then self:ApplyBuff(BuffTable.GetBuffName(InIndex)); UGCLogSystem.Log("[UGCPlayerPawn:ApplyBuff] 执行 InIndex = %d", InIndex) UnrealNetwork.CallUnrealRPC_Multicast(self, "ApplyBuff", InIndex, self.PlayerKey); end else if UGCPlayerStateSystem.GetTeamID(InPlayerKey) == LocalTeamId then local Name = UE.GetAccountInfo(InPlayerKey).PlayerName; local BuffName = BuffTable.GetBuffName(InIndex); UITool.ShowTips("%s 获取了 Buff: %s", Name, BuffName); end end end --- 受到炸弹伤害,击退玩家 function UGCPlayerPawn:BombSkill() end function UGCPlayerPawn:EnableInvincible(Enable) self:SetInvincible(Enable) end function UGCPlayerPawn:GetEnableInvincible() return self.bInvincible; end function UGCPlayerPawn:AddDamageScale(InVal) self.DamageScaleValue = self.DamageScaleValue + InVal; end --- 玩家眩晕 ---@param IsOpen bool 是否开启 function UGCPlayerPawn:Stun(IsOpen) self:UseSkill(SkillTable.ESkillType.Stun) end function UGCPlayerPawn:UseSkill(InSkillId) local SkillMgr = self:GetSkillManagerComponent() SkillMgr:TriggerEvent(SkillTable.SkillInfo[InSkillId].SkillId, UTSkillEventType.SET_KEY_DOWN) end function UGCPlayerPawn:StopSkill(InSkillId) --local SkillMgr = self:GetSkillManagerComponent() --SkillMgr.StopSkillAll() end --- 玩家被击退 function UGCPlayerPawn:Repulse(InNum) --- LaunchVelocity:FVector,bXYOverride:bool,bZOverride:bool local Vec = VectorHelper.MulNumber(self:GetActorForwardVector(), InNum) --VectorHelper.Add(Vec, VectorHelper.MakeVector(0, 0, 200)); self.CharacterMovement.MovementMode = EMovementMode.MOVE_Falling; self.CharacterMovement.Velocity = VectorHelper.MakeVector(self.CharacterMovement.Velocity.X, self.CharacterMovement.Velocity.Y, 2000); self:Jump(); self:LaunchCharacter(Vec, true, true); end --- function UGCPlayerPawn:PlayerLaunch() local SkillMgr = self:GetSkillManagerComponent() SkillMgr:TriggerEvent(121, UTSkillEventType.SET_KEY_DOWN) end function UGCPlayerPawn:SetState(InState) --self:UGC_LeavePawnStateEvent() UGCPawnSystem.EnterPawnState(self, EPawnState.Stun); end function UGCPlayerPawn:TransShape(InKey) if InKey == nil then self.ShapeTransformation:TransformBackToHuman(); else UGCLogSystem.Log("[UGCPlayerPawn:TransShape] InKey = %s", tostring(InKey)) self.ShapeTransformation:TransformToRandomShape(); end end -------------------------------- 测试 -------------------------------- function UGCPlayerPawn:TestPawn() self:TransShape(); end function UGCPlayerPawn:ClearAllAttachments() UGCLogSystem.Log("[UGCPlayerPawn:ClearAllAttachments] 执行") local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self) if Weapon then local PartList = Weapon:GetAvailableWeaponAttachmentSocketTypeList(); local Parts = UE.ToTable(PartList); table.printTable(Parts); end end function UGCPlayerPawn:Test_AddRangeParts() ItemTool.AddRangeItems(self, 204001, 204100); -- 获取当前武器 local Weapon = UGCWeaponManagerSystem.GetCurrentWeapon(self); local DefineID = ItemTool.GetDefineIDBySocketType(Weapon, ItemTool.GetWeaponAttachmentSocketType(EWeaponPartType.Magazine)); UGCLogSystem.Log("[UGCPlayerPawn:Test_AddRangeParts] DefineID = %d", DefineID.TypeSpecificID); end return UGCPlayerPawn;