--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