local EventSystem = require('Event/EventSystem') local VisualObject = require("Battle/Expression/VisualObject") local EFFECT_PATH = ConstAssetPathConfig.EFFECT_PATH local hasFirstEnterTownLevel = false local ExpLevelManager = {curLevelIsOpen = false ,} local private = { guildPointList = {}, inPathGuide = false, preloadingAssetCount = 0, } local LuaConst=LuaConst local FP=FP local EventID=EventID local InstancingCountDefault = 20 local InstancingCountiOS = 5 local NoBatchCountDefault = 2 local NoBatchCountiOS = 2 function ExpLevelManager.Init() if not USE_LUA_STANDALONE then local instCount = InstancingCountDefault local noBatchCount = NoBatchCountDefault --iOS的策略:0档设备不合批,其它档位的设备减少合批数量以减少内存峰值 if UNITY_IOS then local deviceLevel = SettingAPI.deviceLevel if deviceLevel == 0 then instCount = 0 else instCount = InstancingCountiOS noBatchCount = NoBatchCountiOS end end AuxUtil.SetInstancingCount(instCount) AuxUtil.SetNoBatchCount(noBatchCount) end end function ExpLevelManager.OnUpdate(levelLogicData) local logicLoadingStep = levelLogicData.LogicLoadingStep if logicLoadingStep == LuaConst.Enum_LoadingStep.WaitSceneLoadingOk then levelLogicData.SceneLoaded = AppLoadingProxy.OnHandlerWaitSceneLoadingOk() end ExpLevelManager.UpdateLoadStep(logicLoadingStep) end function ExpLevelManager.UpdateLoadStep(step) EventSystem.Dispatch(EventID.UI_Loading_HandleStep,step) end function ExpLevelManager.LoadLevel(levelInfoData) if MDL.Loading.LoadingType == MDL.Loading.LoadingTypeEnum.EnterWorld then else CTL.Loading.BeginLoading(MDL.Loading.LoadingTypeEnum.InGame) end AppLoadingProxy.LoadScene(levelInfoData.ScenePath) end -- 随进随出的关卡要等自己的主将创建显示后执行 ,其他都是在关卡打开的时候打开 function ExpLevelManager.ReadyEnterLevel(levelInfoData) local levelType = levelInfoData.LevelType local levelID = levelInfoData.LevelID if CTL.HomeMain.CheckLevelTypeIsTown(levelType) then CTL.Name.OpenNameView() AuxUtil.SetShowUIBloodBar(false) else CTL.Bag.CloseAllQuickUseWin(); AuxUtil.SetShowUIBloodBar(true) end local camera1ID = levelInfoData.DefaultCameraID[1] local camera2ID = levelInfoData.DefaultCameraID[2] or 0 if not camera1ID or camera1ID <= 0 then logging.error(LTAG.ERROR, "For Designer: Wrong CameraID in Level: ", levelID) end CameraController.Instance:EnterLevel(camera1ID,camera2ID) private.SetMaxDistSqrModelUI() AuxUtil.HandleReadyEnterLevel() ---这里的顺序敏感 有些界面打开时 会关闭场景效果 local feature = DataSheetManager.LevelFeatureData:GetDataByLevelFeatureID(levelType) CTL.Setting.SetLevelCulling(levelType, feature) -- TODO 220版本启用 -- 子弹剔除规则,如果对手直接把子弹释放在自己的视野盲区,那么子弹特效就不会播放,1v1 3v3 不希望出现这种情况 --SettingAPI.SkipMissileEffectCulling = LevelManager.IsNoCullingExpMissileLevel() -- 通知服务器进入了场景 if levelType == LuaConst.LevelType.CrossEscortTown or levelType == LuaConst.LevelType.SingleEscortTown then MDL.GuildEscort.EscortMapLoadComplete() end CTL.BattleAgent.OnEnterLevel() end function ExpLevelManager.PreloadAssets() local isSyncLevel = LevelManager.IsSyncLevel() if GameAppInfo.IsVersionGreaterThan115000() and LevelManager.IsFreeToEnterAndLeaveLevel() then local allPsPreloadIDs = {} --特效预加载-记录 for playerID, playerInfo in pairs(LevelPlayerManager.PlayersArmyTable) do local army = playerInfo.army for _, armyData in pairs(army) do local heroData = DataSheetManager.HeroData:GetDataByID(armyData.HeroID) local preloadData = DataSheetManager.MonsterModelData:GetDataByID(heroData.ModelID) if preloadData then allPsPreloadIDs[preloadData.PreloadID] = true end end --预加载武将模型,注意随进随出玩法里这里可能只能加到机器人,因为玩家的entity还没初始化 local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) private.TryPreloadActorAsset(entity) end --特效预加载-执行 for pid in pairs(allPsPreloadIDs) do AuxUtil.PreloadPsConfig(pid, isSyncLevel) private.preloadingAssetCount = private.preloadingAssetCount + 1 end else for _, entity in pairs(LogicUpdateManager._entityDic) do --特效预加载,剔除副将,同步关卡:技能特效;其他关卡:技能特效+小黑屋 if not entity:IsAdjutant() then local hasPreloadTask = entity.ExpEntity:PreLoadPsModel(isSyncLevel) if hasPreloadTask then private.preloadingAssetCount = private.preloadingAssetCount + 1 end end --预加载武将模型 private.TryPreloadActorAsset(entity) end end end function private.TryPreloadActorAsset(entity) if GameAppInfo.IsVersionGreaterThan116000() and entity and (entity:IsHero() or entity:IsAdjutant()) then local hasPreloadTask = entity.ExpEntity:PreLoadActorModel() if hasPreloadTask then private.preloadingAssetCount = private.preloadingAssetCount + 1 end end end function ExpLevelManager.IsPreloadAssetsCompleted() if GameAppInfo.IsVersionGreaterThan113100() then --return private.preloadingAssetCount == 0 return private.preloadingAssetCount <= 1 else return true end end function ExpLevelManager.OnPreloadAssetsCompleted() private.preloadingAssetCount = private.preloadingAssetCount - 1 end --设置名字版的最远可视距离 function private.SetMaxDistSqrModelUI() if BattleDataGetter.IsDragonArteryLevel() then --龙脉战要求特殊处理 EventSystem.Dispatch(EventID.UIBattle_Element_SetMaxDistSqrModelUI, DataSheetManager.ConstData:GetDataByID("DragonArteryNameFadeDis").IntValue) else EventSystem.Dispatch(EventID.UIBattle_Element_SetMaxDistSqrModelUI, nil) end end function ExpLevelManager.EnterLevel(levelInfoData) if ExpLevelManager.curLevelIsOpen then return end local levelType = levelInfoData.LevelType local levelID = levelInfoData.LevelID CameraController.Instance:ReactiveCamera(0) EventSystem.Dispatch(EventID.LevelWeather_EnterLevelSwitchWeather) CTL.Setting.EnforceAllSettings() if LevelManager.IsMassivePvPLevel() or levelType == LuaConst.LevelType.RogueLike then EventSystem.Dispatch(EventID.Setting_OnAdaptiveQualityTrigger, true) end CTL.Task.TryShowNewChapter() CTL.ChannelChat.OnEnterLevel() CTL.CountryWantedTask.OnEnterLevel() CTL.HomeMain.OpenUIByLevelType(levelType, levelID) local levelType = levelInfoData.LevelType --[[if levelType ~= LuaConst.LevelType.TOWN then ExpLevelManager.InitShowGuide() end--]] EventSystem.Dispatch(EventID.UI_ShowMiniMap) EventSystem.Dispatch(EventID.UI_DelayToTownPlay) ExpLevelManager.SceneObjParent = AuxUtil.GetEmptyObject(nil, "SceneObjs").transform CTL.Loading.EndLoading() ExpUpdateManager.EnterLevel() --第一次进场景打点 if hasFirstEnterTownLevel == false and LevelManager.IsTown then hasFirstEnterTownLevel = true BIManager.DispatchBIClientEvent(BIManager.EventName.RespFirstEnterTownSuccess) BIManager.DispatchBIClientEvent(BIManager.EventName.BDC_IntoGame,BIManager.BDCEventParam.duration_time, tostring(BIManager.GetBDCDiffTime())) end LevelManager.CurLevelFunc.exp:OnAfterEnter() ExpLevelManager.curLevelIsOpen = true LevelItemManager.Global:Notify_LoadingOver() -- 这句话一定要在所有loading操作完毕后 end function ExpLevelManager.PreEnterLevel(id,combineLevelData) CTL.Sound.PlayLevelSound(id) --时序敏感 先拨leveinfo里的 再播场景事件里的 local randomWeather = false if combineLevelData then local randomValue = math.random(1,100) randomWeather = randomValue <= combineLevelData.RandomWeatherProbability end AuxUtil.HandlePreEnterLevel(randomWeather) end function ExpLevelManager.ShowNoLoadingEffect() SystemManager.PlayPsEffect(EFFECT_PATH) end function ExpLevelManager.ExitLevel() AuxUtil.StopAllMissileFollowEffect() CTL.Setting.OnLevelExit() CTL.HomeMain.ClearByLevelType() CTL.VoiceRoom.CheckNeedLeaveVoiceRoom() CTL.Country.ClearStatues() CTL.CountryNightBoss.ClearCountryNightBossModelInfo() CTL.BattleAgent.OnExitLevel() ExpLevelManager.curLevelIsOpen = false end function ExpLevelManager.ClearLevel() EventSystem.Dispatch(EventID.Level_ClearLevel) AuxUtil.HandleClearLevel() ExpLevelManager.ClearShowGuide() if ExpLevelManager.SceneObjParent then AuxUtil.ReturnEmptyObject(ExpLevelManager.SceneObjParent) ExpLevelManager.SceneObjParent = nil end end --同步玩法等待其他玩家进入 function ExpLevelManager.WaitingOtherEnter(isStop ,curFrame, serverFrame, waitOtherLimitFrame) if (not LogicUpdateManager.IsInReconnectFastPlay()) then if isStop then MDL.Tips.ClearTipsMsg() elseif (serverFrame - curFrame < 20 and curFrame % 20 == 0) then --更新等待时间 local totalWaitFrame = waitOtherLimitFrame or LuaConst.SyncWaitOtherLimitFreame CTL.Tips.AddTipsMsg(Const_IDS["IDS_Announce_POP1"],(totalWaitFrame - curFrame) / 20) end end end function ExpLevelManager.ShowTips(entity, ids, noFirstPerson) if noFirstPerson or entity == LogicUpdateManager._curEntity then CTL.Tips.AddTipsMsg(Const_IDS[ids]) end end --region --*************** 寻路路径点 ***************-- local GUIDE_POINT_PATH = ConstAssetPathConfig.Pattern11 function ExpLevelManager.InitShowGuide() private.pathPointParent = AuxUtil.GetEmptyObject(nil, "PathPointList") local trans = private.pathPointParent.transform for i = 1, LuaConst.GUIDE_POINT_COUNT do local point = VisualObject.CreateVisualObject(GUIDE_POINT_PATH, trans) point:SetScale(0, 0, 0) table.insert(private.guildPointList, point) end end function ExpLevelManager.ClearShowGuide() if private.pathPointParent then AuxUtil.ReturnEmptyObject(private.pathPointParent) private.pathPointParent = nil end while true do local item = table.remove(private.guildPointList) if item then item:Dispose() else break end end end function ExpLevelManager.ShowPathGuide(initPos, entity) if MDL.Cheat.IsPCCheatModel() then return end local tailPoint = 0 local accumulateLength = 0 local preTotalLength = 0 local yOffset = LuaConst.GUIDE_POINT_OFFSET local scale = LuaConst.GUIDE_POINT_SCALE local path = entity.components.path.Path2 for i, v in ipairs(path) do local current = i==1 and initPos or path[i-1] local next = v local length = FP.tonumberV1(FP.V2.Distance(next,current)) local logicDir = FP.V2.Normalized(next - current) local totalLength = preTotalLength + length while accumulateLength + LuaConst.GUIDE_POINT_INTERVAL < totalLength do tailPoint = tailPoint + 1 accumulateLength = accumulateLength + LuaConst.GUIDE_POINT_INTERVAL local logicPos = current + logicDir * (accumulateLength - preTotalLength) local point = private.guildPointList[tailPoint] local px, pz = FP.tonumberV2(logicPos) local cx, cz = FP.tonumberV2(current) local nx, nz = FP.tonumberV2(next) point:Invoke("SetPositionAndDirectionAndScale",cx, cz, nx, nz,px, 0, pz, yOffset,scale, scale, scale) if tailPoint == #private.guildPointList then break end end if tailPoint == #private.guildPointList then break end preTotalLength = totalLength end if tailPoint < #private.guildPointList then for i = tailPoint + 1, #private.guildPointList do local point = private.guildPointList[i] point:SetScale(0, 0, 0) end end private.inPathGuide = true end function ExpLevelManager.HidePathGuide() if not private.inPathGuide then return end private.inPathGuide = false for i, v in ipairs(private.guildPointList) do v:SetScale(0, 0, 0) end end function ExpLevelManager.PlayTimeline(path, pauseLevel, autoPassTime, callback, adsorbType, adsorbParam) local hasRewarded = CTL.Cutscene.OnPlayTimeline(path) adsorbType = adsorbType or 0 adsorbParam = adsorbParam or 0 if path == "Assets/TimeLine/Prefabs/Interlude/Plot_99_01_040.prefab" then AuxUtil.StartNormalTimelineWithEntity(path, LogicUpdateManager._curEntity.ExpEntity:GetRenderEntity(), nil, "", pauseLevel, autoPassTime, hasRewarded, callback, adsorbType, adsorbParam) else AuxUtil.StartTimeline(path, pauseLevel, autoPassTime, hasRewarded, callback, adsorbType, adsorbParam) end end function ExpLevelManager.OnTimelineEnd(path, requestReward) CTL.Cutscene.OnEndTimeline(path, requestReward) end --endregion 寻路路径点 function ExpLevelManager.TrySetPhysics() --目前同步组队pve因为要看到阻挡墙特效,所以先暂时开启物理系统 --TODO:【LSH】之后阻挡墙特效的显示逻辑不用物理检测去做 local enablePhysics = not LevelManager.IsSyncLevel() or LevelManager.IsSyncTeamPVE() -- 特殊的关卡要开(劫镖) if BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.SyncPlanesEscort) then enablePhysics = true end AuxUtil.SetPhysicsEnabled(enablePhysics) end function ExpLevelManager.SetupPsLOD(levelType) if levelType then local feature = DataSheetManager.LevelFeatureData:GetDataByLevelFeatureID(levelType) if feature then local presetID = feature.PsLODSetting CTL.Setting.SetPsPresetConfig(presetID) end else --reset to default preset value -1 CTL.Setting.SetPsPresetConfig(-1) end end function ExpLevelManager.StartRealEnterScene() TK2API.ManualUnloadAssetBundle() end return ExpLevelManager