特效工程
This commit is contained in:
parent
eee043b70d
commit
47093c4269
BIN
FX_Preview/Asset/Blueprint/SceneActor/BP_PreViewFXActor.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/SceneActor/BP_PreViewFXActor.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCGameMode.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCGameMode.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCGameState.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCGameState.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCLevelDirector.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCLevelDirector.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCPlayerController.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCPlayerController.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCPlayerPawn.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCPlayerPawn.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/Blueprint/UGCPlayerState.uasset
Normal file
BIN
FX_Preview/Asset/Blueprint/UGCPlayerState.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/FX/KillFX/P_Kill_Boom.uasset
Normal file
BIN
FX_Preview/Asset/FX/KillFX/P_Kill_Boom.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/FX/KillFX/P_Kill_Boom_Write.uasset
Normal file
BIN
FX_Preview/Asset/FX/KillFX/P_Kill_Boom_Write.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/FX/MuzzleFX/Rifle/P_MF_Rifle_Base.uasset
Normal file
BIN
FX_Preview/Asset/FX/MuzzleFX/Rifle/P_MF_Rifle_Base.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UGCGameAttributeCache.uasset
Normal file
BIN
FX_Preview/Asset/UGCGameAttributeCache.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_AvatarFrame_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_AvatarFrame_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_CheckBoxButton.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_CheckBoxButton.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_GameFailure_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_GameFailure_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_GameTopBlueTips_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_GameTopBlueTips_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_GameTopRedTips_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_GameTopRedTips_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_GameVictory_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_GameVictory_UIBP.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_Ingame_RingButton.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_Ingame_RingButton.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_Ingame_SquareButton.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_Ingame_SquareButton.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_NoticeTopTips_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_NoticeTopTips_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_Player_infoBar_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_Player_infoBar_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_1.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_1.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_2.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_2.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_3.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_SecondLevelButton_3.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_SlideModeButton.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_SlideModeButton.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_SwitchButton.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_SwitchButton.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_TMode_Discard_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_TMode_Discard_UIBP.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/General_Team_ScoreBoard_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/General_Team_ScoreBoard_UIBP.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_ItemSelect.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_ItemSelect.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_Main_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_Main_UIBP.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_PropsItem.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_PropsItem.uasset
Normal file
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_Props_UIBP.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/Peekaboo/Peekaboo_Props_UIBP.uasset
Normal file
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/ReuseList2.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/ReuseList2.uasset
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
FX_Preview/Asset/UMGTemplate/UGC_DragDropTextBox.uasset
Normal file
BIN
FX_Preview/Asset/UMGTemplate/UGC_DragDropTextBox.uasset
Normal file
Binary file not shown.
0
FX_Preview/DeleteFiles.txt
Normal file
0
FX_Preview/DeleteFiles.txt
Normal file
71
FX_Preview/FX_Preview.ugcproj
Normal file
71
FX_Preview/FX_Preview.ugcproj
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
[Root]
|
||||||
|
ProjectDisplayName=FX_Preview
|
||||||
|
ProjectDescription=FX_Preview
|
||||||
|
ProjectName=FX_Preview
|
||||||
|
ProjectTrueName=476869D89E45FE63A6DBF94A8DF5E10CF1E4A168214DF9FA013EFC1D81AC60CF
|
||||||
|
ProjectShortPath=/FX_Preview/
|
||||||
|
StartMapName=/FX_Preview/UGCmap
|
||||||
|
MapMode=0
|
||||||
|
bIsBigWorld=0
|
||||||
|
Version=1.29.13.13030
|
||||||
|
UpdateVersion=5
|
||||||
|
GameModePath=/FX_Preview/Asset/Blueprint/UGCGameMode.UGCGameMode_C
|
||||||
|
DefaultLevelDirectorPath=/Asset/Blueprint/UGCLevelDirector.UGCLevelDirector_C
|
||||||
|
|
||||||
|
[MatchSetting]
|
||||||
|
NumberOfTeams=1
|
||||||
|
TeamPlayers=1
|
||||||
|
bEnableChat=0
|
||||||
|
bEnableRoomChat=0
|
||||||
|
ChannelName=全部
|
||||||
|
RoomName=全部
|
||||||
|
bEnablePrivateChat=0
|
||||||
|
bEnableTeamChat=0
|
||||||
|
bShowMessage=0
|
||||||
|
bMessageDisappear=0
|
||||||
|
MessageLifetime=0.0
|
||||||
|
MaxMessageLines=6
|
||||||
|
bEnableSystemChannel=0
|
||||||
|
bEnableChatBubble=0
|
||||||
|
BubbleLifetime=10
|
||||||
|
MatchMethod=0
|
||||||
|
InitialScore=2000
|
||||||
|
MinScore=0
|
||||||
|
MaxScore=4000
|
||||||
|
RankDensity=100
|
||||||
|
BeyondRankTime=10
|
||||||
|
BeyondRankNum=10
|
||||||
|
TeamScoreCalculation=0
|
||||||
|
bUseMultiModeMatchSetting=0
|
||||||
|
MultiModeSettingNum=0
|
||||||
|
|
||||||
|
[MiniMap]
|
||||||
|
ZoomRatios=100
|
||||||
|
SliderExpandRatios=100
|
||||||
|
UserDefineMapPath=0
|
||||||
|
|
||||||
|
[SwitchesInMaps]
|
||||||
|
SwitchesInMaps=((Key="r.Mobile.EnableIBL",Value=0),(Key="s.StreamableDelegateLimitCount",Value=0),(Key="s.StreamableDelegateLimitTime",Value=0.001),(Key="r.mobile.HZBOcclusion",Value=0),(Key="r.mobile.allowsoftwareocclusion",Value=1),(Key="AnimDynamicStateFlipSmoothFrame",Value=5))
|
||||||
|
|
||||||
|
[PlayBinding]
|
||||||
|
PlayBindingArray=[]
|
||||||
|
|
||||||
|
[JobOption]
|
||||||
|
LastJobId=-1
|
||||||
|
LastWindowsJobId=-1
|
||||||
|
LastAndroidJobId=-1
|
||||||
|
LastIOSJobId=-1
|
||||||
|
PakOnly=0
|
||||||
|
LastSkipBake=False
|
||||||
|
LastTargetPlatform=LinuxServer
|
||||||
|
|
||||||
|
[UGCUploadOption]
|
||||||
|
PlatformIndex=0
|
||||||
|
SkipBake=False
|
||||||
|
TargetPlatform=LinuxServer+WindowsNoEditor+Android_ETC2+IOS+OpenHarmony_ETC2
|
||||||
|
|
||||||
|
[DebugSettings]
|
||||||
|
bRoomOB=0
|
||||||
|
TeamPlayers=1,0;1,0;1,0;
|
||||||
|
|
||||||
|
|
42
FX_Preview/Script/Blueprint/SceneActor/BP_PreViewFXActor.lua
Normal file
42
FX_Preview/Script/Blueprint/SceneActor/BP_PreViewFXActor.lua
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---@class BP_PreViewFXActor_C:AActor
|
||||||
|
---@field DynamicTextRender UDynamicTextRenderComponent
|
||||||
|
---@field DefaultSceneRoot USceneComponent
|
||||||
|
---@field MuzzleParticle UParticleSystem
|
||||||
|
---@field KillParticle UParticleSystem
|
||||||
|
---@field BulletParticle UParticleSystem
|
||||||
|
---@field HitParticle UParticleSystem
|
||||||
|
---@field KillParticleOffsetTF FTransform
|
||||||
|
--Edit Below--
|
||||||
|
local BP_PreViewFXActor = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function BP_PreViewFXActor:ReceiveBeginPlay()
|
||||||
|
BP_PreViewFXActor.SuperClass.ReceiveBeginPlay(self)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function BP_PreViewFXActor:ReceiveTick(DeltaTime)
|
||||||
|
BP_PreViewFXActor.SuperClass.ReceiveTick(self, DeltaTime)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function BP_PreViewFXActor:ReceiveEndPlay()
|
||||||
|
BP_PreViewFXActor.SuperClass.ReceiveEndPlay(self)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function BP_PreViewFXActor:GetReplicatedProperties()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function BP_PreViewFXActor:GetAvailableServerRPCs()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
return BP_PreViewFXActor
|
32
FX_Preview/Script/Blueprint/UGCGameMode.lua
Normal file
32
FX_Preview/Script/Blueprint/UGCGameMode.lua
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---@class UGCGameMode_C:BP_UGCGameBase_C
|
||||||
|
--Edit Below--
|
||||||
|
local UGCGameMode = {};
|
||||||
|
|
||||||
|
-- 射击枪械槽类型
|
||||||
|
ShootWeaponEnums = {
|
||||||
|
ESurviveWeaponPropSlot.SWPS_MainShootWeapon1,
|
||||||
|
ESurviveWeaponPropSlot.SWPS_MainShootWeapon2,
|
||||||
|
ESurviveWeaponPropSlot.SWPS_SubShootWeapon,
|
||||||
|
};
|
||||||
|
function UGCGameMode:ReceiveBeginPlay()
|
||||||
|
UGCEventSystem.SetTimerLoop(UGCGameSystem.GameState, function()
|
||||||
|
local AllPlayerPawn = UGCGameSystem.GetAllPlayerPawn()
|
||||||
|
for i, PlayerPawn in pairs(AllPlayerPawn) do
|
||||||
|
for k, ShootWeaponEnum in pairs(ShootWeaponEnums) do
|
||||||
|
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(PlayerPawn, ShootWeaponEnum)
|
||||||
|
if UE.IsValid(Weapon) then
|
||||||
|
UGCGunSystem.EnableClipInfiniteBullets(Weapon, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, 0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
-- function UGCGameMode:ReceiveTick(DeltaTime)
|
||||||
|
|
||||||
|
-- end
|
||||||
|
-- function UGCGameMode:ReceiveEndPlay()
|
||||||
|
|
||||||
|
-- end
|
||||||
|
return UGCGameMode;
|
44
FX_Preview/Script/Blueprint/UGCGameState.lua
Normal file
44
FX_Preview/Script/Blueprint/UGCGameState.lua
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
---@class UGCGameState_C:BP_UGCGameState_C
|
||||||
|
--Edit Below--
|
||||||
|
UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom')
|
||||||
|
UGCGameSystem.UGCRequire('Script.Global.Global')
|
||||||
|
|
||||||
|
local UGCGameState = {};
|
||||||
|
function UGCGameState:ReceiveBeginPlay()
|
||||||
|
self.IsShowDeadBox = false;
|
||||||
|
UGCEventSystem.AddListener(EventEnum.PlayerDeathInfo, self.RespawnPlayer, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCGameState:RespawnPlayer(DeadPlayerKey)
|
||||||
|
UGCEventSystem.SetTimer(self, function() UGCGameSystem.RespawnPlayer(DeadPlayerKey) end, 4)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCGameState:GetPreViewFXActor()
|
||||||
|
if not UE.IsValid(self.PreViewActor) then
|
||||||
|
self.PreViewActor = UGCSystemLibrary.GetUniqueInstanceFromPath(UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/SceneActor/BP_PreViewFXActor.BP_PreViewFXActor_C'))
|
||||||
|
end
|
||||||
|
return self.PreViewActor
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCGameState:SpawnParticleAtPos(Pos)
|
||||||
|
local TempPreViewActor = self:GetPreViewFXActor()
|
||||||
|
if UE.IsValid(TempPreViewActor) then
|
||||||
|
Pos = {
|
||||||
|
X = Pos.X + TempPreViewActor.KillParticleOffsetTF.Translation.X,
|
||||||
|
Y = Pos.Y + TempPreViewActor.KillParticleOffsetTF.Translation.Y,
|
||||||
|
Z = Pos.Z + TempPreViewActor.KillParticleOffsetTF.Translation.Z,
|
||||||
|
}
|
||||||
|
local FXScale = {X = TempPreViewActor.KillParticleOffsetTF.Scale3D.X, Y = TempPreViewActor.KillParticleOffsetTF.Scale3D.Y, Z = TempPreViewActor.KillParticleOffsetTF.Scale3D.Z}
|
||||||
|
GameplayStatics.SpawnEmitterAtLocation(self, TempPreViewActor.KillParticle, Pos, {Roll = 0, Pitch = 0, Yaw = 0}, FXScale, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- function UGCGameState:ReceiveTick(DeltaTime)
|
||||||
|
|
||||||
|
-- end
|
||||||
|
-- function UGCGameState:ReceiveEndPlay()
|
||||||
|
|
||||||
|
-- end
|
||||||
|
|
||||||
|
|
||||||
|
return UGCGameState;
|
177
FX_Preview/Script/Blueprint/UGCPlayerPawn.lua
Normal file
177
FX_Preview/Script/Blueprint/UGCPlayerPawn.lua
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
---@class UGCPlayerPawn_C:BP_UGCPlayerPawn_C
|
||||||
|
---@field StartItemID TArray<int32>
|
||||||
|
--Edit Below--
|
||||||
|
local UGCPlayerPawn = {}
|
||||||
|
|
||||||
|
|
||||||
|
-- 关闭盒子掉落
|
||||||
|
function UGCPlayerPawn:IsSkipSpawnDeadTombBox(EventInstigater)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function UGCPlayerPawn:ReceiveBeginPlay()
|
||||||
|
UGCPlayerPawn.SuperClass.ReceiveBeginPlay(self)
|
||||||
|
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
|
||||||
|
self.OnDeath:Add(self.OnDeathCallBack, self)
|
||||||
|
|
||||||
|
UGCEventSystem.SetTimer(self, function()
|
||||||
|
if UE.IsValid(self) then
|
||||||
|
for i, v in pairs(self.StartItemID) do
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_ReceiveBeginPlay] ID:%s", tostring(v))
|
||||||
|
UGCBackPackSystem.AddItem(self, v, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, 5)
|
||||||
|
else
|
||||||
|
|
||||||
|
end
|
||||||
|
if self.CheckFXHandle == nil then
|
||||||
|
-- 这里防止未设置成功做的校验
|
||||||
|
self.CheckFXHandle = UGCEventSystem.SetTimerLoop(self, self.UpdateFX, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local TempRescueOtherComp = self:GetCharacterRescueOtherComponent()
|
||||||
|
local TempPreViewActor = UGCGameSystem.GameState:GetPreViewFXActor()
|
||||||
|
|
||||||
|
if UE.IsValid(TempRescueOtherComp) and UE.IsValid(TempPreViewActor) then
|
||||||
|
-- 配置倒地粒子 没有用这个方法
|
||||||
|
--TempRescueOtherComp.ShouldAddParticleWhenEnterLastBreath = true
|
||||||
|
--TempRescueOtherComp.ParticleTemplateToAddWhenEnterLastBreath = TempPreViewActor.KillParticle
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_ReceiveBeginPlay] Succeed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function UGCPlayerPawn:ReceiveTick(DeltaTime)
|
||||||
|
UGCPlayerPawn.SuperClass.ReceiveTick(self, DeltaTime)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
|
||||||
|
function UGCPlayerPawn:ReceiveEndPlay()
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
self.OnDeath:Remove(self.OnDeathCallBack, self)
|
||||||
|
end
|
||||||
|
if self.CheckFXHandle then
|
||||||
|
UGCEventSystem.StopTimer(self.CheckFXHandle)
|
||||||
|
self.CheckFXHandle = nil
|
||||||
|
end
|
||||||
|
UGCPlayerPawn.SuperClass.ReceiveEndPlay(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function UGCPlayerPawn:GetReplicatedProperties()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
--[[
|
||||||
|
function UGCPlayerPawn:GetAvailableServerRPCs()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
-- 射击枪械槽类型
|
||||||
|
ShootWeaponEnums = {
|
||||||
|
ESurviveWeaponPropSlot.SWPS_MainShootWeapon1,
|
||||||
|
ESurviveWeaponPropSlot.SWPS_MainShootWeapon2,
|
||||||
|
ESurviveWeaponPropSlot.SWPS_SubShootWeapon,
|
||||||
|
};
|
||||||
|
|
||||||
|
function UGCPlayerPawn:OnPostGetWeapon(Weapon)
|
||||||
|
-- self:UpdateFX()
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_OnPostGetWeapon]")
|
||||||
|
local TempPreViewActor = UGCGameSystem.GameState:GetPreViewFXActor()
|
||||||
|
|
||||||
|
local Effect = Weapon:GetShootWeaponEffectComponent()
|
||||||
|
if UE.IsValid(TempPreViewActor) and UE.IsValid(Effect) and UE.IsValid(TempPreViewActor.MuzzleParticle) then
|
||||||
|
Effect.MuzzleFX = TempPreViewActor.MuzzleParticle
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_OnPostGetWeapon] Succeed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function UGCPlayerPawn:UpdateFX()
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_UpdateFX]")
|
||||||
|
local TempPreViewActor = UGCGameSystem.GameState:GetPreViewFXActor()
|
||||||
|
if UE.IsValid(TempPreViewActor) then
|
||||||
|
for i, v in pairs(ShootWeaponEnums) do
|
||||||
|
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(self, v);
|
||||||
|
if UE.IsValid(Weapon) then
|
||||||
|
local Effect = Weapon:GetShootWeaponEffectComponent()
|
||||||
|
if UE.IsValid(Effect) and UE.IsValid(TempPreViewActor.MuzzleParticle) then
|
||||||
|
Effect.MuzzleFX = TempPreViewActor.MuzzleParticle
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_UpdateFX] Succeed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---@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:PlayerDead(DamageInfo)
|
||||||
|
UGCLogSystem.LogTree("[UGCPlayerPawn_PlayerDead] DamageInfo:", UE.ToTable(DamageInfo))
|
||||||
|
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
|
||||||
|
--UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
|
||||||
|
--UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
|
||||||
|
UGCGameSystem.GameState:SetPlayerIsAlive(VictimKey, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param DamageInfo FDamageInfoCollection
|
||||||
|
---@param ReturnValue float
|
||||||
|
function UGCPlayerPawn:PlayerInjury(DamageInfo)
|
||||||
|
local VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue = self:GetDamageInfoCollectionInfo(DamageInfo)
|
||||||
|
UGCEventSystem.SendEvent(EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
|
||||||
|
UGCSendRPCSystem.RPCEvent(CauserKey, EventEnum.PlayerInjuryInfo, VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCPlayerPawn:OnDeathCallBack(DeadCharacter,Killer,DamageCauser,KillingHitInfo,KillingHitImpulseDir,KillingHitDamageTypeID,DamageTypeClass,IsHeadShotDamage)
|
||||||
|
local CauserKey = Killer and Killer.PlayerKey
|
||||||
|
local WeaponID = -1
|
||||||
|
local DamageType = EDamageType.UGCCustomDamageType + 1
|
||||||
|
UGCLogSystem.Log("[UGCPlayerPawn_TestOnDeath] PlayerKey:%s, CauserKey:%s", tostring(self.PlayerKey), tostring(CauserKey))
|
||||||
|
UGCSendRPCSystem.RPCEvent(nil, EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0)
|
||||||
|
UGCEventSystem.SendEvent(EventEnum.PlayerDeathInfo, self.PlayerKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
-- 发送RPC倒地粒子
|
||||||
|
local SelfPos = self:K2_GetActorLocation()
|
||||||
|
SelfPos = {
|
||||||
|
X = SelfPos.X,
|
||||||
|
Y = SelfPos.Y,
|
||||||
|
Z = SelfPos.Z,
|
||||||
|
}
|
||||||
|
UnrealNetwork.CallUnrealRPC_Multicast(UGCGameSystem.GameState, "SpawnParticleAtPos", SelfPos);
|
||||||
|
end
|
||||||
|
|
||||||
|
return UGCPlayerPawn
|
4
FX_Preview/Script/Common/ue_enum_custom.lua
Normal file
4
FX_Preview/Script/Common/ue_enum_custom.lua
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
-- auto exported UENUM while compiling
|
||||||
|
|
||||||
|
-- sorted by enum name asc
|
||||||
|
|
56
FX_Preview/Script/Global/EventConfig.lua
Normal file
56
FX_Preview/Script/Global/EventConfig.lua
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
EventEnum = {
|
||||||
|
|
||||||
|
-- DefaultEvent
|
||||||
|
DSStartUp = 1001, -- 服务器启动
|
||||||
|
PlayerLogin = 1003, -- 玩家加入房间 PlayerKey
|
||||||
|
PlayerExit = 1004, -- 玩家离开房间 PlayerKey
|
||||||
|
|
||||||
|
-- GameState
|
||||||
|
GameStateChange = 2001, -- 游戏模式改变 CustomEnum.EGameState
|
||||||
|
WaitPlayerJoin = 2002, -- 等待玩家加入
|
||||||
|
GamePlay = 2003, -- 游戏开始
|
||||||
|
GameEnd = 2004, -- 游戏结束
|
||||||
|
RoundBegining = 2005, -- 回合开始
|
||||||
|
RoundEnd = 2006, -- 回合结束
|
||||||
|
RoundReadyFinish = 2007, -- 回合准备阶段结束
|
||||||
|
|
||||||
|
-- PlayerEvent
|
||||||
|
PlayerDeathInfo = 3001, -- 死亡信息 VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue uint, uint, int, int, bool, float, float
|
||||||
|
PlayerInjuryInfo = 3002, -- 受伤信息 VictimKey, CauserKey, WeaponID, DamageType, IsHeadShotDamage, Distance, DamageValue uint, uint, int, int, bool, float, float
|
||||||
|
PlayerPossessed = 3003, -- 玩家受控 PlayerKey
|
||||||
|
PlayerBeginPlay = 3004, -- 玩家受控 PlayerPawn
|
||||||
|
BulletHitCallBack = 3005, -- 玩家射出的子弹命中物体或玩家的回调 (PlayerPawn:UGCPlayerPawn, ShootWeapon:ASTExtraShootWeapon,Bullet:ASTExtraShootWeaponBulletBase,HitInfo:FHitResult)
|
||||||
|
PlayerTeamChange = 3006, -- 玩家的队伍改变 PC, TeamID
|
||||||
|
|
||||||
|
-- PlayerPawn同步参数更新 更新传入Pawn及其同步变量值
|
||||||
|
UpdateCanObtainIncreaseCount = 4001,
|
||||||
|
UpdateNowCanSelectIncrease = 4002,
|
||||||
|
UpdateOwnedIncrease = 4003,
|
||||||
|
UpdateToGodSchedule = 4004,
|
||||||
|
|
||||||
|
-- PlayerEvent End
|
||||||
|
|
||||||
|
|
||||||
|
UpdatePlayerStartList = 10001, -- 通知出生点控制器进行更新出生点指针
|
||||||
|
AchievementSettlement = 10002, -- 成就事件游戏结算
|
||||||
|
UpdateTeamScore = 10003, -- 队伍得分信息更新
|
||||||
|
UpdatePlayerScoreData = 10004, -- 玩家得分信息更新 通过UGCGameSystem.GameState.PlayerScoreDatas 获取玩家得分信息
|
||||||
|
AddTip = 10005, -- 添加提提示 TipStr TipType
|
||||||
|
GameWillBegin = 10006, -- 游戏即将开始
|
||||||
|
PlayerIsAliveIsChange = 10007, -- 玩家存活列表改变
|
||||||
|
UpdatePlayerInfo = 10008, -- 玩家个人信息更新
|
||||||
|
|
||||||
|
PlayerWeaponCombinationUpdate = 11001, -- 玩家可选的武器配置列表更新 [PlayerKey] = CombinationType
|
||||||
|
PlayerSelectedWeaponIndexUpdate = 11002, -- 玩家选择的武器配置索引更新 [PlayerKey] = Index
|
||||||
|
|
||||||
|
|
||||||
|
--- SelectMap
|
||||||
|
LoadMap = 20001, -- 关卡加载 MapConifg.MapType
|
||||||
|
SelectMapCallBack = 20002, -- 地图选择服务器的回调 bSucceed, MapType
|
||||||
|
SelectDefaultWeaponCallBack = 20003, -- 默认武器选择回调 bSucceed, WeaponID
|
||||||
|
RandomSelectVoteMap = 20004,
|
||||||
|
UpdateMapKey = 20005, -- 随机出的地图索引 MapKey
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
-- 需要包含的头目录
|
||||||
|
|
||||||
|
local Prefix = "Script.Global.FunctionExtension."
|
||||||
|
|
||||||
|
require(Prefix .. 'MathExtension')
|
||||||
|
require(Prefix .. 'StringExtension')
|
||||||
|
require(Prefix .. 'TableExtension')
|
||||||
|
require(Prefix .. 'TableHelper')
|
||||||
|
require(Prefix .. 'VectorHelper')
|
||||||
|
require(Prefix .. 'QuatHelper')
|
||||||
|
|
||||||
|
|
||||||
|
|
38
FX_Preview/Script/Global/FunctionExtension/MathExtension.lua
Normal file
38
FX_Preview/Script/Global/FunctionExtension/MathExtension.lua
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
---clamp
|
||||||
|
---@param v number @number
|
||||||
|
---@param Min number @min
|
||||||
|
---@param Max number @max
|
||||||
|
---@return number @clamp v between Min and Max
|
||||||
|
function math.clamp(v, Min, Max)
|
||||||
|
Min = math.min(Min, Max)
|
||||||
|
Max = math.max(Min, Max)
|
||||||
|
if v < Min then
|
||||||
|
return Min
|
||||||
|
end
|
||||||
|
if v > Max then
|
||||||
|
return Max
|
||||||
|
end
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
|
||||||
|
---clamp
|
||||||
|
---@param a number @First number to compare
|
||||||
|
---@param b number @Second number to compare
|
||||||
|
---@param Tolerance number @Maximum allowed difference for considering them as 'nearly equal'
|
||||||
|
---@return boolean @true if a and b are nearly equal
|
||||||
|
function math.isNearlyEqual(a, b, Tolerance)
|
||||||
|
if Tolerance == nil then
|
||||||
|
Tolerance = 0.01
|
||||||
|
end
|
||||||
|
return math.abs(a - b) <= Tolerance
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 在圆中随机生成一个点
|
||||||
|
function math.RandomCirclePoint(Radius, Center)
|
||||||
|
local angle = math.random() * 2 * math.pi;
|
||||||
|
local tr = Radius * math.sqrt(math.random());
|
||||||
|
local x = Center.X + tr * math.cos(angle);
|
||||||
|
local y = Center.Y + tr * math.sin(angle);
|
||||||
|
return { X = x, Y = y };
|
||||||
|
end
|
63
FX_Preview/Script/Global/FunctionExtension/QuatHelper.lua
Normal file
63
FX_Preview/Script/Global/FunctionExtension/QuatHelper.lua
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
QuatHelper = {}
|
||||||
|
-- 四元数结构体
|
||||||
|
QuatHelper = {}
|
||||||
|
QuatHelper.__index = QuatHelper
|
||||||
|
|
||||||
|
-- 创建四元数
|
||||||
|
function QuatHelper.new(W, X, Y, Z)
|
||||||
|
return setmetatable({W = W, X = X, Y = Y, Z = Z}, QuatHelper)
|
||||||
|
end
|
||||||
|
|
||||||
|
function QuatHelper.RotToQuat(Rot)
|
||||||
|
return STExtraBlueprintFunctionLibrary.RotToQuat(Rot)
|
||||||
|
end
|
||||||
|
|
||||||
|
function QuatHelper.QuatToRot(q)
|
||||||
|
return STExtraBlueprintFunctionLibrary.QuatToRot(q)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 四元数乘法 (q1 * q2)
|
||||||
|
function QuatHelper.mul(q1, q2)
|
||||||
|
return QuatHelper.new(
|
||||||
|
q1.W * q2.W - q1.X * q2.X - q1.Y * q2.Y - q1.Z * q2.Z,
|
||||||
|
q1.W * q2.X + q1.X * q2.W + q1.Y * q2.Z - q1.Z * q2.Y,
|
||||||
|
q1.W * q2.Y - q1.X * q2.Z + q1.Y * q2.W + q1.Z * q2.X,
|
||||||
|
q1.W * q2.Z + q1.X * q2.Y - q1.Y * q2.X + q1.Z * q2.W
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 四元数与向量乘法 (q * v),假设向量v是{x, y, z}
|
||||||
|
function QuatHelper.mulVec(q, v)
|
||||||
|
local qv = QuatHelper.new(0, v.x, v.y, v.z)
|
||||||
|
local q_conjugate = QuatHelper.conjugate(q)
|
||||||
|
local result = QuatHelper.mul(QuatHelper.mul(q, qv), q_conjugate)
|
||||||
|
return {x = result.X, y = result.Y, z = result.Z}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 四元数单位化
|
||||||
|
function QuatHelper.normalize(q)
|
||||||
|
local magnitude = math.sqrt(q.W * q.W + q.X * q.X + q.Y * q.Y + q.Z * q.Z)
|
||||||
|
return QuatHelper.new(q.W / magnitude, q.X / magnitude, q.Y / magnitude, q.Z / magnitude)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 四元数共轭
|
||||||
|
function QuatHelper.conjugate(q)
|
||||||
|
return QuatHelper.new(q.W, -q.X, -q.Y, -q.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 四元数逆
|
||||||
|
function QuatHelper.inverse(q)
|
||||||
|
local conjugate = QuatHelper.conjugate(q)
|
||||||
|
local magnitude_squared = q.W * q.W + q.X * q.X + q.Y * q.Y + q.Z * q.Z
|
||||||
|
return QuatHelper.new(conjugate.W / magnitude_squared, conjugate.X / magnitude_squared, conjugate.Y / magnitude_squared, conjugate.Z / magnitude_squared)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 生成四元数字符串表示 (用于调试)
|
||||||
|
function QuatHelper.toString(q)
|
||||||
|
return string.format("(%f, %f, %f, %f)", q.W, q.X, q.Y, q.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return QuatHelper;
|
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
---字符串分割
|
||||||
|
function string:split(sep)
|
||||||
|
--sep = sep or "\t"
|
||||||
|
local fields = {}
|
||||||
|
local pattern = string.format("([^%s]+)", sep)
|
||||||
|
self:gsub(pattern, function(c) fields[#fields+1] = c end)
|
||||||
|
return fields
|
||||||
|
end
|
||||||
|
|
||||||
|
---字符串直接转Number
|
||||||
|
function string.splitToNumber(InStr, sep)
|
||||||
|
--sep = sep or "\t"
|
||||||
|
local fields = {}
|
||||||
|
local pattern = string.format("([^%s]+)", sep)
|
||||||
|
InStr:gsub(pattern, function(c) fields[#fields+1] = tonumber(c) end)
|
||||||
|
return fields
|
||||||
|
end
|
259
FX_Preview/Script/Global/FunctionExtension/TableExtension.lua
Normal file
259
FX_Preview/Script/Global/FunctionExtension/TableExtension.lua
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
-- 拷贝table
|
||||||
|
function table.DeepCopy(object)
|
||||||
|
-- 已经复制过的table,key为复制源table,value为复制后的table
|
||||||
|
-- 为了防止table中的某个属性为自身时出现死循环
|
||||||
|
-- 避免本该是同一个table的属性,在复制时变成2个不同的table(内容同,但是地址关系和原来的不一样了)
|
||||||
|
local lookup_table = {}
|
||||||
|
local function _copy(object)
|
||||||
|
if type(object) ~= 'table' then -- 非table类型都直接返回
|
||||||
|
return object
|
||||||
|
elseif lookup_table[object] then
|
||||||
|
return lookup_table[object]
|
||||||
|
end
|
||||||
|
local new_table = {}
|
||||||
|
lookup_table[object] = new_table
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
new_table[_copy(k)] = _copy(v)
|
||||||
|
end
|
||||||
|
-- 这里直接拿mt来用是因为一般对table操作不会很粗暴的修改mt的相关内容
|
||||||
|
return setmetatable(new_table, getmetatable(object))
|
||||||
|
end
|
||||||
|
return _copy(object)
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.NewLuaObj(InObj)
|
||||||
|
return setmetatable({}, {
|
||||||
|
__index = InObj,
|
||||||
|
__metatable = InObj,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表元素个数
|
||||||
|
function table.getCount(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
local Length = 0
|
||||||
|
for i, v in pairs(t) do
|
||||||
|
Length = Length + 1
|
||||||
|
end
|
||||||
|
return Length
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中所有的Key
|
||||||
|
function table.getKeys(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local keys = {}
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
keys[#keys + 1] = k
|
||||||
|
end
|
||||||
|
return keys
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取对应元素的Index
|
||||||
|
function table.getIndex(t, v)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
for index, value in pairs(t) do
|
||||||
|
if value == v then
|
||||||
|
return index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中是否有对应Key
|
||||||
|
function table.hasKey(t, k)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for key, value in pairs(t) do
|
||||||
|
if k == key then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---按Key删除表中元素
|
||||||
|
function table.removeKey(t, k)
|
||||||
|
if t == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local v = t[k]
|
||||||
|
t[k] = nil
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中是否有对应的Value
|
||||||
|
function table.hasValue(t, value)
|
||||||
|
if t == nil then return false end
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if v == value then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---按Value删除表中元素
|
||||||
|
function table.removeValue(t, value, removeAll)
|
||||||
|
local deleteNum = 0
|
||||||
|
local i = 1
|
||||||
|
local max = table.getCount(t)
|
||||||
|
|
||||||
|
while i <= max do
|
||||||
|
if t[i] == value then
|
||||||
|
table.remove(t,i)
|
||||||
|
deleteNum = deleteNum + 1
|
||||||
|
i = i - 1
|
||||||
|
max = max - 1
|
||||||
|
if not removeAll then break end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
return deleteNum
|
||||||
|
end
|
||||||
|
|
||||||
|
---返回是否是空表
|
||||||
|
function table.isEmpty(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return next(t) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function table.Rand(t)
|
||||||
|
if type(t) ~= "table" or #t <= 0 then return nil end
|
||||||
|
return t[math.random(1, #t)]
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.GetMaxValueResKey(t, fun)
|
||||||
|
if fun == nil then fun = function(p1, p2) return p1 < p2 end end
|
||||||
|
if type(t) ~= "table" or type(fun) ~= "function" or table.getCount(t) <= 0 then return end
|
||||||
|
local res = nil
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if not res or fun(t[res], v) then
|
||||||
|
res = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.FindKey(t, value)
|
||||||
|
if type(t) ~= "table" then return nil end
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if v == value then return k end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.GetMaxValue(t)
|
||||||
|
if type(t) ~= "table" then return nil end
|
||||||
|
local Res = nil
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if Res == nil then Res = v
|
||||||
|
elseif Res < v then Res = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function table.Swap(t, i, k)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local temp = t[i]
|
||||||
|
t[i] = t[k]
|
||||||
|
t[k] = temp
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 打乱整个table 洗牌算法
|
||||||
|
function table.Shuffle(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for i = 1, #t - 1 do
|
||||||
|
local SwapIndex = math.random(i + 1, #t)
|
||||||
|
table.Swap(t, i, SwapIndex)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 判断table相等
|
||||||
|
function table.tablesEqual(table1, table2)
|
||||||
|
-- 检查table1和table2是否为同一个table
|
||||||
|
if table1 == table2 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 检查table类型
|
||||||
|
if type(table1) ~= 'table' or type(table2) ~= 'table' then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 检查table1中的键值对是否在table2中
|
||||||
|
for key, value in pairs(table1) do
|
||||||
|
if type(value) == 'table' then
|
||||||
|
if not tablesEqual(value, table2[key]) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if table2[key] ~= value then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 检查table2中是否有table1中没有的键
|
||||||
|
for key in pairs(table2) do
|
||||||
|
if table1[key] == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 判断table集合相等
|
||||||
|
function table.collectionsEqual(collection1, collection2)
|
||||||
|
local count1 = 0
|
||||||
|
local count2 = 0
|
||||||
|
|
||||||
|
-- 计算第一个集合的大小
|
||||||
|
for _ in pairs(collection1) do
|
||||||
|
count1 = count1 + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 计算第二个集合的大小
|
||||||
|
for _ in pairs(collection2) do
|
||||||
|
count2 = count2 + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 如果大小不同,则集合不同
|
||||||
|
if count1 ~= count2 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 检查collection1中的每个元素是否也在collection2中
|
||||||
|
for key1, value1 in pairs(collection1) do
|
||||||
|
local found = false
|
||||||
|
for key2, value2 in pairs(collection2) do
|
||||||
|
if value1 == value2 then
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not found then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
451
FX_Preview/Script/Global/FunctionExtension/TableHelper.lua
Normal file
451
FX_Preview/Script/Global/FunctionExtension/TableHelper.lua
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
TableHelper = TableHelper or {}
|
||||||
|
|
||||||
|
---@param obj table
|
||||||
|
---@return table
|
||||||
|
function TableHelper.DeepCopy(obj)
|
||||||
|
if obj == nil then
|
||||||
|
return {};
|
||||||
|
end
|
||||||
|
|
||||||
|
local InTable = {};
|
||||||
|
local function Func(obj)
|
||||||
|
if type(obj) ~= "table" then --判断表中是否有表
|
||||||
|
return obj;
|
||||||
|
end
|
||||||
|
local NewTable = {}; --定义一个新表
|
||||||
|
InTable[obj] = NewTable; --若表中有表,则先把表给InTable,再用NewTable去接收内嵌的表
|
||||||
|
for k,v in pairs(obj) do --把旧表的key和Value赋给新表
|
||||||
|
NewTable[Func(k)] = Func(v);
|
||||||
|
end
|
||||||
|
return setmetatable(NewTable, getmetatable(obj))--赋值元表
|
||||||
|
end
|
||||||
|
return Func(obj) --若表中有表,则把内嵌的表也复制了
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param InSelf table
|
||||||
|
---@param InTable table
|
||||||
|
function TableHelper.CopyToTable(InSelf, InTable)
|
||||||
|
if InSelf == nil or InTable == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, v in pairs(InTable) do
|
||||||
|
if type(v) == 'table' then
|
||||||
|
TableHelper.CopyToTable(InSelf[i], v);
|
||||||
|
else
|
||||||
|
InSelf[i] = v;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param Tab table
|
||||||
|
---@return table
|
||||||
|
function TableHelper.CopyTable(Tab)
|
||||||
|
local NewTab = {}
|
||||||
|
for k, v in pairs(Tab) do
|
||||||
|
NewTab[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
return NewTab
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param TableData table
|
||||||
|
---@return table
|
||||||
|
function TableHelper.DeepCopyTable(TableData)
|
||||||
|
if TableData == nil then
|
||||||
|
UGCLogSystem.LogError("表格为空,不能复制");
|
||||||
|
return {};
|
||||||
|
end
|
||||||
|
|
||||||
|
local TmpTab = {};
|
||||||
|
for k, v in pairs(TableData) do
|
||||||
|
if type(v) == "table" then
|
||||||
|
local SubTab = TableHelper.DeepCopyTable(v);
|
||||||
|
TmpTab[k] = SubTab;
|
||||||
|
-- elseif type(v) == "userdata" then
|
||||||
|
-- TmpTab[k] = v:Copy();
|
||||||
|
else
|
||||||
|
TmpTab[k] = v;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TmpTab;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 返回值的下标,没有返回-1
|
||||||
|
---@param tab table
|
||||||
|
---@param val any
|
||||||
|
---@return bool, int32
|
||||||
|
function TableHelper.GetValueIndex(tab, val)
|
||||||
|
for k, v in pairs(tab) do
|
||||||
|
if v == val then
|
||||||
|
return true, k;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false, -1;
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param tab table
|
||||||
|
---@param val any
|
||||||
|
function TableHelper.RemoveByValue(tab, val)
|
||||||
|
for i, Val in pairs(tab) do
|
||||||
|
if Val == val then
|
||||||
|
table.remove(tab, i);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableHelper.Contains(tab, val)
|
||||||
|
for i, Val in pairs(tab) do
|
||||||
|
if Val == val then
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableHelper.GetName(Actor)
|
||||||
|
if UE.IsValid(Actor) then
|
||||||
|
return UE.GetPathName(Actor);
|
||||||
|
elseif Actor ~= nil then
|
||||||
|
return type(Actor)
|
||||||
|
end
|
||||||
|
|
||||||
|
return "[NullActor]";
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableHelper.Length(InTable)
|
||||||
|
if InTable == nil then
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
local Count = 0
|
||||||
|
for _ in pairs(InTable) do
|
||||||
|
Count = Count + 1;
|
||||||
|
end
|
||||||
|
return Count;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableHelper.AppendToTable(OriginalTable, NewTable)
|
||||||
|
if OriginalTable == nil or NewTable == nil then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(NewTable) do
|
||||||
|
table.insert(OriginalTable, v);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TableHelper.ArrayToLuaTable(Array)
|
||||||
|
local Tab = {};
|
||||||
|
for k, v in pairs(Array) do
|
||||||
|
Tab[k] = v;
|
||||||
|
end
|
||||||
|
|
||||||
|
return Tab;
|
||||||
|
end
|
||||||
|
|
||||||
|
function class(classname, super)
|
||||||
|
local superType = type(super)
|
||||||
|
local cls
|
||||||
|
|
||||||
|
if superType ~= "function" and superType ~= "table" then
|
||||||
|
superType = nil
|
||||||
|
super = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if superType == "function" or (super and super.__ctype == 1) then
|
||||||
|
-- inherited from native C++ Object
|
||||||
|
cls = {}
|
||||||
|
|
||||||
|
if superType == "table" then
|
||||||
|
-- copy fields from super
|
||||||
|
for k, v in pairs(super) do
|
||||||
|
cls[k] = v
|
||||||
|
end
|
||||||
|
cls.__create = super.__create
|
||||||
|
cls.super = super
|
||||||
|
else
|
||||||
|
cls.__create = super
|
||||||
|
cls.Ctor = function()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
cls.__cname = classname
|
||||||
|
cls.__ctype = 1
|
||||||
|
|
||||||
|
function cls.New(...)
|
||||||
|
local instance = cls.__create(...)
|
||||||
|
-- copy fields from class to native object
|
||||||
|
for k, v in pairs(cls) do
|
||||||
|
instance[k] = v
|
||||||
|
end
|
||||||
|
instance.class = cls
|
||||||
|
instance:Ctor(...)
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
-- inherited from Lua Object
|
||||||
|
if super then
|
||||||
|
cls = {}
|
||||||
|
setmetatable(cls, {
|
||||||
|
__index = super
|
||||||
|
})
|
||||||
|
cls.super = super
|
||||||
|
else
|
||||||
|
cls = {
|
||||||
|
Ctor = function()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
cls.__cname = classname
|
||||||
|
cls.__ctype = 2 -- lua
|
||||||
|
cls.__index = cls
|
||||||
|
|
||||||
|
function cls.New(...)
|
||||||
|
local instance = setmetatable({}, cls)
|
||||||
|
instance.class = cls
|
||||||
|
instance:Ctor(...)
|
||||||
|
return instance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return cls
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 拷贝table
|
||||||
|
function table.DeepCopy(object)
|
||||||
|
-- 已经复制过的table,key为复制源table,value为复制后的table
|
||||||
|
-- 为了防止table中的某个属性为自身时出现死循环
|
||||||
|
-- 避免本该是同一个table的属性,在复制时变成2个不同的table(内容同,但是地址关系和原来的不一样了)
|
||||||
|
local lookup_table = {}
|
||||||
|
local function _copy(object)
|
||||||
|
if type(object) ~= 'table' then -- 非table类型都直接返回
|
||||||
|
return object
|
||||||
|
elseif lookup_table[object] then
|
||||||
|
return lookup_table[object]
|
||||||
|
end
|
||||||
|
local new_table = {}
|
||||||
|
lookup_table[object] = new_table
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
new_table[_copy(k)] = _copy(v)
|
||||||
|
end
|
||||||
|
-- 这里直接拿mt来用是因为一般对table操作不会很粗暴的修改mt的相关内容
|
||||||
|
return setmetatable(new_table, getmetatable(object))
|
||||||
|
end
|
||||||
|
return _copy(object)
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表元素个数
|
||||||
|
function table.getCount(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
local Length = 0
|
||||||
|
for i, v in pairs(t) do
|
||||||
|
Length = Length + 1
|
||||||
|
end
|
||||||
|
return Length
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中所有的Key
|
||||||
|
function table.getKeys(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
local keys = {}
|
||||||
|
for k,v in pairs(t) do
|
||||||
|
keys[#keys + 1] = k
|
||||||
|
end
|
||||||
|
return keys
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取对应元素的Index
|
||||||
|
function table.getIndex(t, v)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
for index, value in pairs(t) do
|
||||||
|
if value == v then
|
||||||
|
return index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中是否有对应Key
|
||||||
|
function table.hasKey(t, k)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for key, value in pairs(t) do
|
||||||
|
if k == key then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---按Key删除表中元素
|
||||||
|
function table.removeKey(t, k)
|
||||||
|
if t == nil then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local v = t[k]
|
||||||
|
t[k] = nil
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
|
||||||
|
---获取表中是否有对应的Value
|
||||||
|
function table.hasValue(t, value)
|
||||||
|
if t == nil then return false end
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if v == value then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
---按Value删除表中元素
|
||||||
|
function table.removeValue(t, value, removeAll)
|
||||||
|
local deleteNum = 0
|
||||||
|
local i = 1
|
||||||
|
local max = table.getCount(t)
|
||||||
|
|
||||||
|
while i <= max do
|
||||||
|
if t[i] == value then
|
||||||
|
table.remove(t,i)
|
||||||
|
deleteNum = deleteNum + 1
|
||||||
|
i = i - 1
|
||||||
|
max = max - 1
|
||||||
|
if not removeAll then break end
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
return deleteNum
|
||||||
|
end
|
||||||
|
|
||||||
|
---返回是否是空表
|
||||||
|
function table.isEmpty(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return next(t) == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function table.Rand(t)
|
||||||
|
if type(t) ~= "table" or #t <= 0 then return nil end
|
||||||
|
return t[math.random(1, #t)]
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.GetMaxValueResKey(t, fun)
|
||||||
|
if fun == nil then fun = function(p1, p2) return p1 < p2 end end
|
||||||
|
if type(t) ~= "table" or type(fun) ~= "function" or table.getCount(t) <= 0 then return end
|
||||||
|
local res = nil
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if not res or fun(t[res], v) then
|
||||||
|
res = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.FindKey(t, value)
|
||||||
|
if type(t) ~= "table" then return nil end
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if v == value then return k end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.GetMaxValue(t)
|
||||||
|
if type(t) ~= "table" then return nil end
|
||||||
|
local Res = nil
|
||||||
|
for k, v in pairs(t) do
|
||||||
|
if Res == nil then Res = v
|
||||||
|
elseif Res < v then Res = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function table.Swap(t, i, k)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local temp = t[i]
|
||||||
|
t[i] = t[k]
|
||||||
|
t[k] = temp
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 打乱整个table 洗牌算法
|
||||||
|
function table.Shuffle(t)
|
||||||
|
if type(t) ~= "table" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for i = 1, #t - 1 do
|
||||||
|
local SwapIndex = math.random(i + 1, #t)
|
||||||
|
table.Swap(t, i, SwapIndex)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.addTableNum(t, k, v)
|
||||||
|
if t[k] == nil then
|
||||||
|
t[k] = v
|
||||||
|
else
|
||||||
|
t[k] = t[k] + v
|
||||||
|
end
|
||||||
|
return t[k]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------------------------table print---------------------------------------------------------
|
||||||
|
-- log输出格式化
|
||||||
|
local function logPrint(str)
|
||||||
|
str = os.date("\nLog output date: %Y-%m-%d %H:%M:%S \n", os.time()) .. str
|
||||||
|
print(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- key值格式化
|
||||||
|
local function formatKey(key)
|
||||||
|
local t = type(key)
|
||||||
|
if t == "number" then
|
||||||
|
return "[" .. key .. "]"
|
||||||
|
elseif t == "string" then
|
||||||
|
local n = tonumber(key)
|
||||||
|
if n then
|
||||||
|
return "[" .. key .. "]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return key
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return TableHelper;
|
179
FX_Preview/Script/Global/FunctionExtension/VectorHelper.lua
Normal file
179
FX_Preview/Script/Global/FunctionExtension/VectorHelper.lua
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
VectorHelper = {}
|
||||||
|
|
||||||
|
function VectorHelper.Dot(v1, v2)
|
||||||
|
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Mul(v1, v2)
|
||||||
|
return Vector.New(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.MulScalar(v1, S)
|
||||||
|
return Vector.New(v1.X * S, v1.Y * S, v1.Z * S)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.MulScalar2D(v1, S)
|
||||||
|
return Vector.New(v1.X * S, v1.Y * S, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.MulNumber(v1, number)
|
||||||
|
return Vector.New(v1.X * number, v1.Y * number, v1.Z * number)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.MulNumber2D(v1, number)
|
||||||
|
return Vector.New(v1.X * number, v1.Y * number, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Sub(v1, v2)
|
||||||
|
return Vector.New(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Sub2D(v1, v2)
|
||||||
|
return Vector.New(v1.X - v2.X, v1.Y - v2.Y, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Add(v1, v2)
|
||||||
|
return Vector.New(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Add2D(v1, v2)
|
||||||
|
return Vector.New(v1.X + v2.X, v1.Y + v2.Y, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Div2DScalar(v1, s)
|
||||||
|
return Vector.New(v1.X / s , v1.Y / s, 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function VectorHelper.ToString(v)
|
||||||
|
return string.format("(%.2f,%.2f,%.2f)", v.X, v.Y, v.Z)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.RotToString(v)
|
||||||
|
return string.format("(Roll = %.2f, Pitch = %.2f, Yaw = %.2f)", v.Roll, v.Pitch, v.Yaw)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ToStringInt2D(v)
|
||||||
|
if v == nil then
|
||||||
|
return "[X=Nil,Y=Nil]";
|
||||||
|
end
|
||||||
|
return string.format("[%d, %d]", v.X, v.Y);
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ToIntString(v)
|
||||||
|
return "(" .. tostring(math.floor(v.X)) .. "," .. tostring( math.floor(v.Y)) .. "," .. tostring(math.floor(v.Z)) .. ")";
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Cross(v1, v2)
|
||||||
|
return Vector.New(v1.Y * v2.Z - v2.Y * v1.Z,
|
||||||
|
v1.Z * v2.X - v2.Z * v1.X,
|
||||||
|
v1.X * v2.Y - v2.X * v1.Y)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.GetDistance(vector1, vector2)
|
||||||
|
if vector1 == nil or vector2 == nil then return 0 end
|
||||||
|
if vector1.X == nil or vector2.X == nil then return 0 end
|
||||||
|
if vector1.Y == nil or vector2.Y == nil then return 0 end
|
||||||
|
if vector1.Z == nil or vector2.Z == nil then return 0 end
|
||||||
|
local disX = vector1.X - vector2.X
|
||||||
|
local disY = vector1.Y - vector2.Y
|
||||||
|
local disZ = vector1.Z - vector2.Z
|
||||||
|
return math.sqrt(disX ^ 2 + disY ^ 2 + disZ ^ 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.GetDistance2D(vector1, vector2)
|
||||||
|
if vector1 == nil or vector2 == nil then return 0 end
|
||||||
|
if vector1.X == nil or vector2.X == nil then return 0 end
|
||||||
|
if vector1.Y == nil or vector2.Y == nil then return 0 end
|
||||||
|
local disX = vector1.X - vector2.X
|
||||||
|
local disY = vector1.Y - vector2.Y
|
||||||
|
return math.sqrt(disX ^ 2 + disY ^ 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.LengthSquared(v)
|
||||||
|
return v.X ^ 2 + v.Y ^ 2 + v.Z ^ 2
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.LengthSquared2D(v)
|
||||||
|
return v.X ^ 2 + v.Y ^ 2
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Length(v)
|
||||||
|
return math.sqrt(VectorHelper.LengthSquared(v))
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.Length2D(v)
|
||||||
|
return math.sqrt(VectorHelper.LengthSquared2D(v))
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ToLuaTable(v)
|
||||||
|
return {X = v.X, Y = v.Y, Z = v.Z}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ToLuaTable2D(v)
|
||||||
|
return {X = v.X, Y = v.Y, Z = 0}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.RotToLuaTable(v)
|
||||||
|
return {Roll=v.Roll, Pitch=v.Pitch, Yaw=v.Yaw}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ColorToVector(LinearColor)
|
||||||
|
return {X = LinearColor.R, Y = LinearColor.G, Z = LinearColor.B }
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.RotToString(v)
|
||||||
|
return string.format("Roll=%.2f, Pitch=%.2f, Yaw=%.2f", v.Roll, v.Pitch, v.Yaw);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function VectorHelper.GetMiddlePoint(vector1, vector2)
|
||||||
|
return {X = (vector1.X + vector2.X) / 2, Y = (vector1.Y + vector2.Y) / 2,Z = (vector1.Z + vector2.Z) / 2}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function VectorHelper.FromCpp(CppVector)
|
||||||
|
return {X = CppVector.X, Y = CppVector.Y, Z = CppVector.Z};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function VectorHelper.Equal(vector1, vector2)
|
||||||
|
return (vector1.X == vector2.X and vector1.Y == vector2.Y and vector1.Z == vector2.Z);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--计算两点之间连线与Y轴的夹角
|
||||||
|
function VectorHelper.GetAngleByPos(PosA,PosB)
|
||||||
|
local P = {};
|
||||||
|
P.X = PosB.X - PosA.X;
|
||||||
|
P.Y = PosB.Y - PosA.Y;
|
||||||
|
local Pi = 3.1415926;
|
||||||
|
local Dis = math.sqrt( (P.X * P.X) + (P.Y * P.Y));
|
||||||
|
local FAngle = math.acos (P.Y/ Dis);
|
||||||
|
if( P.X < 0) then
|
||||||
|
FAngle = 2 * Pi - FAngle;
|
||||||
|
end
|
||||||
|
local Angle = FAngle * 180 / Pi;
|
||||||
|
Angle = Angle > 0 and (90 - Angle) or (90 + math.abs(Angle));
|
||||||
|
return Angle;
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.RotZero()
|
||||||
|
return {Roll = 0, Pitch = 0, Yaw = 0}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.VectorZero()
|
||||||
|
return {X = 0, Y = 0, Z = 0}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.ScaleOne()
|
||||||
|
return {X = 1, Y = 1, Z = 1}
|
||||||
|
end
|
||||||
|
|
||||||
|
function VectorHelper.CosineValue(v1, v2)
|
||||||
|
return VectorHelper.Dot(v1, v2) / (VectorHelper.Length(v1) * VectorHelper.Length(v2))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return VectorHelper;
|
9
FX_Preview/Script/Global/Global.lua
Normal file
9
FX_Preview/Script/Global/Global.lua
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
require('Script.Global.EventConfig')
|
||||||
|
|
||||||
|
--- 函数拓展
|
||||||
|
require('Script.Global.FunctionExtension.A_IncludeFunctionExtension')
|
||||||
|
--- 各系统功能文件 依赖函数拓展、事件系统、函数拓展
|
||||||
|
require('Script.Global.System.A_IncludeSystem')
|
||||||
|
|
||||||
|
|
16
FX_Preview/Script/Global/System/A_IncludeSystem.lua
Normal file
16
FX_Preview/Script/Global/System/A_IncludeSystem.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
-- 需要包含的头目录
|
||||||
|
|
||||||
|
local Prefix = "Script.Global.System."
|
||||||
|
|
||||||
|
-- 工具集
|
||||||
|
require(Prefix .. 'UGCSystemLibrary')
|
||||||
|
require(Prefix .. 'LevelStreamUtil')
|
||||||
|
require(Prefix .. 'SoundSystem')
|
||||||
|
require(Prefix .. 'UGCDelegate')
|
||||||
|
require(Prefix .. 'UGCDelegateMulticast')
|
||||||
|
require(Prefix .. 'UGCEventSystem')
|
||||||
|
require(Prefix .. 'UGCLogSystem')
|
||||||
|
require(Prefix .. 'UGCSendRPCSystem')
|
||||||
|
require(Prefix .. 'PlayerScoreSystem')
|
||||||
|
require(Prefix .. 'MyVehicleSystem')
|
||||||
|
require(Prefix .. 'MyWeaponSystem')
|
143
FX_Preview/Script/Global/System/LevelStreamUtil.lua
Normal file
143
FX_Preview/Script/Global/System/LevelStreamUtil.lua
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
--require("Script.Common.UGCLog");
|
||||||
|
--require("Script.Common.TableHelper");
|
||||||
|
|
||||||
|
LevelStreamUtil = LevelStreamUtil or
|
||||||
|
{
|
||||||
|
LevelLoadCounter = 0;
|
||||||
|
LoadDelegate = nil;
|
||||||
|
LoadCompletedCallback = nil;
|
||||||
|
IsAsyncLoad = false;
|
||||||
|
|
||||||
|
LevelUnloadCounter = 0;
|
||||||
|
UnLoadDelegate = nil;
|
||||||
|
UnloadCompletedCallback = nil;
|
||||||
|
IsAsyncUnload = false;
|
||||||
|
|
||||||
|
LoadedLevels = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
---@class CallbackStruct
|
||||||
|
---@field Object Object
|
||||||
|
---@field Func fun()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---@param LevelNameList string[]字符串关卡名列表
|
||||||
|
---@param CompletedCallback CallbackStruct 加载完成时的回调函静态函数
|
||||||
|
---@param bShouldBlockOnLoad bool 是否等待处理完成
|
||||||
|
--- LoadStreamLevel fun(WorldContextObject:UObject,LevelName:FName,bMakeVisibleAfterLoad:bool,bShouldBlockOnLoad:bool,LatentInfo:FLatentActionInfo)
|
||||||
|
function LevelStreamUtil.LoadStreamLevels(LevelNameList, CompletedCallback, bShouldBlockOnLoad)
|
||||||
|
|
||||||
|
--UGCLogSystem.Log("[Level] 加载关卡数量:%d CompletedCallback:%s", LevelNameList:Num(), UE.ToTable(CompletedCallback));
|
||||||
|
|
||||||
|
LevelStreamUtil.LevelLoadCounter = LevelStreamUtil.LevelLoadCounter + #LevelNameList;
|
||||||
|
LevelStreamUtil.LoadCompletedCallback = CompletedCallback;
|
||||||
|
LevelStreamUtil.IsAsyncLoad = not bShouldBlockOnLoad;
|
||||||
|
|
||||||
|
--UGCLogSystem.Log("[Level] 加载关卡 LoadCompletedCallback:%s", UE.ToTable(LevelStreamUtil.LoadCompletedCallback));
|
||||||
|
|
||||||
|
for k, v in pairs(LevelNameList) do
|
||||||
|
UGCLogSystem.Log("[Level] 加载关卡:%s", v);
|
||||||
|
table.insert(LevelStreamUtil.LoadedLevels, v);
|
||||||
|
|
||||||
|
LevelStreamUtil.LoadDelegate = ObjectExtend.CreateDelegate(UGCGameSystem.GameState, LevelStreamUtil.OnLoadCompleted, LevelStreamUtil);
|
||||||
|
|
||||||
|
GameplayStatics.LoadStreamLevel(UGCGameSystem.GameState, v, true, bShouldBlockOnLoad,
|
||||||
|
ObjectExtend.CreateLatentAction(LevelStreamUtil.LoadDelegate));
|
||||||
|
|
||||||
|
-- 强制加载完成
|
||||||
|
if bShouldBlockOnLoad then
|
||||||
|
GameplayStatics.FlushLevelStreaming(UGCGameSystem.GameState);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if bShouldBlockOnLoad then
|
||||||
|
UGCLogSystem.Log("[Level] 完成同步加载关卡");
|
||||||
|
-- LevelStreamUtil.LoadCompletedCallback();
|
||||||
|
LevelStreamUtil.LoadCompletedCallback.Func(LevelStreamUtil.LoadCompletedCallback.Object);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 加载结束异步回调
|
||||||
|
function LevelStreamUtil:OnLoadCompleted()
|
||||||
|
if not LevelStreamUtil.IsAsyncLoad then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
LevelStreamUtil.LevelLoadCounter = LevelStreamUtil.LevelLoadCounter - 1;
|
||||||
|
UGCLogSystem.Log("[Level] 加载关卡完成 剩余等待计数:[%d]", LevelStreamUtil.LevelLoadCounter);
|
||||||
|
|
||||||
|
if LevelStreamUtil.LevelLoadCounter == 0 then
|
||||||
|
ObjectExtend.DestroyDelegate(LevelStreamUtil.LoadDelegate);
|
||||||
|
LevelStreamUtil.LoadDelegate = nil;
|
||||||
|
|
||||||
|
UGCLogSystem.Log("[Level] 加载关卡完成 LoadCompletedCallback:%s", UE.ToTable(LevelStreamUtil.LoadCompletedCallback));
|
||||||
|
if LevelStreamUtil.LoadCompletedCallback ~= nil then
|
||||||
|
UGCLogSystem.Log("[Level] 完成异步加载关卡");
|
||||||
|
-- LevelStreamUtil.CompletedCallback();
|
||||||
|
|
||||||
|
-- 必须缓存用,不然会被加载子关卡的调用冲掉
|
||||||
|
local Callback = LevelStreamUtil.LoadCompletedCallback;
|
||||||
|
LevelStreamUtil.LoadCompletedCallback = nil;
|
||||||
|
Callback.Func(Callback.Object);
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 根据传入的列表销毁相应的关卡
|
||||||
|
---@param LevelNameList string[]字符串关卡名列表
|
||||||
|
---@param UnloadCompletedCallback CallbackStruct 销毁完成时的回调函静态函数
|
||||||
|
---@param bShouldBlockOnLoad bool 是否等待处理完成
|
||||||
|
---UnloadStreamLevel fun(WorldContextObject:UObject,LevelName:FName,LatentInfo:FLatentActionInfo)
|
||||||
|
function LevelStreamUtil.UnLoadStreamLevels(LevelNameList, UnloadCompletedCallback, bShouldBlockOnLoad)
|
||||||
|
|
||||||
|
LevelStreamUtil.UnloadCompletedCallback = UnloadCompletedCallback;
|
||||||
|
LevelStreamUtil.LevelUnloadCounter = LevelStreamUtil.LevelUnloadCounter + #LevelNameList;
|
||||||
|
LevelStreamUtil.IsAsyncUnload = not bShouldBlockOnLoad;
|
||||||
|
|
||||||
|
for k, v in pairs(LevelNameList) do
|
||||||
|
UGCLogSystem.Log("[Level] 销毁关卡:%s", v);
|
||||||
|
|
||||||
|
-- TableHelper.RemoveByValue(LevelStreamUtil.LoadedLevels, v);
|
||||||
|
table.removeValue(LevelStreamUtil.LoadedLevels, v, true)
|
||||||
|
|
||||||
|
LevelStreamUtil.UnLoadDelegate = ObjectExtend.CreateDelegate(UGCGameSystem.GameState, LevelStreamUtil.UnLoadCompleted, LevelStreamUtil);
|
||||||
|
GameplayStatics.UnloadStreamLevel(UGCGameSystem.GameState, v,
|
||||||
|
ObjectExtend.CreateLatentAction(LevelStreamUtil.UnLoadDelegate));
|
||||||
|
|
||||||
|
-- 强制销毁完成
|
||||||
|
if bShouldBlockOnLoad then
|
||||||
|
GameplayStatics.FlushLevelStreaming(UGCGameSystem.GameState);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if bShouldBlockOnLoad then
|
||||||
|
UGCLogSystem.Log("[Level] 完成同步销毁关卡");
|
||||||
|
LevelStreamUtil.UnloadCompletedCallback.Func(LevelStreamUtil.UnloadCompletedCallback.Object);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 销毁结束异步回调
|
||||||
|
function LevelStreamUtil:UnLoadCompleted()
|
||||||
|
if not LevelStreamUtil.IsAsyncUnload then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
UGCLogSystem.Log("[Level] 销毁关卡完成[%d]", LevelStreamUtil.LevelUnloadCounter);
|
||||||
|
LevelStreamUtil.LevelUnloadCounter = LevelStreamUtil.LevelUnloadCounter - 1;
|
||||||
|
|
||||||
|
if LevelStreamUtil.LevelUnloadCounter == 0 then
|
||||||
|
ObjectExtend.DestroyDelegate(LevelStreamUtil.UnLoadDelegate);
|
||||||
|
LevelStreamUtil.UnLoadDelegate = nil;
|
||||||
|
|
||||||
|
if LevelStreamUtil.UnloadCompletedCallback ~= nil then
|
||||||
|
UGCLogSystem.Log("[Level] 完成异步销毁关卡");
|
||||||
|
-- LevelStreamUtil.UnloadCompletedCallback();
|
||||||
|
LevelStreamUtil.UnloadCompletedCallback.Func(LevelStreamUtil.UnloadCompletedCallback.Object);
|
||||||
|
LevelStreamUtil.UnloadCompletedCallback = nil;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
59
FX_Preview/Script/Global/System/MyVehicleSystem.lua
Normal file
59
FX_Preview/Script/Global/System/MyVehicleSystem.lua
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||||
|
--- Created by LT.
|
||||||
|
--- DateTime: 2024/8/23 17:10
|
||||||
|
---
|
||||||
|
MyVehicleSystem = MyVehicleSystem or {}
|
||||||
|
MyVehicleSystem.VehicleClassName = "STExtraWheeledVehicle"
|
||||||
|
MyVehicleSystem.SpawnVehiclePointPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/SceneActor/BP_VehicleSpawnPoint.BP_VehicleSpawnPoint_C')
|
||||||
|
|
||||||
|
function MyVehicleSystem.GetVehicleBaseClass()
|
||||||
|
if MyVehicleSystem.VehicleBaseClass == nil then
|
||||||
|
MyVehicleSystem.VehicleBaseClass = ScriptGameplayStatics.FindClass(MyVehicleSystem.VehicleClassName)
|
||||||
|
end
|
||||||
|
return MyVehicleSystem.VehicleBaseClass
|
||||||
|
end
|
||||||
|
|
||||||
|
function MyVehicleSystem.GetSpawnVehiclePointClass()
|
||||||
|
if MyVehicleSystem.VehicleBaseClass == nil then
|
||||||
|
MyVehicleSystem.VehicleBaseClass = UE.LoadClass(MyVehicleSystem.SpawnVehiclePointPath)
|
||||||
|
end
|
||||||
|
return MyVehicleSystem.VehicleBaseClass
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 保存当前场景中载具的信息
|
||||||
|
function MyVehicleSystem.SaveAllVehicleTF(MapIndex)
|
||||||
|
MyVehicleSystem.AllVehicleTF = {}
|
||||||
|
--local AllVehicles = {}
|
||||||
|
--AllVehicles = ScriptGameplayStatics.GetActorsOfClass(UGCGameSystem.GameState, MyVehicleSystem.GetVehicleBaseClass(), {})
|
||||||
|
--for i, VehicleInst in pairs(AllVehicles) do
|
||||||
|
-- MyVehicleSystem.AllVehicleTF[#MyVehicleSystem.AllVehicleTF + 1] = {VehicleID = VehicleInst.VehicleConfigID, Pos = VehicleInst:K2_GetActorLocation(), Rot = VehicleInst:K2_GetActorRotation(), Inst = VehicleInst}
|
||||||
|
--end
|
||||||
|
--UGCLogSystem.LogTree("[MyVehicleSystem_SaveAllVehicleTF]", MyVehicleSystem.AllVehicleTF)
|
||||||
|
MyVehicleSystem.AllVehicleTF = {}
|
||||||
|
local AllVehicleSpawnPoints = ScriptGameplayStatics.GetActorsOfClass(UGCGameSystem.GameState, MyVehicleSystem.GetSpawnVehiclePointClass(), {})
|
||||||
|
for i, v in pairs(AllVehicleSpawnPoints) do
|
||||||
|
UGCLogSystem.Log("[MyVehicleSystem_SaveAllVehicleTF] VehiclePath:%s", v.VehiclePath)
|
||||||
|
if MapIndex == nil or MapIndex == v.MapIndex then
|
||||||
|
MyVehicleSystem.AllVehicleTF[#MyVehicleSystem.AllVehicleTF + 1] = {VehiclePath = v.VehiclePath, Pos = v:K2_GetActorLocation(), Rot = v:K2_GetActorRotation(), Inst = nil}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
UGCLogSystem.LogTree("[MyVehicleSystem_SaveAllVehicleTF]", MyVehicleSystem.AllVehicleTF)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 移除场景中的载具
|
||||||
|
function MyVehicleSystem.DestroyAllSavedVehicle()
|
||||||
|
for i, v in pairs(MyVehicleSystem.AllVehicleTF) do
|
||||||
|
if UE.IsValid(v.Inst) then
|
||||||
|
UGCVehicleSystem.DestroySelf(v.Inst)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 重置当前场景中的载具,需要先调移除
|
||||||
|
function MyVehicleSystem.ResetAllSavedVehicle()
|
||||||
|
for i, v in pairs(MyVehicleSystem.AllVehicleTF) do
|
||||||
|
MyVehicleSystem.AllVehicleTF[i].Inst = UGCVehicleSystem.SpawnVehicleNew(v.VehiclePath, v.Pos, v.Rot, true)
|
||||||
|
UGCLogSystem.Log("[MyVehicleSystem_ResetAllSavedVehicle] Inst:%s", tostring(MyVehicleSystem.AllVehicleTF[i].Inst))
|
||||||
|
end
|
||||||
|
end
|
216
FX_Preview/Script/Global/System/MyWeaponSystem.lua
Normal file
216
FX_Preview/Script/Global/System/MyWeaponSystem.lua
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
--[[
|
||||||
|
---@field ItemID int32
|
||||||
|
---@field ItemName FString
|
||||||
|
---@field ItemType int32
|
||||||
|
---@field ItemSubType int32
|
||||||
|
---@field BPID int32
|
||||||
|
---@field Durability int32
|
||||||
|
---@field Electricity int32
|
||||||
|
---@field AIFullVaule int32
|
||||||
|
---@field Equippable bool
|
||||||
|
---@field Consumable bool
|
||||||
|
---@field AutoEquipAndDrop bool
|
||||||
|
---@field MaxCount int32
|
||||||
|
---@field WeightforOrder int32
|
||||||
|
---@field WeightforOrder2 int32
|
||||||
|
---@field UnitWeight_f float
|
||||||
|
---@field ItemBigIcon_n FName
|
||||||
|
---@field ItemSmallIcon_n FName
|
||||||
|
---@field ItemWhiteIcon_n FName
|
||||||
|
---@field ArmorySimpleDesc FString
|
||||||
|
---@field BackpackSimple FString
|
||||||
|
---@field ItemQuality int32
|
||||||
|
---@field PickUpSound FString
|
||||||
|
---@field DropSound FString
|
||||||
|
---@field EquipSound FString
|
||||||
|
---@field UnEquipSound FString
|
||||||
|
---@field PickUpBank FString
|
||||||
|
---@field DropBank FString
|
||||||
|
---@field EquipBank FString
|
||||||
|
---@field UnEquipBank FString
|
||||||
|
---@field KillWhiteIcon FString
|
||||||
|
---@field StTime int32
|
||||||
|
---@field ItemTypeBigWorld int32
|
||||||
|
---@field BigWorldBackpackTab_n FName
|
||||||
|
---@field IsVirtualItem bool
|
||||||
|
---@field Droppable bool
|
||||||
|
---@field HomeBackpackTab_n FName
|
||||||
|
---@field Rarelevel int32
|
||||||
|
---@field RarelevelEffPath FString
|
||||||
|
---@field CustomizedType FString
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
|
MyWeaponSystem = MyWeaponSystem or {}
|
||||||
|
|
||||||
|
|
||||||
|
--- 异步加载Item小图标到Image画刷
|
||||||
|
function MyWeaponSystem.AsyncLoadItemSmallIconToBrush(InItemID, ImageWidget)
|
||||||
|
MyWeaponSystem.AsyncLoadItemIconToBrush(InItemID, ImageWidget, "ItemSmallIcon_n")
|
||||||
|
end
|
||||||
|
--- 异步加载Item大图标到Image画刷
|
||||||
|
function MyWeaponSystem.AsyncLoadItemBigIconToBrush(InItemID, ImageWidget)
|
||||||
|
MyWeaponSystem.AsyncLoadItemIconToBrush(InItemID, ImageWidget, "ItemBigIcon_n")
|
||||||
|
end
|
||||||
|
--- 异步加载Item白色剪影图标到Image画刷
|
||||||
|
function MyWeaponSystem.AsyncLoadItemWhiteIconToBrush(InItemID, ImageWidget)
|
||||||
|
MyWeaponSystem.AsyncLoadItemIconToBrush(InItemID, ImageWidget, "ItemWhiteIcon_n")
|
||||||
|
end
|
||||||
|
--- 异步加载Item图标到Image画刷
|
||||||
|
function MyWeaponSystem.AsyncLoadItemIconToBrush(InItemID, ImageWidget, TexKey)
|
||||||
|
local ItemInfo = UGCItemSystem.GetItemData(InItemID);
|
||||||
|
if ItemInfo then
|
||||||
|
UGCSystemLibrary.AsyncLoadAsset(ItemInfo[TexKey],
|
||||||
|
function(Tex)
|
||||||
|
if UE.IsValid(ImageWidget) then
|
||||||
|
ImageWidget:SetBrushFromTexture(Tex);
|
||||||
|
end
|
||||||
|
end , nil
|
||||||
|
,true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--- 判断Item是否为武器的配件
|
||||||
|
function MyWeaponSystem.IsWeaponPartValid(InId)
|
||||||
|
if InId == nil then
|
||||||
|
return false;
|
||||||
|
end
|
||||||
|
return WeaponParts[InId] ~= nil;
|
||||||
|
end
|
||||||
|
--- 获取Item名
|
||||||
|
function MyWeaponSystem.GetItemName(InItemID)
|
||||||
|
if InItemID == nil then return "" end
|
||||||
|
if InItemID <= 0 then
|
||||||
|
return "拳击"
|
||||||
|
else
|
||||||
|
local ItemInfo = UGCItemSystem.GetItemData(InItemID);
|
||||||
|
if ItemInfo then
|
||||||
|
return ItemInfo.ItemName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
UGCLogSystem.Log("[GetWeaponName]无法找到对应 Weapon ID: " .. InItemID)
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
--- 获取配件Item是否为武器可用Item
|
||||||
|
---@param WeaponID int
|
||||||
|
---@param PartItemID int
|
||||||
|
function MyWeaponSystem.PartIsWeaponCanBeUsed(WeaponID, PartItemID)
|
||||||
|
if WeaponSuits[WeaponID] == nil then
|
||||||
|
UGCLogSystem.LogError("[MyWeaponSystem_PartIsWeaponCanBeUsed]")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
for i, v in pairs(WeaponSuits[WeaponID]) do
|
||||||
|
for _, PartItemIDTemp in pairs(v) do
|
||||||
|
if PartItemIDTemp == PartItemID then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
--- 获取武器最佳配件
|
||||||
|
function MyWeaponSystem.GetWeaponBastParts(InWeaponID)
|
||||||
|
if WeaponTable.RecommendedWeaponParts[InWeaponID] then
|
||||||
|
return WeaponTable.RecommendedWeaponParts[InWeaponID]
|
||||||
|
end
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
--- 获取武器可用配件
|
||||||
|
function MyWeaponSystem.GetWeaponCanUsePartFromPartType(WeaponID, PartType)
|
||||||
|
if WeaponSuits[WeaponID] == nil then return {} end
|
||||||
|
if WeaponSuits[WeaponID][PartType] == nil then return {} end
|
||||||
|
return WeaponSuits[WeaponID][PartType]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 将配件列表转化为配件字典 Key为PartType Value为ItemID
|
||||||
|
function MyWeaponSystem.PartListToPartMap(InPartList)
|
||||||
|
local Res = {}
|
||||||
|
for i, v in pairs(InPartList) do
|
||||||
|
if WeaponParts[v] then
|
||||||
|
Res[WeaponParts[v].Type] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
function MyWeaponSystem.GetPartType(InPartItemID)
|
||||||
|
if WeaponParts[InPartItemID] then
|
||||||
|
return WeaponParts[InPartItemID].Type
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Weapon_LastGetWeaponIDTime = -1.
|
||||||
|
Weapon_LastGetWeaponIDRes = {} -- PlayerKey = {}
|
||||||
|
|
||||||
|
--- 获取配件Item是否为武器可用Item
|
||||||
|
---@param PlayerKey uint
|
||||||
|
function MyWeaponSystem.GetPlayerShootWeaponIDs(PlayerKey)
|
||||||
|
local NowTime = KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
|
||||||
|
if Weapon_LastGetWeaponIDTime == NowTime then
|
||||||
|
if Weapon_LastGetWeaponIDRes[PlayerKey] then
|
||||||
|
return Weapon_LastGetWeaponIDRes[PlayerKey]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Weapon_LastGetWeaponIDTime = NowTime
|
||||||
|
Weapon_LastGetWeaponIDRes = {}
|
||||||
|
end
|
||||||
|
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
local Res = {}
|
||||||
|
if UE.IsValid(TargetPawn) then
|
||||||
|
for i, v in pairs(ShootWeaponEnums) do
|
||||||
|
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(TargetPawn, v)
|
||||||
|
if Weapon then
|
||||||
|
Res[#Res + 1] = UGCWeaponManagerSystem.GetWeaponItemID(Weapon)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Weapon_LastGetWeaponIDRes[PlayerKey] = Res
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function MyWeaponSystem.GetItemWeaponAmmunitionItemID(WeaponID)
|
||||||
|
return WeaponAmmunitionItem[WeaponID]
|
||||||
|
end
|
||||||
|
|
||||||
|
MyWeaponSystem.BackPackHandle1 = {}
|
||||||
|
MyWeaponSystem.BackPackHandle2 = {}
|
||||||
|
MyWeaponSystem.BackPackHandle3 = {}
|
||||||
|
MyWeaponSystem.BackPackHandle4 = {}
|
||||||
|
|
||||||
|
function MyWeaponSystem.UpdatePlayerBackPack(PlayerKey)
|
||||||
|
-- 默认武器
|
||||||
|
if MyWeaponSystem.BackPackHandle1[PlayerKey] then UGCEventSystem.StopTimer(MyWeaponSystem.BackPackHandle1[PlayerKey]) end
|
||||||
|
MyWeaponSystem.BackPackHandle1[PlayerKey] = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
MyWeaponSystem.BackPackHandle1[PlayerKey] = nil
|
||||||
|
UGCGameSystem.GameState:UpdatePlayerWeapon(PlayerKey)
|
||||||
|
end, 1.)
|
||||||
|
|
||||||
|
-- 默认装备
|
||||||
|
if MyWeaponSystem.BackPackHandle2[PlayerKey] then UGCEventSystem.StopTimer(MyWeaponSystem.BackPackHandle2[PlayerKey]) end
|
||||||
|
MyWeaponSystem.BackPackHandle2[PlayerKey] = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
MyWeaponSystem.BackPackHandle2[PlayerKey] = nil
|
||||||
|
local DefaultBackPack = TableHelper.DeepCopy(UGCGameSystem.GameState:GetPlayerBeBornParts(PlayerKey))
|
||||||
|
UGCGameSystem.GameState:PlayerAddItemInfo(PlayerKey, DefaultBackPack)
|
||||||
|
end, 2.)
|
||||||
|
|
||||||
|
-- 校验玩家的武器和配件1次
|
||||||
|
if MyWeaponSystem.BackPackHandle3[PlayerKey] then UGCEventSystem.StopTimer(MyWeaponSystem.BackPackHandle3[PlayerKey]) end
|
||||||
|
MyWeaponSystem.BackPackHandle3[PlayerKey] = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
MyWeaponSystem.BackPackHandle3[PlayerKey] = nil
|
||||||
|
UGCGameSystem.GameState:CheckWeaponAndParts(PlayerKey)
|
||||||
|
end, 6.)
|
||||||
|
-- 校验玩家的武器和配件2次
|
||||||
|
if MyWeaponSystem.BackPackHandle4[PlayerKey] then UGCEventSystem.StopTimer(MyWeaponSystem.BackPackHandle4[PlayerKey]) end
|
||||||
|
MyWeaponSystem.BackPackHandle4[PlayerKey] = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
MyWeaponSystem.BackPackHandle4[PlayerKey] = nil
|
||||||
|
UGCGameSystem.GameState:CheckWeaponAndParts(PlayerKey)
|
||||||
|
end, 8.)
|
||||||
|
|
||||||
|
-- 补满武器弹夹
|
||||||
|
UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
UGCSystemLibrary.PlayerFullBullet(PlayerKey)
|
||||||
|
end, 3.)
|
||||||
|
end
|
303
FX_Preview/Script/Global/System/PlayerScoreSystem.lua
Normal file
303
FX_Preview/Script/Global/System/PlayerScoreSystem.lua
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
--[[
|
||||||
|
使用说明
|
||||||
|
|
||||||
|
1、注册积分类型列表,放在GameState的
|
||||||
|
PlayerScoreSystem.RegisterInfo(InScoreList) 其中InScoreList 可参考PlayerScoreSystem.Config.ScoreList
|
||||||
|
|
||||||
|
2、在玩家加入时添加
|
||||||
|
PlayerScoreSystem.InitPlayerScoreData(PlayerKey)
|
||||||
|
|
||||||
|
3、绑定得分表的更新函数,更新函数内可以设置同步参数,参数放置GameState内
|
||||||
|
PlayerScoreSystem.BindChangeScoreDataCallBack(Func, Obj)
|
||||||
|
刷新绑定的案例:
|
||||||
|
(1)GameState加入同步参数PlayerScoreDatas
|
||||||
|
|
||||||
|
(2)GameState的BeginPlay函数内加入
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
-- 绑定更新积分的函数
|
||||||
|
PlayerScoreSystem.BindChangeScoreDataCallBack(self.UpdateAllPlayerScoreDatas, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
(3)加入UpdateAllPlayerScoreDatas函数
|
||||||
|
function UGCGameState:UpdateAllPlayerScoreDatas()
|
||||||
|
self.PlayerScoreDatas = PlayerScoreSystem.GetPlayerScoreDatas()
|
||||||
|
end
|
||||||
|
|
||||||
|
(4)加入UpdateAllPlayerScoreDatas函数
|
||||||
|
function UGCGameState:UpdateAllPlayerScoreDatas()
|
||||||
|
self.PlayerScoreDatas = PlayerScoreSystem.GetPlayerScoreDatas()
|
||||||
|
end
|
||||||
|
|
||||||
|
(5)加入OnRep_PlayerScoreDatas函数
|
||||||
|
function UGCGameState:OnRep_PlayerScoreDatas()
|
||||||
|
PlayerScoreSystem.SetPlayerScoreDatas(self.PlayerScoreDatas)
|
||||||
|
UGCEventSystem.SendEvent(EventEnum.UpdatePlayerScoreData)
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
常用函数 -----------
|
||||||
|
|
||||||
|
--- Server 重置所有玩家的积分信息
|
||||||
|
PlayerScoreSystem.ResetAllPlayerScoreData()
|
||||||
|
|
||||||
|
--- Server 增加玩家积分
|
||||||
|
PlayerScoreSystem.AddPlayerScoreData(PlayerKey, ScoreType, AddVal)
|
||||||
|
|
||||||
|
--- Server 设置玩家积分
|
||||||
|
PlayerScoreSystem.SetPlayerScoreDataFromType(PlayerKey, ScoreType, Val)
|
||||||
|
|
||||||
|
--- Server or Client 获取玩家积分信息
|
||||||
|
---@return number
|
||||||
|
PlayerScoreSystem.GetPlayerScoreDataFromType(PlayerKey, ScoreType)
|
||||||
|
|
||||||
|
--- Server or Client 获取玩家得分 返回: ∑得分类型×类型对应得分
|
||||||
|
---@return number
|
||||||
|
PlayerScoreSystem.GetPlayerScore(PlayerKey)
|
||||||
|
|
||||||
|
--- Server or Client 获取玩家排名 InPlayerKeys:所需排名的PlayerKeys,若为nil则全部一起排名
|
||||||
|
---@return "table {PlayerKey, ...}"
|
||||||
|
PlayerScoreSystem.GetRank(InPlayerKeys)
|
||||||
|
|
||||||
|
--- Server or Client 获取队伍的玩家排名
|
||||||
|
---@return "table {[TeamID] = {PlayerKey, ...}, ...}"
|
||||||
|
PlayerScoreSystem.GetTeamRank()
|
||||||
|
|
||||||
|
--- Server 刷新或重设PlayerScoreSystem内的玩家TeamID
|
||||||
|
PlayerScoreSystem.UpdatePlayerTeamID(PlayerKey, TeamID)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 特殊情况需要用的函数 -----------
|
||||||
|
|
||||||
|
--- Server 移除玩家得分信息 NeedNotify是否通知更新 这个比较少用,用于有玩家退出时再进行补人的操作,放在PlayerExit内调用
|
||||||
|
PlayerScoreSystem.RemovePlayerScoreInfo(PlayerKey, NeedNotify)
|
||||||
|
|
||||||
|
--- Server 清除退出的玩家得分信息
|
||||||
|
PlayerScoreSystem.ClearExitPlayer()
|
||||||
|
|
||||||
|
]]
|
||||||
|
|
||||||
|
PlayerScoreSystem = PlayerScoreSystem or {}
|
||||||
|
|
||||||
|
PlayerScoreSystem.Config = {}
|
||||||
|
|
||||||
|
|
||||||
|
-- Config ----------------------------------------------------------------
|
||||||
|
PlayerScoreSystem.Config.EScoreType = {
|
||||||
|
Kills = 1,
|
||||||
|
Assists = 2,
|
||||||
|
Deaths = 3,
|
||||||
|
Damage = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Key值对应得分类型,Value值对应该类型每点所获得的积分
|
||||||
|
PlayerScoreSystem.Config.ScoreList = {
|
||||||
|
[PlayerScoreSystem.Config.EScoreType.Kills] = 0;
|
||||||
|
[PlayerScoreSystem.Config.EScoreType.Assists] = 0;
|
||||||
|
[PlayerScoreSystem.Config.EScoreType.Deaths] = -1;
|
||||||
|
[PlayerScoreSystem.Config.EScoreType.Damage] = 10;
|
||||||
|
}
|
||||||
|
-- Config End ------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Params ----------------------------------------------------------------
|
||||||
|
-- 得分类型对应的分数 [ScoreType] = Score
|
||||||
|
PlayerScoreSystem.ScoreList = {};
|
||||||
|
-- 得分类型
|
||||||
|
PlayerScoreSystem.ScoreType = {};
|
||||||
|
-- 玩家得分信息 [PlayerKey] = {[ScoreType] = Score, ...} 额外附加 TeamID(PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID)
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas = {};
|
||||||
|
-- Params End ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
--- 注册积分类型列表
|
||||||
|
---@param InScoreList 可参考PlayerScoreSystem.Config.ScoreList
|
||||||
|
function PlayerScoreSystem.RegisterInfo(InScoreList)
|
||||||
|
if type(InScoreList) ~= "table" then
|
||||||
|
UGCLogSystem.LogError("[PlayerScoreSystem_RegisterInfo] InScoreType 类型错误")
|
||||||
|
end
|
||||||
|
|
||||||
|
PlayerScoreSystem.ScoreType = table.getKeys(InScoreList)
|
||||||
|
PlayerScoreSystem.ScoreList = InScoreList
|
||||||
|
|
||||||
|
UGCLogSystem.LogTree("[PlayerScoreSystem_RegisterInfo] ScoreType", PlayerScoreSystem.ScoreType)
|
||||||
|
UGCLogSystem.LogTree("[PlayerScoreSystem_RegisterInfo] ScoreList", PlayerScoreSystem.ScoreList)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server or Client
|
||||||
|
--- 获取得分信息
|
||||||
|
function PlayerScoreSystem.GetPlayerScoreDatas()
|
||||||
|
return PlayerScoreSystem.PlayerScoreDatas
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 设置全部的得分信息 此操作不进行函数回调,因为有可能是GameState的参数传进来的所以有可能导致死循环
|
||||||
|
function PlayerScoreSystem.SetPlayerScoreDatas(InPlayerScoreDatas)
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas = InPlayerScoreDatas
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 绑定GameState的更新函数,简化其他操作,所以只能绑一个
|
||||||
|
function PlayerScoreSystem.BindChangeScoreDataCallBack(Func, Obj)
|
||||||
|
PlayerScoreSystem.ChangeScoreDataCallBackFunc = Func
|
||||||
|
PlayerScoreSystem.ChangeScoreDataCallBackObj = Obj
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 通知回调
|
||||||
|
function PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
if PlayerScoreSystem.ChangeScoreDataCallBackFunc then
|
||||||
|
if PlayerScoreSystem.ChangeScoreDataCallBackObj then
|
||||||
|
PlayerScoreSystem.ChangeScoreDataCallBackFunc(PlayerScoreSystem.ChangeScoreDataCallBackObj)
|
||||||
|
else
|
||||||
|
PlayerScoreSystem.ChangeScoreDataCallBackFunc()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 初始化玩家的积分信息,也可作为重置函数使用
|
||||||
|
function PlayerScoreSystem.InitPlayerScoreData(PlayerKey, IsReset)
|
||||||
|
if PlayerScoreSystem.PlayerScoreDatas[PlayerKey] == nil or IsReset then
|
||||||
|
-- 初始化列表
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey] = {}
|
||||||
|
-- 初始化信息
|
||||||
|
for i, v in pairs(PlayerScoreSystem.ScoreType) do
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey][v] = 0
|
||||||
|
end
|
||||||
|
-- 设置队伍ID
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID = UGCPlayerStateSystem.GetTeamID(PlayerKey)
|
||||||
|
UGCLogSystem.Log("[PlayerScoreSystem_InitPlayerScoreData] TeamID:%s", tostring(PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID))
|
||||||
|
-- 更新函数回调
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 刷新玩家TeamID
|
||||||
|
function PlayerScoreSystem.UpdatePlayerTeamID(PlayerKey, TeamID)
|
||||||
|
if TeamID then
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID = TeamID
|
||||||
|
else
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID = UGCPlayerStateSystem.GetTeamID(PlayerKey)
|
||||||
|
end
|
||||||
|
UGCLogSystem.Log("[PlayerScoreSystem_UpdatePlayerTeamID] TeamID:%s", tostring(PlayerScoreSystem.PlayerScoreDatas[PlayerKey].TeamID))
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 校验玩家积分信息是否初始化
|
||||||
|
function PlayerScoreSystem.CheckPlayerScoreDataIsInit(PlayerKey)
|
||||||
|
if PlayerScoreSystem.PlayerScoreDatas[PlayerKey] == nil then
|
||||||
|
UGCLogSystem.LogError("[PlayerScoreSystem_CheckPlayerScoreDataIsInit] PlayerKey:%s, 玩家信息未注册", tostring(PlayerKey))
|
||||||
|
PlayerScoreSystem.InitPlayerScoreData(PlayerKey)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 重置所有玩家的积分信息
|
||||||
|
function PlayerScoreSystem.ResetAllPlayerScoreData()
|
||||||
|
for PlayerKey, v in pairs(PlayerScoreSystem.PlayerScoreDatas) do
|
||||||
|
PlayerScoreSystem.InitPlayerScoreData(PlayerKey, true)
|
||||||
|
end
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 添加玩家积分信息
|
||||||
|
function PlayerScoreSystem.AddPlayerScoreData(PlayerKey, ScoreType, AddVal)
|
||||||
|
PlayerScoreSystem.CheckPlayerScoreDataIsInit(PlayerKey)
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey][ScoreType] = PlayerScoreSystem.PlayerScoreDatas[PlayerKey][ScoreType] + AddVal
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 移除玩家得分信息
|
||||||
|
function PlayerScoreSystem.RemovePlayerScoreInfo(PlayerKey, NeedNotify)
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey] = nil
|
||||||
|
if NeedNotify == nil or NeedNotify then
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 清除退出的玩家得分信息
|
||||||
|
function PlayerScoreSystem.ClearExitPlayer()
|
||||||
|
local AllPlayerKey = table.getKeys(PlayerScoreSystem.PlayerScoreDatas)
|
||||||
|
for i, v in pairs(AllPlayerKey) do
|
||||||
|
if UGCGameSystem.GetPlayerControllerByPlayerKey(v) == nil then
|
||||||
|
PlayerScoreSystem.RemovePlayerScoreInfo(v, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 设置玩家积分信息
|
||||||
|
function PlayerScoreSystem.SetPlayerScoreDataFromType(PlayerKey, ScoreType, Val)
|
||||||
|
PlayerScoreSystem.CheckPlayerScoreDataIsInit(PlayerKey)
|
||||||
|
PlayerScoreSystem.PlayerScoreDatas[PlayerKey][ScoreType] = Val
|
||||||
|
PlayerScoreSystem.NotifyChangeScoreDataCallBack()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server or Client
|
||||||
|
--- 获取玩家积分信息
|
||||||
|
function PlayerScoreSystem.GetPlayerScoreDataFromType(PlayerKey, ScoreType)
|
||||||
|
PlayerScoreSystem.CheckPlayerScoreDataIsInit(PlayerKey)
|
||||||
|
return PlayerScoreSystem.PlayerScoreDatas[PlayerKey][ScoreType]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server or Client
|
||||||
|
--- 获取玩家得分
|
||||||
|
---@return number
|
||||||
|
function PlayerScoreSystem.GetPlayerScore(PlayerKey)
|
||||||
|
PlayerScoreSystem.CheckPlayerScoreDataIsInit(PlayerKey)
|
||||||
|
local Res = 0
|
||||||
|
for i, v in pairs(PlayerScoreSystem.PlayerScoreDatas[PlayerKey]) do
|
||||||
|
if PlayerScoreSystem.ScoreList[i] then
|
||||||
|
Res = Res + PlayerScoreSystem.ScoreList[i] * v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server or Client
|
||||||
|
--- 获取玩家排名
|
||||||
|
---@param InPlayerKeys "所需排名的PlayerKeys,若为nil则全部一起排名"
|
||||||
|
---@return "table {PlayerKey, ...}"
|
||||||
|
function PlayerScoreSystem.GetRank(InPlayerKeys)
|
||||||
|
local AllPlayerKey = {}
|
||||||
|
if InPlayerKeys == nil or type(InPlayerKeys) ~= "table" then
|
||||||
|
AllPlayerKey = table.getKeys(PlayerScoreSystem.PlayerScoreDatas)
|
||||||
|
else
|
||||||
|
AllPlayerKey = InPlayerKeys
|
||||||
|
end
|
||||||
|
table.sort(AllPlayerKey, function(a, b) return PlayerScoreSystem.GetPlayerScore(a) > PlayerScoreSystem.GetPlayerScore(b) end)
|
||||||
|
return AllPlayerKey
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server or Client
|
||||||
|
--- 获取队伍的玩家排名
|
||||||
|
---@return "table {[TeamID] = {PlayerKey, ...}, ...}"
|
||||||
|
function PlayerScoreSystem.GetTeamRank()
|
||||||
|
local Res = {}
|
||||||
|
-- 获取队伍玩家PlayerKey
|
||||||
|
local TeamPlayers = {}
|
||||||
|
for PlayerKey, ScoreInfo in pairs(PlayerScoreSystem.PlayerScoreDatas) do
|
||||||
|
if TeamPlayers[ScoreInfo.TeamID] == nil then TeamPlayers[ScoreInfo.TeamID] = {} end
|
||||||
|
TeamPlayers[ScoreInfo.TeamID][#TeamPlayers[ScoreInfo.TeamID] + 1] = PlayerKey
|
||||||
|
end
|
||||||
|
-- 获取队伍内排名
|
||||||
|
for TeamID, PlayerKeys in pairs(TeamPlayers) do
|
||||||
|
Res[TeamID] = PlayerScoreSystem.GetRank(PlayerKeys)
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
151
FX_Preview/Script/Global/System/SoundSystem.lua
Normal file
151
FX_Preview/Script/Global/System/SoundSystem.lua
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
|
||||||
|
SoundSystem = SoundSystem or {}
|
||||||
|
|
||||||
|
SoundSystem.ESound = {
|
||||||
|
Scoll = 1,
|
||||||
|
Click = 2,
|
||||||
|
Btn = 3,
|
||||||
|
Kill = 4,
|
||||||
|
Kill2 = 5,
|
||||||
|
Kill3 = 6,
|
||||||
|
Incentive = 7,
|
||||||
|
ActiveMechanism = 8,
|
||||||
|
MechanismKill = 9,
|
||||||
|
|
||||||
|
HookFire = 101,
|
||||||
|
HookImpulse = 102,
|
||||||
|
Impulse = 103,
|
||||||
|
Dissipate = 104,
|
||||||
|
OkLetsGo = 105,
|
||||||
|
|
||||||
|
IsReady = 201,
|
||||||
|
Clock = 202,
|
||||||
|
TrapOpen = 203,
|
||||||
|
GameStart = 204,
|
||||||
|
Impact = 205, -- 击打音效
|
||||||
|
BreakWind = 206, -- 破风
|
||||||
|
Star = 207, -- 获得星星
|
||||||
|
Pu = 208,
|
||||||
|
|
||||||
|
Shot_Boom = 209,
|
||||||
|
Boom2 = 210,
|
||||||
|
AddScore = 211,
|
||||||
|
Error = 212,
|
||||||
|
Right = 213,
|
||||||
|
Point = 214;
|
||||||
|
PickUpBuff = 215;
|
||||||
|
KillFX = 216;
|
||||||
|
Explosion = 217;
|
||||||
|
|
||||||
|
-- Piano
|
||||||
|
Piano_3dd = 1073,
|
||||||
|
Piano_6dd = 1076,
|
||||||
|
Piano_2ddd = 1082,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SoundSystem.EMusic = {
|
||||||
|
-- UGC Music
|
||||||
|
Music1 = 100001 ,
|
||||||
|
Music2 = 100002 ,
|
||||||
|
Music3 = 100003 ,
|
||||||
|
Music4 = 100004 ,
|
||||||
|
Music5 = 100005 ,
|
||||||
|
Music6 = 100006 ,
|
||||||
|
Music7 = 100007 ,
|
||||||
|
Music8 = 100008 ,
|
||||||
|
Music9 = 100009 ,
|
||||||
|
Music10 = 100010 ,
|
||||||
|
Music11 = 100011 ,
|
||||||
|
Music12 = 100012 ,
|
||||||
|
Music13 = 100013 ,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundSystem.MusicName = {
|
||||||
|
[SoundSystem.EMusic.Music1 ] = "盛夏空投", -- 节奏
|
||||||
|
[SoundSystem.EMusic.Music2 ] = "赛博纪元", -- 科技节奏
|
||||||
|
[SoundSystem.EMusic.Music3 ] = "魔鬼纵队", -- 幽灵的感觉
|
||||||
|
[SoundSystem.EMusic.Music4 ] = "勇气", -- 人声
|
||||||
|
[SoundSystem.EMusic.Music5 ] = "四圣降临", -- 叶问的感觉
|
||||||
|
[SoundSystem.EMusic.Music6 ] = "沙漠绿洲", -- 平静
|
||||||
|
[SoundSystem.EMusic.Music7 ] = "锦绣年画", -- 过年 年年有余的感觉
|
||||||
|
[SoundSystem.EMusic.Music8 ] = "电音嘉年华",--类似悬溺
|
||||||
|
[SoundSystem.EMusic.Music9 ] = "空投行动", -- 射击长时间玩法
|
||||||
|
[SoundSystem.EMusic.Music10] = "未来之城", -- 跑酷等
|
||||||
|
[SoundSystem.EMusic.Music11] = "大战在即",
|
||||||
|
[SoundSystem.EMusic.Music12] = "激战隆冬",
|
||||||
|
[SoundSystem.EMusic.Music13] = "声动光影",
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundSystem.SoundList = {
|
||||||
|
[SoundSystem.ESound.Scoll] = '/Game/WwiseEvent/UI/Play_UI_Item_Change.Play_UI_Item_Change',
|
||||||
|
[SoundSystem.ESound.Click] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Click_2_1.AK_Click_2_1'),
|
||||||
|
[SoundSystem.ESound.Btn] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Button_1.AK_Button_1'),
|
||||||
|
[SoundSystem.ESound.Kill] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/Audio_Kill.Audio_Kill'),
|
||||||
|
[SoundSystem.ESound.Kill2] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Kill2_1.AK_Kill2_1'),
|
||||||
|
[SoundSystem.ESound.Kill3] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Kill3_1.AK_Kill3_1'),
|
||||||
|
[SoundSystem.ESound.Incentive] = '/Game/WwiseEvent/UI/Play_UI_Champion.Play_UI_Champion',
|
||||||
|
[SoundSystem.ESound.ActiveMechanism] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_ActiveMechanism_1.AK_ActiveMechanism_1'),
|
||||||
|
[SoundSystem.ESound.MechanismKill] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_MechanismKill_1.AK_MechanismKill_1'),
|
||||||
|
|
||||||
|
[SoundSystem.ESound.HookFire] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/Ak_HookFire_1.Ak_HookFire_1'),
|
||||||
|
[SoundSystem.ESound.HookImpulse] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/Ak_HookImpulse_1.Ak_HookImpulse_1'),
|
||||||
|
[SoundSystem.ESound.Impulse] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/Ak_Impulse_1.Ak_Impulse_1'),
|
||||||
|
[SoundSystem.ESound.Dissipate] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Dissipate_1.AK_Dissipate_1'),
|
||||||
|
[SoundSystem.ESound.OkLetsGo] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_OkLetsGo_1.AK_OkLetsGo_1'),
|
||||||
|
[SoundSystem.ESound.IsReady] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_IsReady_1.AK_IsReady_1'),
|
||||||
|
[SoundSystem.ESound.Clock] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/T_Clock_1.T_Clock_1'),
|
||||||
|
[SoundSystem.ESound.TrapOpen] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_OpenDoor_1.AK_OpenDoor_1'),
|
||||||
|
[SoundSystem.ESound.GameStart] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_GameStart_1.AK_GameStart_1'),
|
||||||
|
[SoundSystem.ESound.Impact] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Impact_1.AK_Impact_1'),
|
||||||
|
[SoundSystem.ESound.BreakWind] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_BreakWind_1.AK_BreakWind_1'),
|
||||||
|
[SoundSystem.ESound.Star] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Star_1.AK_Star_1'),
|
||||||
|
[SoundSystem.ESound.Pu] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_PU_1.AK_PU_1'),
|
||||||
|
[SoundSystem.ESound.Shot_Boom] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AT_Shot_Boom_1.AT_Shot_Boom_1'),
|
||||||
|
|
||||||
|
[SoundSystem.ESound.Boom2] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Boom2_1.AK_Boom2_1'),
|
||||||
|
[SoundSystem.ESound.AddScore] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_AddScore_1.AK_AddScore_1'),
|
||||||
|
[SoundSystem.ESound.Error] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Error_1.AK_Error_1'),
|
||||||
|
[SoundSystem.ESound.Right] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Right_1.AK_Right_1'),
|
||||||
|
[SoundSystem.ESound.Point] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Point_1.AK_Point_1'),
|
||||||
|
|
||||||
|
[SoundSystem.ESound.PickUpBuff] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_PickUpBuff_1.AK_PickUpBuff_1');
|
||||||
|
[SoundSystem.ESound.KillFX] ='/Game/WwiseEvent/UI/Play_UI_KillEffect.Play_UI_KillEffect';
|
||||||
|
[SoundSystem.ESound.Explosion] ='/Game/WwiseEvent/Weapon_Player/Weapon_UCAV/Play_Weapon_UCAV_Explosion.Play_Weapon_UCAV_Explosion';
|
||||||
|
|
||||||
|
[SoundSystem.ESound.Piano_3dd] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Piano_3dd_1.AK_Piano_3dd_1'),
|
||||||
|
[SoundSystem.ESound.Piano_6dd] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Piano_6dd_1.AK_Piano_6dd_1'),
|
||||||
|
[SoundSystem.ESound.Piano_2ddd] = UGCGameSystem.GetUGCResourcesFullPath('Asset/WwiseEvent/AK_Piano_2ddd_1.AK_Piano_2ddd_1'),
|
||||||
|
|
||||||
|
[SoundSystem.EMusic.Music1 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_Summer_Theme_CG014.Play_Music_Summer_Theme_CG014',
|
||||||
|
[SoundSystem.EMusic.Music2 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_Cyberpunk_Theme.Play_Music_Cyberpunk_Theme',
|
||||||
|
[SoundSystem.EMusic.Music3 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_Halloween.Play_Music_Halloween',
|
||||||
|
[SoundSystem.EMusic.Music4 ] = '/Game/WwiseEvent/Music/Music_Auto/Play_Music_Auto_Courage.Play_Music_Auto_Courage',
|
||||||
|
[SoundSystem.EMusic.Music5 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_MythicalCreatures_CG011.Play_Music_MythicalCreatures_CG011',
|
||||||
|
[SoundSystem.EMusic.Music6 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_SS6_Theme.Play_Music_SS6_Theme',
|
||||||
|
[SoundSystem.EMusic.Music7 ] = '/Game/WwiseEvent/Music/Music_Main/Play_CG021_Music_Gardens_SpringFestival_Theme.Play_CG021_Music_Gardens_SpringFestival_Theme',
|
||||||
|
[SoundSystem.EMusic.Music8 ] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_717Summer_EDM.Play_Music_717Summer_EDM',
|
||||||
|
[SoundSystem.EMusic.Music9 ] = '/Game/WwiseEvent/Music/Music_Main/Play_CG018_Music_Celebration_Theme.Play_CG018_Music_Celebration_Theme',
|
||||||
|
[SoundSystem.EMusic.Music10] = '/Game/WwiseEvent/Music/Music_Main/Play_CG019_Music_FutureCity_Theme.Play_CG019_Music_FutureCity_Theme',
|
||||||
|
[SoundSystem.EMusic.Music11] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_Snow_Theme_CG010.Play_Music_Snow_Theme_CG010',
|
||||||
|
[SoundSystem.EMusic.Music12] = '/Game/WwiseEvent/Music/Music_Main/Play_CG016_Music_Winter_Theme.Play_CG016_Music_Winter_Theme',
|
||||||
|
[SoundSystem.EMusic.Music13] = '/Game/WwiseEvent/Music/Music_Main/Play_Music_MovieStudio_Theme_CG015.Play_Music_MovieStudio_Theme_CG015',
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function SoundSystem.PlaySound(SoundType, TargetLocation, TargetRotation)
|
||||||
|
if SoundSystem.SoundList[SoundType] ~= nil then
|
||||||
|
local AKSound = UGCSystemLibrary.LoadAsset(SoundSystem.SoundList[SoundType], true)
|
||||||
|
if TargetLocation then
|
||||||
|
if TargetRotation == nil then
|
||||||
|
TargetRotation = VectorHelper.RotZero()
|
||||||
|
end
|
||||||
|
return UGCSoundManagerSystem.PlaySoundAtLocation(AKSound, TargetLocation, TargetRotation)
|
||||||
|
else
|
||||||
|
return UGCSoundManagerSystem.PlaySound2D(AKSound)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
37
FX_Preview/Script/Global/System/UGCDelegate.lua
Normal file
37
FX_Preview/Script/Global/System/UGCDelegate.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
--[[
|
||||||
|
[使用方法]
|
||||||
|
====初始化====
|
||||||
|
local UGCDelegate = require("Script.Common.UGCDelegate");
|
||||||
|
local DelObj = UGCDelegate.New(self, self.SomeFunction);
|
||||||
|
|
||||||
|
====在需要调用的地方====
|
||||||
|
DelObj:Execute(Par1, Par2, Par3);
|
||||||
|
--]]
|
||||||
|
|
||||||
|
---@class UGCDelegate
|
||||||
|
local UGCDelegate = LuaClass("UGCDelegate");
|
||||||
|
|
||||||
|
UGCDelegate.Object = nil;
|
||||||
|
UGCDelegate.Func = nil;
|
||||||
|
|
||||||
|
|
||||||
|
--- 构造函数
|
||||||
|
---@param InObject any
|
||||||
|
---@param InFunc function @函数变量
|
||||||
|
function UGCDelegate:ctor(InObject, InFunc)
|
||||||
|
self.Object = InObject;
|
||||||
|
self.Func = InFunc;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 调用回调函数
|
||||||
|
function UGCDelegate:Execute(...)
|
||||||
|
if self.Object ~= nil then
|
||||||
|
self.Func(self.Object, ...);
|
||||||
|
elseif self.Func ~= nil then
|
||||||
|
self.Func(...);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return UGCDelegate;
|
66
FX_Preview/Script/Global/System/UGCDelegateMulticast.lua
Normal file
66
FX_Preview/Script/Global/System/UGCDelegateMulticast.lua
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
--[[
|
||||||
|
[使用方法]
|
||||||
|
====初始化====
|
||||||
|
local UGCDelegateMulticast = require("Script.Common.UGCDelegateMulticast");
|
||||||
|
local DelObj = UGCDelegate.New(self, self.SomeFunction);
|
||||||
|
DelObj:Add(self, self.AnotherFunction);
|
||||||
|
|
||||||
|
====在需要调用的地方====
|
||||||
|
DelObj:Broadcast(Par1, Par2, Par3);
|
||||||
|
--]]
|
||||||
|
|
||||||
|
---@class UGCDelegateMulticast
|
||||||
|
local UGCDelegateMulticast = LuaClass("UGCDelegateMulticast");
|
||||||
|
|
||||||
|
--- 绑定回调函数列表
|
||||||
|
UGCDelegateMulticast.EventsHandler = {};
|
||||||
|
|
||||||
|
|
||||||
|
--- 构造函数
|
||||||
|
---@param InObject any
|
||||||
|
---@param InFunc function @函数变量
|
||||||
|
function UGCDelegateMulticast:ctor(InObject, InFunc)
|
||||||
|
UGCDelegateMulticast:Add(InObject, InFunc);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 添加回调函数
|
||||||
|
---@param InObject any
|
||||||
|
---@param InFunc function @函数变量
|
||||||
|
function UGCDelegateMulticast:Add(InObject, InFunc)
|
||||||
|
table.insert(UGCDelegateMulticast.EventsHandler, {Object=InObject, Func=InFunc});
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 移除回调函数
|
||||||
|
---@param InObject any
|
||||||
|
---@param InFunc function @函数变量
|
||||||
|
function UGCDelegateMulticast:Remove(InObject, InFunc)
|
||||||
|
for _, FuncData in pairs(UGCDelegateMulticast.EventsHandler) do
|
||||||
|
if FuncData.Object == InObject and FuncData.Func == InFunc then
|
||||||
|
FuncData.Object = nil;
|
||||||
|
FuncData.Func = nil;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 清除所有的回调绑定
|
||||||
|
function UGCDelegateMulticast:Clear()
|
||||||
|
self.EventsHandler = {};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 调用所有的回调函数
|
||||||
|
function UGCDelegateMulticast:Broadcast(...)
|
||||||
|
for _, FuncData in pairs(UGCDelegateMulticast.EventsHandler) do
|
||||||
|
if FuncData.Object ~= nil then
|
||||||
|
FuncData.Func(FuncData.Object, ...);
|
||||||
|
elseif FuncData.Func ~= nil then
|
||||||
|
FuncData.Func(...);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return UGCDelegateMulticast;
|
108
FX_Preview/Script/Global/System/UGCEventSystem.lua
Normal file
108
FX_Preview/Script/Global/System/UGCEventSystem.lua
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
UGCEventSystem = UGCEventSystem or {}
|
||||||
|
|
||||||
|
UGCEventSystem.Events = {}
|
||||||
|
|
||||||
|
-- 添加监听
|
||||||
|
function UGCEventSystem.AddListener(EventType, Func, Object)
|
||||||
|
if EventType == nil or Func == nil or type(Func) ~= "function" then
|
||||||
|
UGCLogSystem.LogError("[UGCEventSystem_AddListener] EventType or Func is nil!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local FuncData = {}
|
||||||
|
FuncData.Object = Object
|
||||||
|
FuncData.Func = Func
|
||||||
|
|
||||||
|
if UGCEventSystem.Events[EventType]==nil then
|
||||||
|
local NewEventFuncs={}
|
||||||
|
table.insert(NewEventFuncs ,FuncData)
|
||||||
|
UGCEventSystem.Events[EventType] = NewEventFuncs
|
||||||
|
--UGCLogSystem.Log("[UGCEventSystem_AddListener] EventType[%s], Func[%s]", tostring(EventType), tostring(Func))
|
||||||
|
else
|
||||||
|
table.insert(UGCEventSystem.Events[EventType], FuncData)
|
||||||
|
--UGCLogSystem.Log("[UGCEventSystem_AddListener] EventType[%s], Func[%s]", tostring(EventType), tostring(Func))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 移除监听
|
||||||
|
function UGCEventSystem.RemoveListener(EventType, Func, Object)
|
||||||
|
if EventType == nil or Func == nil then
|
||||||
|
UGCLogSystem.LogError("[UGCEventSystem_RemoveListener] EventType or Func is nil!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if UGCEventSystem.Events[EventType] ~= nil then
|
||||||
|
for i = #UGCEventSystem.Events[EventType], 1, -1 do
|
||||||
|
local FuncData = UGCEventSystem.Events[EventType][i]
|
||||||
|
if FuncData.Func == Func and FuncData.Object == Object then
|
||||||
|
local result = table.remove(UGCEventSystem.Events[EventType], i)
|
||||||
|
UGCLogSystem.Log("[UGCEventSystem_RemoveListener] EventType[%s], Func[%s]", tostring(EventType), tostring(result))
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCEventSystem_RemoveListener] EventFuncs[%s] is nil!", tostring(EventType))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 派发事件
|
||||||
|
function UGCEventSystem.SendEvent(EventType, ...)
|
||||||
|
UGCLogSystem.Log("[UGCEventSystem_SendEvent] EventType: %s", tostring(EventType))
|
||||||
|
if EventType ~= nil then
|
||||||
|
local EventFuncs = UGCEventSystem.Events[EventType];
|
||||||
|
if EventFuncs ~= nil then
|
||||||
|
for i, FuncData in pairs(EventFuncs) do
|
||||||
|
if FuncData.Object ~= nil then
|
||||||
|
FuncData.Func(FuncData.Object, ...)
|
||||||
|
else
|
||||||
|
FuncData.Func(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCEventSystem_SendEvent] EventFuncs[%s] is nil!", tostring(EventType))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- SetTimer
|
||||||
|
---@param Obj UObject
|
||||||
|
---@param Fun fun()
|
||||||
|
---@param IntevalSeconds float
|
||||||
|
---@return TimerHandle
|
||||||
|
function UGCEventSystem.SetTimer(Obj, Fun, IntevalSeconds)
|
||||||
|
UGCLogSystem.Log("[UGCEventSystem_SetTimer] 设置定时器 %s:%s", UE.GetPathName(Obj), tostring(Fun))
|
||||||
|
local TimerDelegate = ObjectExtend.CreateDelegate(Obj, Fun, Obj)
|
||||||
|
local Handle = KismetSystemLibrary.K2_SetTimerDelegateForLua(TimerDelegate, Obj, IntevalSeconds, false)
|
||||||
|
local R = {}
|
||||||
|
R.Object = Obj
|
||||||
|
R.Handle = Handle
|
||||||
|
return R
|
||||||
|
end
|
||||||
|
|
||||||
|
--- SetTimerLoop
|
||||||
|
---@param Obj UObject
|
||||||
|
---@param Fun fun()
|
||||||
|
---@param IntevalSeconds float
|
||||||
|
---@return TimerHandle
|
||||||
|
function UGCEventSystem.SetTimerLoop(Obj, Fun, IntevalSeconds)
|
||||||
|
local TimerDelegate = ObjectExtend.CreateDelegate(Obj, Fun, Obj);
|
||||||
|
local Handle = KismetSystemLibrary.K2_SetTimerDelegateForLua(TimerDelegate, Obj, IntevalSeconds, true);
|
||||||
|
local R = {};
|
||||||
|
R.Object = Obj;
|
||||||
|
R.Handle = Handle;
|
||||||
|
|
||||||
|
UGCLogSystem.Log("[UGCEventSystem_SetTimerLoop] 设置循环定时器 %s:%s H:%s", UE.GetPathName(Obj), tostring(Fun), tostring(R));
|
||||||
|
return R;
|
||||||
|
end
|
||||||
|
|
||||||
|
--- StopTimer
|
||||||
|
---@param HandlePair TimerHandle
|
||||||
|
function UGCEventSystem.StopTimer(HandlePair)
|
||||||
|
if HandlePair == nil then
|
||||||
|
UGCLogSystem.LogError("[UGCEventSystem_StopTimer] HandlePair is nil")
|
||||||
|
else
|
||||||
|
UGCLogSystem.Log("[UGCEventSystem_StopTimer] 停止定时器 Object:%s Handle:%s", UE.GetPathName(HandlePair.Object), tostring(HandlePair.Handle));
|
||||||
|
KismetSystemLibrary.K2_ClearTimerHandle(HandlePair.Object, HandlePair.Handle);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return UGCEventSystem
|
46
FX_Preview/Script/Global/System/UGCLogSystem.lua
Normal file
46
FX_Preview/Script/Global/System/UGCLogSystem.lua
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
||||||
|
--- Created by LT.
|
||||||
|
--- DateTime: 2023/10/29 15:49
|
||||||
|
---
|
||||||
|
UGCLogSystem = UGCLogSystem or {}
|
||||||
|
|
||||||
|
UGCLogSystem.EnableLog = true
|
||||||
|
function UGCLogSystem.SetEnableLog(isEnable)
|
||||||
|
UGCLogSystem.EnableLog = isEnable
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCLogSystem.LogTag()
|
||||||
|
return "[UGCLogSystem] " .. (UGCGameSystem.IsServer() and "[Server]" or "[Client]")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function UGCLogSystem.Print(Log)
|
||||||
|
if not UGCLogSystem.EnableLog then return end
|
||||||
|
print(Log)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCLogSystem.Log(Fmt, ...)
|
||||||
|
if not UGCLogSystem.EnableLog then return end
|
||||||
|
|
||||||
|
local LogStr = UGCLogSystem.LogTag()..string.format(Fmt, ...)
|
||||||
|
UGCLogSystem.Print(LogStr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCLogSystem.LogTree(Fmt, OutTable)
|
||||||
|
if not UGCLogSystem.EnableLog then return end
|
||||||
|
log_tree(Fmt, OutTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCLogSystem.UGCLog(Fmt, ...)
|
||||||
|
if not UGCLogSystem.EnableLog then return end
|
||||||
|
ugcprint(string.format(Fmt, ...));
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCLogSystem.LogError(Fmt, ...)
|
||||||
|
if not UGCLogSystem.EnableLog then return end
|
||||||
|
|
||||||
|
local LogStr = UGCLogSystem.LogTag().."[LogicError]"..string.format(Fmt, ...)
|
||||||
|
UGCLogSystem.Print(LogStr)
|
||||||
|
end
|
114
FX_Preview/Script/Global/System/UGCSendRPCSystem.lua
Normal file
114
FX_Preview/Script/Global/System/UGCSendRPCSystem.lua
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
--[[
|
||||||
|
需要委托绑定初始化:InitUGCSendRPCSystem
|
||||||
|
服务器客户端处均可初始化,仅一方初始化则只能在该位置发起RPC 建议在服务器和客户端均执行InitUGCSendRPCSystem
|
||||||
|
InTargetObj内的目标RPC函数必须调用UGCSendRPCSystem.RPCFunc(...)如下
|
||||||
|
function UGCGameState:UGCSendRPCSystemFunc(...) UGCSendRPCSystem.RPCFunc(...) end
|
||||||
|
]]--
|
||||||
|
|
||||||
|
UGCSendRPCSystem = UGCSendRPCSystem or {}
|
||||||
|
|
||||||
|
UGCSendRPCSystem.DelegationObj = nil
|
||||||
|
UGCSendRPCSystem.DelegationFuncName = ""
|
||||||
|
|
||||||
|
---@param InTargetObj AActor*
|
||||||
|
---@param InUGCSendRPCSystemFuncName string
|
||||||
|
function UGCSendRPCSystem.InitUGCSendRPCSystem(InTargetObj, InUGCSendRPCSystemFuncName)
|
||||||
|
if UE.IsValid(InTargetObj) and type(InTargetObj[InUGCSendRPCSystemFuncName]) == "function" then
|
||||||
|
UGCSendRPCSystem.DelegationObj = InTargetObj
|
||||||
|
UGCSendRPCSystem.DelegationFuncName = InUGCSendRPCSystemFuncName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- RPC自动发送 TargetPlayer为nil则广播到所有客户端,为table则发送到包含的客户端,为int32则发送到目标客户端
|
||||||
|
---@param RPCFuncName UGCSendRPCSystem的函数名称
|
||||||
|
---@param InTargetPlayer multi nil/table/int32
|
||||||
|
---@param ... any 事件输入的可变参数
|
||||||
|
function UGCSendRPCSystem.AutoTriggerRPC(RPCFuncName, InTargetPlayer, ...)
|
||||||
|
if not UGCSendRPCSystem.CheckUGCSendRPCSystem() then
|
||||||
|
UGCLogSystem.LogError("[UGCSendRPCSystem_AutoTriggerRPC] not initialized")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if InTargetPlayer == nil then
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
UnrealNetwork.CallUnrealRPC_Multicast(UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...)
|
||||||
|
else
|
||||||
|
local TargetController = STExtraGameplayStatics.GetFirstPlayerController(UGCGameSystem.GameState)
|
||||||
|
if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end
|
||||||
|
end
|
||||||
|
elseif type(InTargetPlayer) == "number" then
|
||||||
|
local TargetController = nil
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(InTargetPlayer)
|
||||||
|
else
|
||||||
|
TargetController = STExtraGameplayStatics.GetFirstPlayerController(UGCGameSystem.GameState)
|
||||||
|
end
|
||||||
|
|
||||||
|
if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end
|
||||||
|
elseif type(InTargetPlayer) == "table" and UGCGameSystem.IsServer() then
|
||||||
|
for _, PlayerKey in pairs(InTargetPlayer) do
|
||||||
|
local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey)
|
||||||
|
if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPCFunc(FuncName, ...) UGCSendRPCSystem[FuncName](...) end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.CheckUGCSendRPCSystem() return UE.IsValid(UGCSendRPCSystem.DelegationObj) end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------- Delegation Func -------------------------------------------
|
||||||
|
|
||||||
|
--- RPC委托调用事件
|
||||||
|
function UGCSendRPCSystem.RPCEvent(TargetPlayer, EventType, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_RPCEvent", TargetPlayer, EventType, ... ) end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPC_RPCEvent(EventType, ...) UGCEventSystem.SendEvent(EventType, ...) end
|
||||||
|
|
||||||
|
--- RPC委托触发Actor的函数
|
||||||
|
function UGCSendRPCSystem.ActorRPCNotify(TargetPlayer, TargetActor, FuncName, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_ActorRPCNotify", TargetPlayer, TargetActor, FuncName, ... ) end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPC_ActorRPCNotify(TargetActor, FuncName, ...)
|
||||||
|
if UE.IsValid(TargetActor) then
|
||||||
|
TargetActor[FuncName](TargetActor, ...)
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSendRPCSystem_RPC_ActorRPCNotify] Actor is nil. FuncName:%s", FuncName)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- RPC委托触发模式编辑器的事件
|
||||||
|
function UGCSendRPCSystem.PlayActionEvent(TargetPlayer, EventName, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_PlayActionEvent", TargetPlayer, EventName, ... ) end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPC_PlayActionEvent(EventName, ...) UGCGameSystem.SendModeCustomEvent(EventName, ...) end
|
||||||
|
|
||||||
|
--- 客户端显示隐藏UI
|
||||||
|
function UGCSendRPCSystem.ClientShowUI(TargetPlayer, UIType, bShow, NeedClosePeerPanel, ...)
|
||||||
|
if UGCGameSystem.IsServer() then
|
||||||
|
if bShow == nil then bShow = true end
|
||||||
|
if NeedClosePeerPanel == nil then NeedClosePeerPanel = false end
|
||||||
|
UGCSendRPCSystem.AutoTriggerRPC("RPC_ClientShowUI", TargetPlayer, UIType, bShow, NeedClosePeerPanel, ... )
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSendRPCSystem_ClientShowUI] 仅服务器调用生效 UIType:%s", tostring(UIType))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPC_ClientShowUI(UIType, bShow, NeedClosePeerPanel, ...)
|
||||||
|
if bShow then WidgetManager:ShowPanel(UIType, NeedClosePeerPanel, ...) else WidgetManager:ClosePanel(UIType) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.ExeStaticLogic(TargetPlayer, LogicType, FuncName, ...)
|
||||||
|
UGCSendRPCSystem.AutoTriggerRPC("RPC_ExeStaticLogic", TargetPlayer, LogicType, FuncName, ... )
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSendRPCSystem.RPC_ExeStaticLogic(LogicType, FuncName, ...)
|
||||||
|
if table.hasValue(LogicConfig.ELogicType, LogicType) then
|
||||||
|
UGCLogSystem.Log("[UGCSendRPCSystem_RPC_ExeStaticLogic] FuncName:%s", FuncName)
|
||||||
|
local LogicStatic = require(LogicConfig.RequireList[LogicType])
|
||||||
|
UGCLogSystem.LogTree("[UGCSendRPCSystem_RPC_ExeStaticLogic] ", LogicStatic)
|
||||||
|
LogicStatic[FuncName](...)
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSendRPCSystem_RPC_ExeStaticLogic] LogicConfig.ELogicType[%s] is nil ", tostring(LogicType))
|
||||||
|
end
|
||||||
|
end
|
760
FX_Preview/Script/Global/System/UGCSystemLibrary.lua
Normal file
760
FX_Preview/Script/Global/System/UGCSystemLibrary.lua
Normal file
@ -0,0 +1,760 @@
|
|||||||
|
UGCSystemLibrary = UGCSystemLibrary or {}
|
||||||
|
|
||||||
|
UGCSystemLibrary.IsServer = nil
|
||||||
|
-- 缓存的资产
|
||||||
|
UGCSystemLibrary.CacheAsset = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------ 获取本地信息 ------------------------------------------------
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetLocalPlayerController()
|
||||||
|
if not UE.IsValid(UGCSystemLibrary.LocalController) and UGCGameSystem.GameState then
|
||||||
|
UGCSystemLibrary.LocalController = STExtraGameplayStatics.GetFirstPlayerController(UGCGameSystem.GameState)
|
||||||
|
end
|
||||||
|
return UGCSystemLibrary.LocalController
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetLocalPlayerKey() return UGCSystemLibrary.GetLocalPlayerController().PlayerKey end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetLocalPlayerPawn() return UGCGameSystem.GetPlayerPawnByPlayerKey(UGCSystemLibrary.GetLocalPlayerKey()) end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetGameTime()
|
||||||
|
if UGCGameSystem.GameState then
|
||||||
|
return KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
|
||||||
|
else
|
||||||
|
return 0.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------- 获取本地信息 End ----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
--- 通过资产路径去获取场景唯一实例
|
||||||
|
---@param AssetPath string
|
||||||
|
function UGCSystemLibrary.GetUniqueInstanceFromPath(AssetPath)
|
||||||
|
local ObjClass = UE.LoadClass(AssetPath)
|
||||||
|
if UE.IsValid(ObjClass) then
|
||||||
|
local AllActor = ScriptGameplayStatics.GetActorsOfClass(UGCGameSystem.GameState, ObjClass)
|
||||||
|
for i, v in pairs(AllActor) do return v end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local RootPackagePath = UGCMapInfoLib.GetRootLongPackagePath()
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetFullPath(InPath)
|
||||||
|
if type(InPath) ~= "string" then return "" end
|
||||||
|
|
||||||
|
if #RootPackagePath > #InPath or string.sub(InPath, 1, #RootPackagePath) ~= RootPackagePath then
|
||||||
|
InPath = RootPackagePath..InPath
|
||||||
|
end
|
||||||
|
|
||||||
|
return InPath
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------ Load ------------------------------------------
|
||||||
|
--- {URL = Asset}
|
||||||
|
UGCSystemLibrary.DownloadImageAsset = {}
|
||||||
|
--- 下载图像
|
||||||
|
function UGCSystemLibrary.DownloadImage(URL, bSaveAsset, CallBackFunc, Obj)
|
||||||
|
if UE.IsValid(UGCSystemLibrary.DownloadImageAsset[URL]) then
|
||||||
|
if Obj then
|
||||||
|
CallBackFunc(Obj, UGCSystemLibrary.DownloadImageAsset[URL])
|
||||||
|
else
|
||||||
|
CallBackFunc(UGCSystemLibrary.DownloadImageAsset[URL])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
|
local ResHandle = AsyncTaskDownloadImage.DownloadImage(URL)
|
||||||
|
--ResHandle.OnSuccess:Add(CallBackFunc, Obj)
|
||||||
|
--ResHandle.OnFail:Add(CallBackFunc, Obj)
|
||||||
|
ResHandle.OnSuccess:Add(CallBackFunc)
|
||||||
|
ResHandle.OnFail:Add(CallBackFunc)
|
||||||
|
if bSaveAsset then
|
||||||
|
ResHandle.OnSuccess:Add(
|
||||||
|
function(Texture)
|
||||||
|
UGCSystemLibrary.DownloadImageAsset[URL] = Texture
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
UGCSystemLibrary.DownloadImageCache = {}
|
||||||
|
--- 下载图像至UImage
|
||||||
|
---@param Image UImage*
|
||||||
|
---@param URL string
|
||||||
|
---@param IsSave boolean
|
||||||
|
function UGCSystemLibrary.DownloadImageToUImage(Image, URL, IsSave)
|
||||||
|
if UE.IsValid(UGCSystemLibrary.DownloadImageCache[URL]) then
|
||||||
|
Image:SetBrushFromTextureDynamic(UGCSystemLibrary.DownloadImageCache[URL])
|
||||||
|
else
|
||||||
|
UGCSystemLibrary.DownloadImage(URL, true,
|
||||||
|
function(Texture)
|
||||||
|
if UE.IsValid(Texture) then
|
||||||
|
Image:SetBrushFromTextureDynamic(Texture)
|
||||||
|
if IsSave then
|
||||||
|
UGCSystemLibrary.DownloadImageCache[URL] = Texture
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_DownloadImageToUImage] Download Texture Failure. URL: %s", URL)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------- Load End ----------------------------------------
|
||||||
|
|
||||||
|
-- OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult
|
||||||
|
function UGCSystemLibrary.BindBeginOverlapFunc(CollisionComponent, Func, Obj) CollisionComponent.OnComponentBeginOverlap:Add(Func, Obj) end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.BindEndOverlapFunc(CollisionComponent, Func, Obj) CollisionComponent.OnComponentEndOverlap:Add(Func, Obj) end
|
||||||
|
|
||||||
|
|
||||||
|
function UGCSystemLibrary.formatTime(seconds, ShowMinutes, ShowHours, ShowRemainingSeconds)
|
||||||
|
if ShowMinutes == nil then ShowMinutes = false end
|
||||||
|
if ShowHours == nil then ShowHours = false end
|
||||||
|
if ShowRemainingSeconds == nil then ShowRemainingSeconds = false end
|
||||||
|
local hours = math.floor(seconds / 3600)
|
||||||
|
local minutes = math.floor((seconds - hours * 3600) / 60)
|
||||||
|
local remainingSeconds = seconds - hours * 3600 - minutes * 60
|
||||||
|
local ResTime = ""
|
||||||
|
ResTime = ResTime .. ((hours > 0 or ShowHours) and string.format("%02d:", hours) or "")
|
||||||
|
ResTime = ResTime .. ((minutes > 0 or hours > 0 or ShowHours or ShowMinutes) and string.format("%02d:", minutes) or "")
|
||||||
|
ResTime = ResTime .. (ShowRemainingSeconds and string.format("%02.3f", remainingSeconds) or string.format("%02.0f", remainingSeconds))
|
||||||
|
return ResTime
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param AssetPath:string
|
||||||
|
---@param CallBackFunc:fun(LoadObject:UObject,resID:int32)
|
||||||
|
---@param Obj:table CallBackFunc拥有者
|
||||||
|
---@param SaveAsset:bool 是否保存
|
||||||
|
function UGCSystemLibrary.AsyncLoadAsset(AssetPath, CallBackFunc, Obj, SaveAsset)
|
||||||
|
if not UE.IsValid(UGCSystemLibrary.CacheAsset[AssetPath]) then
|
||||||
|
local softObjPath = KismetSystemLibrary.MakeSoftObjectPath(AssetPath);
|
||||||
|
STExtraBlueprintFunctionLibrary.GetAssetByAssetReferenceAsync(softObjPath,
|
||||||
|
ObjectExtend.CreateDelegate(UGCGameSystem.GameState, function(LoadObject, resID)
|
||||||
|
if CallBackFunc then
|
||||||
|
if Obj ~= nil then CallBackFunc(Obj, LoadObject) else CallBackFunc(LoadObject) end
|
||||||
|
end
|
||||||
|
if UE.IsValid(LoadObject) and SaveAsset then UGCSystemLibrary.CacheAsset[AssetPath] = LoadObject end
|
||||||
|
end), true);
|
||||||
|
else
|
||||||
|
if CallBackFunc then
|
||||||
|
if Obj ~= nil then CallBackFunc(Obj, UGCSystemLibrary.CacheAsset[AssetPath]) else CallBackFunc(UGCSystemLibrary.CacheAsset[AssetPath]) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param AssetPath:string
|
||||||
|
---@param SaveAsset:bool 是否保存
|
||||||
|
function UGCSystemLibrary.LoadAsset(AssetPath, SaveAsset)
|
||||||
|
if SaveAsset == nil then SaveAsset = true end
|
||||||
|
if not UE.IsValid(UGCSystemLibrary.CacheAsset[AssetPath]) then
|
||||||
|
local TargetAsset = UE.LoadObject(AssetPath)
|
||||||
|
if SaveAsset and UE.IsValid(TargetAsset) then UGCSystemLibrary.CacheAsset[AssetPath] = TargetAsset end
|
||||||
|
return TargetAsset
|
||||||
|
else
|
||||||
|
return UGCSystemLibrary.CacheAsset[AssetPath]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 通过ItemID获取item类型
|
||||||
|
---@param ItemID int
|
||||||
|
---@return ItemTypeID int
|
||||||
|
function UGCSystemLibrary.GetItemTypeID(ItemID) return ItemID // 1000 end
|
||||||
|
|
||||||
|
--- 输入PlayerKey获取活着的玩家,若玩家已死亡或者不存在PlayerKey对应的Pawn时则返回nil
|
||||||
|
---@param PlayerKey uint
|
||||||
|
---@return Pawn
|
||||||
|
function UGCSystemLibrary.GetAlivePlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
return (UE.IsValid(PlayerPawn) and PlayerPawn:IsAlive()) and PlayerPawn or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- 最多循环加50次
|
||||||
|
UGCSystemLibrary.LoopAddItemCountMax = 50
|
||||||
|
UGCSystemLibrary.LoopAddItemHandle = nil
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo = {} -- PlayerKey = {ItemID, Count, LoopNum}
|
||||||
|
---添加道具
|
||||||
|
---生效范围:服务器
|
||||||
|
---@return IsSucceed bool
|
||||||
|
---@param PlayerPawn PlayerPawn* @玩家角色
|
||||||
|
---@param ItemID int @物品ID
|
||||||
|
---@param Count int @数量
|
||||||
|
function UGCSystemLibrary.AddItem(PlayerPawn, ItemID, Count)
|
||||||
|
|
||||||
|
if UE.IsValid(PlayerPawn) then
|
||||||
|
local bSucceed = UGCBackPackSystem.AddItem(PlayerPawn, ItemID, Count)
|
||||||
|
if not bSucceed then
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_AddItem]")
|
||||||
|
if UGCSystemLibrary.PlayerAddItemInfo[PlayerPawn.PlayerKey] == nil then
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo[PlayerPawn.PlayerKey] = {}
|
||||||
|
end
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo[PlayerPawn.PlayerKey][#UGCSystemLibrary.PlayerAddItemInfo[PlayerPawn.PlayerKey] + 1] = {ItemID = ItemID, Count = Count, LoopNum = 0}
|
||||||
|
if UGCSystemLibrary.LoopAddItemHandle == nil then
|
||||||
|
UGCSystemLibrary.LoopAddItemHandle = UGCEventSystem.SetTimerLoop(UGCGameSystem.GameState,
|
||||||
|
function()
|
||||||
|
local PlayerKeys = table.getKeys(UGCSystemLibrary.PlayerAddItemInfo)
|
||||||
|
for _, PlayerKey in PlayerKeys do
|
||||||
|
local ItemInfos = table.DeepCopy(UGCSystemLibrary.PlayerAddItemInfo[PlayerKey])
|
||||||
|
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
if UE.IsValid(TargetPawn) then
|
||||||
|
for i = #ItemInfos, 1, 1 do
|
||||||
|
bSucceed = UGCBackPackSystem.AddItem(TargetPawn, ItemInfos[i].ItemID, ItemInfos[i].Count)
|
||||||
|
-- 成功加入或者超过添加次数则移除
|
||||||
|
if bSucceed then
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo[PlayerKey][i] = nil
|
||||||
|
else
|
||||||
|
if ItemInfos[i].LoopNum >= UGCSystemLibrary.LoopAddItemCountMax then
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_AddItem] PlayerKey:%s,AddItem:%s Failue", tostring(PlayerKey), tostring(ItemInfos[i].ItemID))
|
||||||
|
else
|
||||||
|
ItemInfos[i].LoopNum = ItemInfos[i].LoopNum + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #UGCSystemLibrary.PlayerAddItemInfo[PlayerKey] == 0 then
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo[PlayerKey] = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCSystemLibrary.PlayerAddItemInfo[PlayerKey] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if table.getCount(UGCSystemLibrary.PlayerAddItemInfo) == 0 then
|
||||||
|
UGCEventSystem.StopTimer(UGCSystemLibrary.LoopAddItemHandle)
|
||||||
|
end
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_AddItem] Finish")
|
||||||
|
end,
|
||||||
|
0.1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_AddItem] PlayerPawn is nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 判断物体是否可以看到玩家
|
||||||
|
---@param ObjectContext 目标物体
|
||||||
|
---@param EyePos 物体开始检测的位置
|
||||||
|
---@param TargetPlayerPawn 目标玩家
|
||||||
|
---@param LineTraceChannels 检测的通道,默认为{ECollisionChannel.ECC_WorldStatic, ECollisionChannel.ECC_WorldDynamic, ECollisionChannel.ECC_Pawn}
|
||||||
|
function UGCSystemLibrary.CanSeePlayer(ObjectContext, EyePos, TargetPlayerPawn, LineTraceChannels)
|
||||||
|
if not (UE.IsValid(ObjectContext) and UE.IsValid(TargetPlayerPawn)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if LineTraceChannels == nil then
|
||||||
|
LineTraceChannels = {ECollisionChannel.ECC_WorldStatic, ECollisionChannel.ECC_WorldDynamic, ECollisionChannel.ECC_Pawn}
|
||||||
|
end
|
||||||
|
-- UGCLogSystem.Log("[UGCSystemLibrary_CanSeePlayer] TargetPlayerPawn:%s", KismetSystemLibrary.GetObjectName(TargetPlayerPawn))
|
||||||
|
--local SkeletonSocketNames = {"head", "spine_01", "hand_l", "hand_r", "foot_r", "foot_l"}
|
||||||
|
local PawnPos = TargetPlayerPawn:K2_GetActorLocation()
|
||||||
|
local UpPawnPos = table.DeepCopy(PawnPos)
|
||||||
|
local DownPawnPos = table.DeepCopy(PawnPos)
|
||||||
|
UpPawnPos.Z = UpPawnPos.Z + 80
|
||||||
|
DownPawnPos.Z = DownPawnPos.Z - 80
|
||||||
|
--for i, SocketName in pairs(SkeletonSocketNames) do
|
||||||
|
for i, EndPos in pairs({UpPawnPos, PawnPos, DownPawnPos}) do
|
||||||
|
-- local BornSocketPos = TargetPlayerPawn.Mesh:GetSocketLocation(SocketName)
|
||||||
|
--if BornSocketPos then
|
||||||
|
---@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 bSucceed, HitResult = KismetSystemLibrary.LineTraceSingleForObjects(ObjectContext, EyePos, EndPos, LineTraceChannels, false, {ObjectContext, })
|
||||||
|
if bSucceed then
|
||||||
|
local HitActor = HitResult.Actor:Get()
|
||||||
|
if HitActor == TargetPlayerPawn then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_CanSeePlayer]HitActorName:%s", KismetSystemLibrary.GetObjectName(HitActor))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--else
|
||||||
|
-- UGCLogSystem.LogError("[UGCSystemLibrary_CanSeePlayer] BornSocketPos is nil")
|
||||||
|
--end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 通过类名销毁物体
|
||||||
|
--- 拾取物"PickUpWrapperActor"
|
||||||
|
--- 死亡盒子"PlayerTombBox"
|
||||||
|
--- 已投出的投掷物 "EliteProjectile"
|
||||||
|
function UGCSystemLibrary.RemoveActorFromClassName(ClassName)
|
||||||
|
local PlayerTombBoxClass = ScriptGameplayStatics.FindClass(ClassName);
|
||||||
|
if UE.IsValid(PlayerTombBoxClass) then
|
||||||
|
local PlayerTombBoxs = ScriptGameplayStatics.GetActorsOfClass(UGCGameSystem.GameState, PlayerTombBoxClass, {})
|
||||||
|
for i, PlayerTombBox in ipairs(PlayerTombBoxs) do
|
||||||
|
if PlayerTombBox ~= nil then
|
||||||
|
PlayerTombBox:K2_DestroyActor();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_RemoveActorFromClassName] %sClass is not Valid", tostring(ClassName))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 清除PickUpActor 忽略传入的ItemID
|
||||||
|
function UGCSystemLibrary.ClearPickUpActor(IgnoreItemIDs)
|
||||||
|
if IgnoreItemIDs == nil then
|
||||||
|
IgnoreItemIDs = {}
|
||||||
|
end
|
||||||
|
local PickUpActorClass = ScriptGameplayStatics.FindClass("PickUpWrapperActor");
|
||||||
|
if UE.IsValid(PickUpActorClass) then
|
||||||
|
local PickUpActors = ScriptGameplayStatics.GetActorsOfClass(UGCGameSystem.GameState, PickUpActorClass, {})
|
||||||
|
--
|
||||||
|
for i, PickUpActor in ipairs(PickUpActors) do
|
||||||
|
if PickUpActor ~= nil then
|
||||||
|
local ItemID = PickUpActor.DefineID.TypeSpecificID
|
||||||
|
-- UGCLogSystem.Log("[UGCSystemLibrary_ClearPickUpActor]ItemID:%s", tostring(ItemID))
|
||||||
|
if not table.hasValue(IgnoreItemIDs, ItemID) then
|
||||||
|
PickUpActor:K2_DestroyActor();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_ClearPickUpActor] PickUpWrapperActor Class is not Valid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [PlayerKey] = {Handle, RespawnGameTime}
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo = {}
|
||||||
|
-- 重置玩家
|
||||||
|
function UGCSystemLibrary.RespawnPlayer(PlayerKey, Time)
|
||||||
|
-- 不进行瞬时重生,防止同一帧重复调用
|
||||||
|
if Time == nil then Time = 0.1 end
|
||||||
|
local NowTime = UGCSystemLibrary.GetGameTime()
|
||||||
|
local RespawnHandleInfo = UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey]
|
||||||
|
if RespawnHandleInfo then
|
||||||
|
-- 若多次调用则仅采用长的复活时间
|
||||||
|
if Time + NowTime <= RespawnHandleInfo.RespawnGameTime then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 删除之前的复活Handle
|
||||||
|
if UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] then
|
||||||
|
UGCEventSystem.StopTimer(UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].Handle)
|
||||||
|
end
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] = {}
|
||||||
|
-- 构建新的符合Handle
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].Handle = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] = nil
|
||||||
|
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
if UE.IsValid(PlayerPawn) then
|
||||||
|
PlayerPawn:K2_DestroyActor()
|
||||||
|
end
|
||||||
|
UGCGameSystem.RespawnPlayer(PlayerKey)
|
||||||
|
end, Time)
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].RespawnGameTime = Time + NowTime
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.RespawnPlayer_V2(PlayerKey, Time)
|
||||||
|
|
||||||
|
-- 不进行瞬时重生,防止同一帧重复调用
|
||||||
|
if Time == nil then Time = 0.1 end
|
||||||
|
local NowTime = UGCSystemLibrary.GetGameTime()
|
||||||
|
local RespawnHandleInfo = UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey]
|
||||||
|
if RespawnHandleInfo then
|
||||||
|
-- 若多次调用则仅采用长的复活时间
|
||||||
|
if Time + NowTime <= RespawnHandleInfo.RespawnGameTime then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 删除之前的复活Handle
|
||||||
|
if UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] then
|
||||||
|
UGCEventSystem.StopTimer(UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].Handle)
|
||||||
|
end
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] = {}
|
||||||
|
-- 构建新的符合Handle
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].Handle = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey] = nil
|
||||||
|
local PlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
|
||||||
|
if UE.IsValid(PlayerPawn) then
|
||||||
|
PlayerPawn:K2_DestroyActor()
|
||||||
|
end
|
||||||
|
local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey)
|
||||||
|
if UE.IsValid(PC) then
|
||||||
|
-- UGCGameSystem.GameMode:RestartPlayer(PC)
|
||||||
|
local DefaultPawnClass = UGCGameSystem.GameMode:GetDefaultPawnClassForController(PC)
|
||||||
|
if DefaultPawnClass then
|
||||||
|
local Pawn = UGCGameSystem.SpawnActor(UGCGameSystem.GameState, DefaultPawnClass, VectorHelper.VectorZero(), VectorHelper.RotZero(), VectorHelper.ScaleOne())
|
||||||
|
PC:Possess(Pawn)
|
||||||
|
-- 将玩家重置到出生点
|
||||||
|
UGCEventSystem.SendEvent(EventEnum.ResetPlayerTransformToPlayerStart, PC, Pawn)
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_RespawnPlayer_V2] Finish")
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_RespawnPlayer_V2]DefaultPawnClass is nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_RespawnPlayer_V2] [%s]PC is nil", tostring(PlayerKey))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end, Time)
|
||||||
|
UGCSystemLibrary.RespawnPlayerHandlesInfo[PlayerKey].RespawnGameTime = Time + NowTime
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 设置pawn是否可移动
|
||||||
|
function UGCSystemLibrary.SetPlayerPawnMovable(InPawn, IsMovable)
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Move , not IsMovable);
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Shoveling , not IsMovable);
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Jump , not IsMovable);
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.GunFire , not IsMovable);
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.HoldGrenade , not IsMovable);
|
||||||
|
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.MeleeAttack , not IsMovable);
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.SetAllPawnMovable(IsMovable)
|
||||||
|
local AllPawn = UGCGameSystem.GetAllPlayerPawn()
|
||||||
|
for i, v in pairs(AllPawn) do
|
||||||
|
UGCSystemLibrary.SetPlayerPawnMovable(v, IsMovable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 设置玩家是否可移动
|
||||||
|
function UGCSystemLibrary.SetPlayerIsMovable(PlayerController, IsMovable)
|
||||||
|
if UE.IsValid(PlayerController) then
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_SetPlayerIsMovable] PlayerController:%s", tostring(PlayerController.PlayerKey))
|
||||||
|
if IsMovable then
|
||||||
|
-- 关闭电影模式,启用玩家移动
|
||||||
|
PlayerController:SetCinematicMode(false, false, false, true, false)
|
||||||
|
else
|
||||||
|
-- 开启电影模式,禁止玩家移动
|
||||||
|
PlayerController:SetCinematicMode(true, false, false, true, false)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
UGCLogSystem.LogError("[UGCSystemLibrary_SetPlayerIsMovable] PlayerController Is Not Valid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Server
|
||||||
|
--- 设置所有玩家是否可移动
|
||||||
|
function UGCSystemLibrary.SetAllPlayerIsMovable(IsMovable)
|
||||||
|
local TempPlayerControllers = UGCGameSystem.GetAllPlayerController(true)
|
||||||
|
for _, PC in pairs(TempPlayerControllers) do
|
||||||
|
UGCSystemLibrary.SetPlayerIsMovable(PC, IsMovable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------- 准备状态 ---------------------------------------------
|
||||||
|
--[[
|
||||||
|
需要在Pawn内的ReceivePossessed函数中加入
|
||||||
|
function UGCPlayerPawn:ReceivePossessed(NewController)
|
||||||
|
if UGCSystemLibrary.GetIsPreparationState() then
|
||||||
|
UGCSystemLibrary.SetPlayerPawnMovable(self, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
-- 准备时间
|
||||||
|
UGCSystemLibrary.PreparationTime = 0;
|
||||||
|
-- 是否为准备阶段
|
||||||
|
UGCSystemLibrary.IsPreparationState = false;
|
||||||
|
--- Server
|
||||||
|
--- 进入准备状态
|
||||||
|
function UGCSystemLibrary.EnterPreparationState()
|
||||||
|
UGCSystemLibrary.IsPreparationState = true
|
||||||
|
if UGCEventSystem.PreparationStateHandle then
|
||||||
|
UGCEventSystem.StopTimer(UGCEventSystem.PreparationStateHandle)
|
||||||
|
end
|
||||||
|
UGCEventSystem.PreparationStateHandle = UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||||||
|
UGCSystemLibrary.SetAllPawnMovable(true)
|
||||||
|
UGCSystemLibrary.IsPreparationState = false
|
||||||
|
UGCEventSystem.PreparationStateHandle = nil
|
||||||
|
end, UGCSystemLibrary.PreparationTime)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.GetIsPreparationState()
|
||||||
|
return UGCSystemLibrary.IsPreparationState
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.SetPreparationTime(InPreparationTime)
|
||||||
|
if InPreparationTime >= 0 then
|
||||||
|
UGCSystemLibrary.PreparationTime = InPreparationTime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------- 准备状态 End -------------------------------------------
|
||||||
|
|
||||||
|
--- 获取所有的PlayerKey
|
||||||
|
function UGCSystemLibrary.GetAllPlayerKeys()
|
||||||
|
local AllPC = UGCGameSystem.GetAllPlayerController()
|
||||||
|
local Res = {}
|
||||||
|
for i, v in pairs(AllPC) do
|
||||||
|
Res[#Res + 1] = v.PlayerKey
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 给玩家的所有武器补满当前弹夹子弹
|
||||||
|
function UGCSystemLibrary.PlayerFullBullet(InPlayerKey)
|
||||||
|
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey)
|
||||||
|
if UE.IsValid(TargetPawn) then
|
||||||
|
--补满子弹
|
||||||
|
TargetPawn:SetAllWeaponBulletNumToMaxOnServer(true, false)
|
||||||
|
for i, v in pairs(ShootWeaponEnums) do
|
||||||
|
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(TargetPawn, v)
|
||||||
|
if UE.IsValid(Weapon) then
|
||||||
|
UGCGunSystem.EnableClipInfiniteBullets(Weapon, true)
|
||||||
|
local MaxBulletNumInOneClip = UGCGunSystem.GetMaxBulletNumInOneClip(Weapon)
|
||||||
|
Weapon:SetCurrentBulletNumInClipOnServer(MaxBulletNumInOneClip, true)
|
||||||
|
-- 玩家离开换弹状态
|
||||||
|
if UE.IsValid(TargetPawn) then
|
||||||
|
UGCPawnSystem.LeavePawnState(TargetPawn, EPawnState.Roload)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 重置和平里的击杀和助攻数
|
||||||
|
function UGCSystemLibrary.ResetAllPlayerKillsAndAssists()
|
||||||
|
local AllPS = UGCGameSystem.GetAllPlayerState()
|
||||||
|
for i, PS in pairs(AllPS) do
|
||||||
|
PS.Kills = 0
|
||||||
|
PS.Assists = 0
|
||||||
|
PS.KillPlayerNum = 0
|
||||||
|
DOREPONCE(PS,"Kills")
|
||||||
|
DOREPONCE(PS,"Assists")
|
||||||
|
DOREPONCE(PS,"KillPlayerNum")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 获取当天为一年中的第几天
|
||||||
|
function UGCSystemLibrary.GetDayOfYear()
|
||||||
|
local now = os.time()
|
||||||
|
local year = os.date("*t", now).year
|
||||||
|
local startOfYear = os.time{year = year, month = 1, day = 1}
|
||||||
|
local days = os.difftime(now, startOfYear) / (24 * 60 * 60)
|
||||||
|
return math.floor(days) + 1 -- 加1是因为Lua里月份和天数是从1开始计数的
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 获取现实时间秒
|
||||||
|
function UGCSystemLibrary.GatRealTimeSeconds()
|
||||||
|
return os.time()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- 获取UTF-8字符串的长度
|
||||||
|
function UGCSystemLibrary.utf8len(s)
|
||||||
|
local len = 0
|
||||||
|
local i = 1
|
||||||
|
local c = string.byte(s, i)
|
||||||
|
while c do
|
||||||
|
if c > 0 and c <= 127 then
|
||||||
|
i = i + 1
|
||||||
|
elseif c >= 194 and c <= 223 then
|
||||||
|
i = i + 2
|
||||||
|
elseif c >= 224 and c <= 239 then
|
||||||
|
i = i + 3
|
||||||
|
elseif c >= 240 and c <= 244 then
|
||||||
|
i = i + 4
|
||||||
|
else
|
||||||
|
return nil -- invalid UTF-8
|
||||||
|
end
|
||||||
|
len = len + 1
|
||||||
|
c = string.byte(s, i)
|
||||||
|
end
|
||||||
|
return len
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 裁剪UTF-8字符串
|
||||||
|
function UGCSystemLibrary.utf8sub(s, startChar, numChars)
|
||||||
|
local startIndex = 1
|
||||||
|
while startChar > 1 do
|
||||||
|
local c = string.byte(s, startIndex)
|
||||||
|
if not c then return "" end
|
||||||
|
if c > 0 and c <= 127 then
|
||||||
|
startIndex = startIndex + 1
|
||||||
|
elseif c >= 194 and c <= 223 then
|
||||||
|
startIndex = startIndex + 2
|
||||||
|
elseif c >= 224 and c <= 239 then
|
||||||
|
startIndex = startIndex + 3
|
||||||
|
elseif c >= 240 and c <= 244 then
|
||||||
|
startIndex = startIndex + 4
|
||||||
|
else
|
||||||
|
return "" -- invalid UTF-8
|
||||||
|
end
|
||||||
|
startChar = startChar - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local currentIndex = startIndex
|
||||||
|
while numChars > 0 and currentIndex <= #s do
|
||||||
|
local c = string.byte(s, currentIndex)
|
||||||
|
if not c then break end
|
||||||
|
if c > 0 and c <= 127 then
|
||||||
|
currentIndex = currentIndex + 1
|
||||||
|
elseif c >= 194 and c <= 223 then
|
||||||
|
currentIndex = currentIndex + 2
|
||||||
|
elseif c >= 224 and c <= 239 then
|
||||||
|
currentIndex = currentIndex + 3
|
||||||
|
elseif c >= 240 and c <= 244 then
|
||||||
|
currentIndex = currentIndex + 4
|
||||||
|
else
|
||||||
|
break -- invalid UTF-8
|
||||||
|
end
|
||||||
|
numChars = numChars - 1
|
||||||
|
end
|
||||||
|
return s:sub(startIndex, currentIndex - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function UGCSystemLibrary.remove_punctuation(s)
|
||||||
|
-- 定义要移除的标点符号
|
||||||
|
local punctuation = {
|
||||||
|
["。"] = true, [","] = true, ["!"] = true, ["?"] = true,
|
||||||
|
["."] = true, [","] = true, ["!"] = true, ["?"] = true,
|
||||||
|
[";"] = true, [":"] = true, [";"] = true, [":"] = true,
|
||||||
|
["、"] = true, ["("] = true, [")"] = true, ["("] = true, [")"] = true,
|
||||||
|
["【"] = true, ["】"] = true, ["["] = true, ["]"] = true,
|
||||||
|
["“"] = true, ["”"] = true, ["\""] = true, ["'"] = true,
|
||||||
|
["\n"] = true, ["\r"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
local i = 1
|
||||||
|
local c = string.byte(s, i)
|
||||||
|
while c do
|
||||||
|
local char_len = 1
|
||||||
|
if c > 0 and c <= 127 then
|
||||||
|
char_len = 1
|
||||||
|
elseif c >= 194 and c <= 223 then
|
||||||
|
char_len = 2
|
||||||
|
elseif c >= 224 and c <= 239 then
|
||||||
|
char_len = 3
|
||||||
|
elseif c >= 240 and c <= 244 then
|
||||||
|
char_len = 4
|
||||||
|
else
|
||||||
|
return "" -- invalid UTF-8
|
||||||
|
end
|
||||||
|
|
||||||
|
local char = s:sub(i, i + char_len - 1)
|
||||||
|
print(char .. "--")
|
||||||
|
if not punctuation[char] then
|
||||||
|
table.insert(result, char)
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i + char_len
|
||||||
|
c = string.byte(s, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 移除标点符号
|
||||||
|
function UGCSystemLibrary.remove_character(s, char_to_remove)
|
||||||
|
local result = {}
|
||||||
|
local i = 1
|
||||||
|
local c = string.byte(s, i)
|
||||||
|
while c do
|
||||||
|
local char_len = 1
|
||||||
|
if c > 0 and c <= 127 then
|
||||||
|
char_len = 1
|
||||||
|
elseif c >= 194 and c <= 223 then
|
||||||
|
char_len = 2
|
||||||
|
elseif c >= 224 and c <= 239 then
|
||||||
|
char_len = 3
|
||||||
|
elseif c >= 240 and c <= 244 then
|
||||||
|
char_len = 4
|
||||||
|
else
|
||||||
|
return "" -- invalid UTF-8
|
||||||
|
end
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_remove_character] c:%s", c)
|
||||||
|
|
||||||
|
local char = s:sub(i, i + char_len - 1)
|
||||||
|
if char ~= char_to_remove then
|
||||||
|
UGCLogSystem.Log("[UGCSystemLibrary_remove_character] Add")
|
||||||
|
table.insert(result, char)
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i + char_len
|
||||||
|
c = string.byte(s, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 概率函数,输入为概率列表,输出为依据概率随机出来的索引
|
||||||
|
function UGCSystemLibrary.RandomIndex(probabilities)
|
||||||
|
local sum = 0
|
||||||
|
local cumulative = {}
|
||||||
|
|
||||||
|
-- 计算概率总和,并构建累积概率列表
|
||||||
|
for i, prob in ipairs(probabilities) do
|
||||||
|
sum = sum + prob
|
||||||
|
cumulative[i] = sum
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 生成一个0到sum之间的随机数
|
||||||
|
local randomValue = math.random() * sum
|
||||||
|
|
||||||
|
-- 根据随机数选择对应的索引
|
||||||
|
for i, cumProb in ipairs(cumulative) do
|
||||||
|
if randomValue <= cumProb then
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- 获取其他队伍的ID
|
||||||
|
---@param TeamID uint 忽略的队伍ID
|
||||||
|
---@return TeamIDs table 其他队伍ID
|
||||||
|
function UGCTeamSystem.GetOtherTeamIDs(TeamID)
|
||||||
|
local TeamIDs = UGCTeamSystem.GetTeamIDs()
|
||||||
|
local Res = {}
|
||||||
|
for i, v in pairs(TeamIDs) do
|
||||||
|
if v ~= TeamID then
|
||||||
|
Res[#Res + 1] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 获取其他队伍的玩家
|
||||||
|
---@param TeamID uint 忽略的队伍ID
|
||||||
|
---@return PlayerKeys table 其他玩家PlayerKey
|
||||||
|
function UGCTeamSystem.GetOtherTeamPlayerKeys(TeamID)
|
||||||
|
local OtherTeamIDs = UGCTeamSystem.GetOtherTeamIDs(TeamID)
|
||||||
|
local Res = {}
|
||||||
|
for i, v in pairs(OtherTeamIDs) do
|
||||||
|
local OtherPlayerKeys = UGCTeamSystem.GetPlayerKeysByTeamID(v)
|
||||||
|
for _, PlayerKey in pairs(OtherPlayerKeys) do
|
||||||
|
Res[#Res + 1] = PlayerKey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 获取队伍成员PlayerKey
|
||||||
|
---@return PlayerKeys table 队伍玩家PlayerKey
|
||||||
|
function UGCTeamSystem.GetTeammates(PlayerKey)
|
||||||
|
local Res = {}
|
||||||
|
local TeamID = UGCPlayerStateSystem.GetTeamID(PlayerKey)
|
||||||
|
UGCLogSystem.Log("[UGCTeamSystem_GetTeammates] TeamID:%s", tostring(TeamID))
|
||||||
|
local Teammates = UGCTeamSystem.GetPlayerKeysByTeamID(TeamID)
|
||||||
|
for i, v in pairs(Teammates) do
|
||||||
|
Res[#Res + 1] = v
|
||||||
|
end
|
||||||
|
return Res
|
||||||
|
end
|
23
FX_Preview/Script/gamemode/Action_PlayerDead.lua
Normal file
23
FX_Preview/Script/gamemode/Action_PlayerDead.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
local Action_PlayerDead = {
|
||||||
|
-- 可配置参数定义,参数将显示在Action配置面板
|
||||||
|
-- 例:
|
||||||
|
-- MyIntParameter = 0
|
||||||
|
KillerPlayerKey = 0;
|
||||||
|
DeadPlayerKey = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-- 触发器激活时,将执行Action的Execute
|
||||||
|
function Action_PlayerDead:Execute(...)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- 需要勾选Action的EnableTick,才会执行Update
|
||||||
|
-- 触发器激活后,将在每个tick执行Action的Update,直到self.bEnableActionTick为false
|
||||||
|
function Action_PlayerDead:Update(DeltaSeconds)
|
||||||
|
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
return Action_PlayerDead
|
23
FX_Preview/Script/gamemode/Action_PlayerLeave.lua
Normal file
23
FX_Preview/Script/gamemode/Action_PlayerLeave.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
local Action_PlayerLeave = {
|
||||||
|
-- 可配置参数定义,参数将显示在Action配置面板
|
||||||
|
-- 例:
|
||||||
|
-- MyIntParameter = 0
|
||||||
|
PlayerKey = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-- 触发器激活时,将执行Action的Execute
|
||||||
|
function Action_PlayerLeave:Execute(...)
|
||||||
|
ugcprint(string.format("[Action_PlayerLeave] Start settlement %d", self.PlayerKey));
|
||||||
|
UGCGameSystem.SendPlayerSettlement(self.PlayerKey);
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
-- 需要勾选Action的EnableTick,才会执行Update
|
||||||
|
-- 触发器激活后,将在每个tick执行Action的Update,直到self.bEnableActionTick为false
|
||||||
|
function Action_PlayerLeave:Update(DeltaSeconds)
|
||||||
|
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
|
return Action_PlayerLeave
|
16
FX_Preview/Script/gamemode/Action_SendEvent.lua
Normal file
16
FX_Preview/Script/gamemode/Action_SendEvent.lua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
local Action_SendEvent =
|
||||||
|
{
|
||||||
|
SendEventName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function Action_SendEvent:Execute()
|
||||||
|
print(string.format("Action_SendEvent:Execute SendEventName[%s]", self.SendEventName));
|
||||||
|
|
||||||
|
LuaQuickFireEvent(self.SendEventName, self);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return Action_SendEvent
|
0
FX_Preview/Script/gamemode/readme.txt
Normal file
0
FX_Preview/Script/gamemode/readme.txt
Normal file
90
FX_Preview/Script/luahelper.json
Normal file
90
FX_Preview/Script/luahelper.json
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"BaseDir":"./",
|
||||||
|
"ShowWarnFlag": 1,
|
||||||
|
"ShareSymbolsFlag": 1,
|
||||||
|
"ReferMatchPathFlag": 0,
|
||||||
|
"GvalTipFlag": 1,
|
||||||
|
"IgnoreFileNameVarFlag": 1,
|
||||||
|
"ProjectFiles":[
|
||||||
|
],
|
||||||
|
"IgnoreModules":["hive", "import",
|
||||||
|
"TssManager", "GameFrontendHUD", "Vector", "Rotator", "bp_lobby", "Vector2D", "bp_global", "bp_authorization", "LobbyENV",
|
||||||
|
"InGameUIManager", "DSHUD", "Puffer", "BP_Platform", "LobbyG", "BP_MAP_ClubLogo", "BP_ARRAY_ClubLogo", "Instance",
|
||||||
|
"LinearColor", "LuaDebugHelper", "ScriptHelperServer", "ScriptHelperServer_WorldParallelism", "VSCodeLuaDebug",
|
||||||
|
"UE", "UAEUserWidget", "LogE", "Tss", "ObjectExtend" ,"UE_BUILD_SHIPPING","ImageManipulator","ImageDownloaderV2","ImageDownloaderV3","ImageEx","SlateBrush",
|
||||||
|
"DateTime","Timespan","KeepGameLiveInterface","Dolphin","BP_STRUCT_TeamUpFriendInfo","ComplaintFeedbackSummaryNotice","EncryptPakTest","DoReloadLua","LuaMemoryUI","BP_ARRAY_DynamicLevels","BP_ARRAY_lbsranktypetable",
|
||||||
|
"pakwhitelist","ConfigDownloader","extrapaklistneedmount","BP_ARRAY_Paradise","VideoConfigDownloader","TextBlock"
|
||||||
|
],
|
||||||
|
"IgnoreFileVars": [
|
||||||
|
{
|
||||||
|
"File": "client_entry.lua",
|
||||||
|
"Vars": ["UE_BUILD_SHIPPING", "Tss"]
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"File": "util.lua",
|
||||||
|
"Vars": ["newestpakslist"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"IgnoreReadFiles": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"IgnoreErrorTypes": [
|
||||||
|
4,6,18
|
||||||
|
],
|
||||||
|
"IgnoreFileOrFloder": [
|
||||||
|
"lobby/on.*lua",
|
||||||
|
"tests/",
|
||||||
|
"robot/",
|
||||||
|
"coverage/"
|
||||||
|
],
|
||||||
|
"IgnoreFileErr": [
|
||||||
|
"lobby/gm1.lua",
|
||||||
|
"common/test.lua",
|
||||||
|
"Replay/Test.lua",
|
||||||
|
"test/luaunit.lua",
|
||||||
|
"improved_ingameui",
|
||||||
|
"ingame",
|
||||||
|
"Server",
|
||||||
|
"vsCodeDebugger",
|
||||||
|
"delete_lua"
|
||||||
|
],
|
||||||
|
"IgnoreFileErrTypes": [
|
||||||
|
{
|
||||||
|
"File": "gc_control.lua",
|
||||||
|
"Types": [3]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"File": "sandbox.lua",
|
||||||
|
"Types": [3]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ProtocolVars": [
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
"AnntotateSets": [
|
||||||
|
{
|
||||||
|
"FuncName": "GetUIObject",
|
||||||
|
"ParamIndex": 2,
|
||||||
|
"SplitFlag": 0,
|
||||||
|
"PrefixStr": "",
|
||||||
|
"SuffixStr": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FuncName": "KismetLibrary.New",
|
||||||
|
"ParamIndex": 1,
|
||||||
|
"SplitFlag": 1,
|
||||||
|
"PrefixStr": "",
|
||||||
|
"PrefixStrList": ["U", "A", ""],
|
||||||
|
"SuffixStr": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FuncName": "CreateUIWidget",
|
||||||
|
"ParamIndex": 2,
|
||||||
|
"SplitFlag": 1,
|
||||||
|
"PrefixStr": "",
|
||||||
|
"SuffixStr": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
FX_Preview/UGCmap.umap
Normal file
BIN
FX_Preview/UGCmap.umap
Normal file
Binary file not shown.
4
FX_Preview/WhiteList.ini
Normal file
4
FX_Preview/WhiteList.ini
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[WhiteList]
|
||||||
|
WhiteListUsrIdNum=0
|
||||||
|
|
||||||
|
|
11
FX_Preview/workspace.code-workspace
Normal file
11
FX_Preview/workspace.code-workspace
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "Script"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "..\\..\\Content\\LuaHelper"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user