369 lines
15 KiB
Lua
Raw Normal View History

2025-01-04 23:00:19 +08:00
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 ----------------------------------------
-- 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"
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
--- 获取其他队伍的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