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

404 lines
17 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
--- 下载图像至UImage
---@param Image UImage*
---@param URL string
function UGCSystemLibrary.DownloadImageToUImage(Image, URL)
UGCSystemLibrary.DownloadImage(URL, true,
function(Texture)
if UE.IsValid(Texture) then
Image:SetBrushFromTextureDynamic(Texture)
else
UGCLogSystem.LogError("[UGCSystemLibrary_DownloadImageToUImage] Download Texture Failure. URL: %s", URL)
end
end
)
end
---------------------------------------- Load End ----------------------------------------
--- Server
--- 设置玩家是否可移动
function UGCSystemLibrary.SetPlayerIsMoveable(PlayerController, IsMoveable)
if UE.IsValid(PlayerController) then
UGCLogSystem.Log("[UGCSystemLibrary_SetPlayerIsMoveable] PlayerController:%s", tostring(PlayerController.PlayerKey))
if IsMoveable then
-- 关闭电影模式,启用玩家移动
PlayerController:SetCinematicMode(false, false, false, true, false)
--PlayerController:SetIgnoreMoveInput(false)
else
-- 开启电影模式,禁止玩家移动
PlayerController:SetCinematicMode(true, false, false, true, false)
--PlayerController:SetIgnoreMoveInput(true)
end
else
UGCLogSystem.LogError("[UGCSystemLibrary_SetPlayerIsMoveable] PlayerController Is Not Valid")
end
end
--- Server
--- 设置所有玩家是否可移动
function UGCSystemLibrary.SetAllPlayerIsMoveable(IsMoveable)
local TempPlayerControllers = UGCGameSystem.GetAllPlayerController(true)
for _, PC in pairs(TempPlayerControllers) do
UGCSystemLibrary.SetPlayerIsMoveable(PC, IsMoveable)
end
end
--- Server
--- 设置pawn是否可移动
function UGCSystemLibrary.SetPlayerPawnMoveable(InPawn, IsMoveable)
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Move, not IsMoveable);
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Shoveling, not IsMoveable);
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.Jump, not IsMoveable);
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.GunFire, not IsMoveable);
UGCPawnSystem.DisabledPawnState(InPawn, EPawnState.HoldGrenade, not IsMoveable);
-- UGCSystemLibrary.SetPlayerPawnMoveable(self, IsMoveable)
end
--- 补充满玩家的当前所有武器的子弹
function UGCSystemLibrary.FullAllWeaponBullet(PlayerPawn)
if UE.IsValid(PlayerPawn) then
for i, v in pairs(ShootWeaponEnums) do
local Weapon = UGCWeaponManagerSystem.GetWeaponBySlot(PlayerPawn, v)
if UE.IsValid(Weapon) then
UGCGunSystem.EnableClipInfiniteBullets(Weapon, true)
local MaxBulletNumInOneClip = UGCGunSystem.GetMaxBulletNumInOneClip(Weapon)
Weapon:SetCurrentBulletNumInClipOnServer(MaxBulletNumInOneClip, true)
end
end
end
end
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
--- Server执行设置第一人称FPP模式
function UGCSystemLibrary.SetFPPMode()
UGCGameSystem.GameMode.IsGameModeFpp = 1
UGCGameSystem.GameState.IsFPPGameMode = true
end
--- 通过类名销毁物体
--- 拾取物"PickUpWrapperActor"
--- 死亡盒子"PlayerTombBox"
function UGCSystemLibrary.RemoveActorFromClassName(ClassName)
local PlayerTombBoxClass = ScriptGameplayStatics.FindClass(ClassName);
if UE.IsValid(PlayerTombBoxClass) then
UGCLogSystem.Log("[UGCSystemLibrary_RemoveActorFromClassName] %sClass is Valid", tostring(ClassName))
-- local PlayerTombBoxs = GameplayStatics.GetAllActorsOfClass(self, PlayerTombBoxClass, {});
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
--- 获取其他队伍的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