320 lines
9.7 KiB
Lua
320 lines
9.7 KiB
Lua
|
---@type table<string, UClass>
|
||
|
---@private
|
||
|
UE.CachedClasses = {};
|
||
|
|
||
|
--- 组件位置
|
||
|
UE.ComponentPath = {
|
||
|
Camera = "/Script/Engine.CameraComponent",
|
||
|
SpringArm = "/Script/Engine.SpringArmComponent",
|
||
|
}
|
||
|
|
||
|
---@param InInfo PlayerAccountInfo
|
||
|
---@return PlayerAccountInfo
|
||
|
function UE.HandleAccountInfo(InInfo)
|
||
|
return {
|
||
|
UID = InInfo.UID,
|
||
|
PlayerName = InInfo.PlayerName,
|
||
|
TeamID = InInfo.TeamID,
|
||
|
Gender = InInfo.Gender,
|
||
|
PlatformGender = InInfo.PlatformGender,
|
||
|
PlayerLevel = InInfo.PlayerLevel,
|
||
|
SegmentLevel = InInfo.SegmentLevel,
|
||
|
IconURL = InInfo.IconURL,
|
||
|
};
|
||
|
end
|
||
|
|
||
|
---@return table
|
||
|
function UE.InitArchiveData()
|
||
|
return {
|
||
|
GameTimes = 0, -- 游戏游玩次数
|
||
|
}
|
||
|
end
|
||
|
|
||
|
---@param InClass UClass<AActor>
|
||
|
---@param InTable table<int32, AActor> 获得的
|
||
|
---@param InFunc fun(InIndex:int32, InActor:AActor): int32|bool|string|any
|
||
|
---@return table<int32, AActor>
|
||
|
function UE.FindActorsByClass(InClass, InTable, InFunc)
|
||
|
if InTable == nil then InTable = {}; end
|
||
|
local AllActors = {};
|
||
|
GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, InClass, AllActors);
|
||
|
for i, v in pairs(AllActors) do
|
||
|
if InFunc ~= nil then
|
||
|
local val = InFunc(i, v)
|
||
|
if val then
|
||
|
if type(val) == 'boolean' then
|
||
|
table.insert(InTable, v);
|
||
|
else
|
||
|
InTable[val] = v;
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
table.insert(InTable, v);
|
||
|
end
|
||
|
end
|
||
|
return InTable;
|
||
|
end
|
||
|
|
||
|
---@param InClass UClass<AActor>
|
||
|
---@param InFunc fun(InIndex:int32, InActor:AActor): bool
|
||
|
---@return AActor
|
||
|
function UE.FindActorByClass(InClass, InFunc)
|
||
|
local Table = {};
|
||
|
UE.FindActorsByClass(InClass, Table, InFunc);
|
||
|
if table.isEmpty(Table) then return nil; end
|
||
|
return Table[1];
|
||
|
end
|
||
|
|
||
|
---@type table<UClass, AActor>
|
||
|
UE.GlobalCachedActor = {};
|
||
|
|
||
|
---@param InClass UClass
|
||
|
---@return nil | AActor
|
||
|
function UE.FindOrCreateActorByClass(InClass, bDestroyOther)
|
||
|
print(string.format('[UE.FindOrCreateActorByClass] 开始执行, ClassName = %s', UE.GetName(InClass)));
|
||
|
if InClass == nil then return nil; end
|
||
|
|
||
|
local CachedActor = UE.GlobalCachedActor[InClass];
|
||
|
if CachedActor ~= nil and UE.IsValid(CachedActor) then
|
||
|
return CachedActor;
|
||
|
end
|
||
|
|
||
|
local Actors = UE.FindActorsByClass(InClass)
|
||
|
local Count = table.getCount(Actors);
|
||
|
print(string.format('[UE.FindOrCreateActorByClass] 查找完毕,一共找到 %d 个元素', Count));
|
||
|
if Count > 0 then
|
||
|
log_tree('[UE.FindOrCreateActorByClass] Actors = ', Actors);
|
||
|
end
|
||
|
|
||
|
local Actor = nil
|
||
|
for i, v in pairs(Actors) do
|
||
|
Actor = v;
|
||
|
if Actor ~= v and bDestroyOther then v:K2_DestroyActor(); end
|
||
|
end
|
||
|
if Actor ~= nil then
|
||
|
UE.GlobalCachedActor[InClass] = Actor;
|
||
|
return Actor;
|
||
|
end
|
||
|
return UE.CreateActor(InClass);
|
||
|
end
|
||
|
|
||
|
---@param ClassPath string 类路径
|
||
|
---@return UClass | nil
|
||
|
function UE.CachedLoadClass(ClassPath)
|
||
|
if UE.CachedClasses[ClassPath] == nil then UE.CachedClasses[ClassPath] = UE.LoadClass(ClassPath); end
|
||
|
if UE.CachedClasses[ClassPath] == nil then
|
||
|
print(string.format('[UE.CachedLoadClass] Error Cant Load Class By Path: %s', ClassPath));
|
||
|
return nil;
|
||
|
end
|
||
|
return UE.CachedClasses[ClassPath];
|
||
|
end
|
||
|
|
||
|
function UE.CreateActor(InClass, InOuter, InCount)
|
||
|
if InOuter == nil then InOuter = UGCGameSystem.GameState; end
|
||
|
if InCount == nil then InCount = 1 end
|
||
|
local Actors = {};
|
||
|
for i = 1, InCount do
|
||
|
local Actor = UGCGameSystem.SpawnActor(InOuter, InClass, VectorHelper.VectorZero(), VectorHelper.RotZero(), VectorHelper.ScaleOne(), InOuter);
|
||
|
Actors[#Actors + 1] = Actor;
|
||
|
end
|
||
|
if InCount == 1 then return Actors[1]; end
|
||
|
return Actors;
|
||
|
end
|
||
|
|
||
|
--- 玩家重生
|
||
|
---@param InPlayerKey PlayerKey
|
||
|
---@param InTime float
|
||
|
function UE.RespawnPlayer(InPlayerKey, InTime)
|
||
|
UGCEventSystem.SetTimer(GameState, function()
|
||
|
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
|
||
|
if Pawn then Pawn:K2_DestroyActor(); end
|
||
|
UGCGameSystem.RespawnPlayer(InPlayerKey);
|
||
|
end, InTime);
|
||
|
end
|
||
|
|
||
|
--- 获取当前时间
|
||
|
function UE.GetCurrentTime()
|
||
|
return KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState)
|
||
|
end
|
||
|
|
||
|
---@param InPlayerKey PlayerKey
|
||
|
---@return PlayerAccountInfo
|
||
|
function UE.GetAccountInfo(InPlayerKey)
|
||
|
return UGCGameSystem.GameState.PlayerDatas.AccountInfo[InPlayerKey];
|
||
|
end
|
||
|
|
||
|
--- 移动玩家到某个地方
|
||
|
---@param InPawn UGCPlayerPawn_C
|
||
|
---@param Location FVector
|
||
|
---@param Rotation FRotator
|
||
|
function UE.MovePlayerToLocation(InPawn, Location, Rotation)
|
||
|
InPawn:bShouldDumpCallstackWhenMovingfast_Tofalse()
|
||
|
InPawn:SetClientLocationOrRotation(Location, Rotation, true, Rotation ~= nil, false);
|
||
|
InPawn:bShouldDumpCallstackWhenMovingfast_ToTrue()
|
||
|
end
|
||
|
|
||
|
--- 激活对应的 Camera
|
||
|
---@param InPawn UGCPlayerPawn_C
|
||
|
---@param InCamera UCameraComponent
|
||
|
---@param InArm USpringArmComponent
|
||
|
function UE.ActiveCamera(InPawn, InCamera, InArm)
|
||
|
-- 关闭所有其他的相机,然后开启 默认 相机
|
||
|
UE.ForeachComponent(InPawn, UE.ComponentPath.Camera, function(c) c:Deactivate() end)
|
||
|
UE.ForeachComponent(InPawn, UE.ComponentPath.SpringArm, function(c) c:Deactivate() end)
|
||
|
InCamera:Activate();
|
||
|
InArm:Activate();
|
||
|
table.func(InPawn, "SetCurrentCamera", InCamera, InArm);
|
||
|
end
|
||
|
|
||
|
--- 遍历 Actor 上面的所有组件
|
||
|
---@param InActor AActor
|
||
|
---@param InComponent UActorComponent
|
||
|
---@param cb fun(c: UActorComponent)
|
||
|
function UE.ForeachComponent(InActor, InComponent, cb)
|
||
|
local Path = UE.ComponentPath[InComponent] == nil and InComponent or UE.ComponentPath[InComponent];
|
||
|
for i, v in pairs(InActor:GetComponentsByClass(LoadClass(Path))) do
|
||
|
cb(v);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
---清空地图上的 Wrapper
|
||
|
function UE.ClearWrappers(bWeapon, bPart, bBullet, bEquipment, bSkin, bSupplies)
|
||
|
local AllActors = {};
|
||
|
local Func = function(b) if b == nil then return true end return b; end
|
||
|
bWeapon = Func(bWeapon);
|
||
|
bPart = Func(bPart);
|
||
|
bBullet = Func(bBullet);
|
||
|
bEquipment = Func(bEquipment);
|
||
|
bSkin = Func(bSkin);
|
||
|
bSupplies = Func(bSupplies);
|
||
|
UE.FindActorsByClass(UGCGameSystem.GameState:GetWrapperClass(), AllActors, function(InIndex, InActor)
|
||
|
if InActor.DefineID == nil then return true; end
|
||
|
local ItemId = InActor.DefineID.TypeSpecificID;
|
||
|
if ItemId == nil or (not InActor.DefineID.bValidItem) then return true; end
|
||
|
UGCLogSystem.Log("[UE.ClearWrappers] ItemId = %s", tostring(ItemId));
|
||
|
local Type = GetCustomItemType(ItemId);
|
||
|
if Type == ECustomItemType.Weapon then
|
||
|
if bWeapon then return true; end
|
||
|
elseif Type == ECustomItemType.Part then
|
||
|
if bPart then return true; end
|
||
|
elseif Type == ECustomItemType.Bullet then
|
||
|
if bBullet then return true; end
|
||
|
elseif Type == ECustomItemType.Equipment then
|
||
|
if bEquipment then return true; end
|
||
|
elseif Type == ECustomItemType.Skin then
|
||
|
if bSkin then return true; end
|
||
|
elseif Type == ECustomItemType.Supplies then
|
||
|
if bSupplies then return true; end
|
||
|
end
|
||
|
return false;
|
||
|
end);
|
||
|
|
||
|
for i, v in pairs(AllActors) do
|
||
|
v:K2_DestroyActor();
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- 组件朝向玩家
|
||
|
---@param InComponent USceneComponent
|
||
|
---@param InActor AActor
|
||
|
function UE.ComponentTowardActor(InComponent, InActor)
|
||
|
if LocalPlayerKey == nil then return; end
|
||
|
local Vec = VectorHelper.Sub(InActor:K2_GetActorLocation(), InComponent:GetOwner():K2_GetActorLocation());
|
||
|
Vec = VectorHelper.Normalize(Vec)
|
||
|
InComponent:K2_SetWorldRotation(VectorHelper.VecToRot(Vec));
|
||
|
end
|
||
|
|
||
|
function UE.GetServerTime()
|
||
|
if UGCGameSystem.GameState then
|
||
|
return UGCGameSystem.GameState:GetServerTime();
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
---@param InTable table<int32|string, AActor>
|
||
|
---@param InFunc fun(InActor:AActor):bool
|
||
|
function UE.DestroyTable(InTable, InFunc)
|
||
|
if table.isEmpty(InTable) then return end
|
||
|
for i, v in pairs(InTable) do
|
||
|
if (InFunc ~= nil and InFunc(v)) or InFunc == nil then v:K2_DestroyActor() end
|
||
|
end
|
||
|
InTable = {};
|
||
|
end
|
||
|
|
||
|
function UE.RespawnAllPlayer(InTime)
|
||
|
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
|
||
|
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(v.PlayerKey);
|
||
|
if UE.IsValid(Pawn) then Pawn:K2_DestroyActor(); end
|
||
|
end
|
||
|
|
||
|
if InTime == nil or InTime <= 0 then
|
||
|
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
|
||
|
UGCGameSystem.RespawnPlayer(v.PlayerKey);
|
||
|
end
|
||
|
else
|
||
|
UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
|
||
|
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
|
||
|
UGCGameSystem.RespawnPlayer(v.PlayerKey);
|
||
|
end
|
||
|
end, InTime);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
---@param Path string
|
||
|
---@param cb fun(TargetClass: UClass)
|
||
|
function UE.AsyncLoadClass(Path, cb)
|
||
|
if cb == nil then return end
|
||
|
if UE.AsyncCachedItems[Path] then
|
||
|
cb(UE.AsyncCachedItems[Path]);
|
||
|
return;
|
||
|
end
|
||
|
CommonUtils:AsyncLoadClass(UGCGameSystem.GameState, Path, function(TargetClass)
|
||
|
if TargetClass and UE.IsValid(TargetClass) then cb(TargetClass); end
|
||
|
end);
|
||
|
end
|
||
|
|
||
|
UE.AsyncCachedItems = {};
|
||
|
|
||
|
---@param Path string
|
||
|
---@param cb fun(TargetClass: UClass)
|
||
|
function UE.AsyncLoadClass_Cached(Path, cb)
|
||
|
if UE.AsyncCachedItems[Path] ~= nil then
|
||
|
if cb then cb(UE.AsyncCachedItems[Path]); end
|
||
|
return;
|
||
|
end
|
||
|
if cb == nil then return end
|
||
|
CommonUtils:AsyncLoadClass(UGCGameSystem.GameState, Path, function(TargetClass)
|
||
|
if TargetClass and UE.IsValid(TargetClass) then
|
||
|
UE.AsyncCachedItems[Path] = TargetClass;
|
||
|
if cb then cb(UE.AsyncCachedItems[Path]); end
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
---@param Path string
|
||
|
---@param cb fun(TargetObject: UObject)
|
||
|
function UE.AsyncLoadObject(Path, cb)
|
||
|
if cb == nil then return end
|
||
|
if UE.AsyncCachedItems[Path] then
|
||
|
cb(UE.AsyncCachedItems[Path]);
|
||
|
return;
|
||
|
end
|
||
|
CommonUtils:AsyncLoadObject(UGCGameSystem.GameState, Path, function(TargetObject)
|
||
|
if TargetObject and UE.IsValid(TargetObject) then cb(TargetObject); end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
---@param Path string
|
||
|
---@param cb fun(TargetObject: UObject)
|
||
|
function UE.AsyncLoadObject_Cached(Path, cb)
|
||
|
if UE.AsyncCachedItems[Path] ~= nil then
|
||
|
if cb then cb(UE.AsyncCachedItems[Path]); end
|
||
|
return;
|
||
|
end
|
||
|
CommonUtils:AsyncLoadObject(UGCGameSystem.GameState, Path, function(TargetObject)
|
||
|
if TargetObject and UE.IsValid(TargetObject) then
|
||
|
UE.AsyncCachedItems[Path] = TargetObject;
|
||
|
if cb then cb(TargetObject); end
|
||
|
end
|
||
|
end)
|
||
|
end
|