local AssetAnalysisTools = {} local private = { curCameraModel = 0, analysisAssetModel = 0, isInAssetAnalysis = false, } local LuaUpdater = require("Main/LuaUpdater") local AssetDataAnalysis = require("ProfilerKit/AssetDataAnalysis") local prefabUpdateFrameIndex = 0 local currentPrefabIndex = 1 local ConstPrefabForceReturnFrameIndex = 15 local ConstPrefabGCFrameIndex = 20 local ConstTotalPrefabFrameIndex = 35 local effectUpdateFrameIndex = 0 local currentEffectIndex = 1 local ConstEffectForceStopFrameIndex = 150 local ConstEffectGCFrameIndex = 180 local ConstTotalEffectFrameIndex = 200 local otherUpdateFrameIndex = 0 local currentOtherIndex = 1 local ConstOtherForceStopFrameIndex = 60 local ConstOtherGCFrameIndex = 165 local ConstTotalOtherFrameIndex = 180 local curRenderEntity local currentOtherInfo = { otherPath = "", otherObject = nil, } local currentAnalysisState local prefabPathList local effectPathList local otherPathList local prefabPathListFilter local effectPathListFilter local otherPathListFilter local assetFilterStr local EmptyModelPath = ConstAssetPathConfig.EmptyModelPath local AssetAnalysisModules = { [1] = "Basic", [2] = "Overdraw", [3] = "Mipmaps", } local CameraModelStr = { [1] = "主城相机", [2] = "PVP相机", [3] = "展示相机", [4] = "马相机", [5] = "宝物相机", } local AnalysisAssetModelStr = { "模型", "特效", "其他", } function AssetAnalysisTools.GetAssetAnalysisModules() return AssetAnalysisModules end function private.GetConfigTable(path) local str if not LuaExt.FileExists(path) then --复制到包外 str = AuxUtil.ReadStreamingAssetText(path) LuaExt.FileWriteText(path, str) end str = LuaExt.FileReadText(path) return string.split(str, "|") end function AssetAnalysisTools.Start() UnityEngine.SceneManagement.SceneManager.LoadScene("AssetAnalysis") require("Common/define") prefabPathList = private.GetConfigTable("AssetAnalysis_Prefab.txt") effectPathList = private.GetConfigTable("AssetAnalysis_Effect.txt") otherPathList = private.GetConfigTable("AssetAnalysis_Other.txt") CTL.Setting.SetPsPresetConfig(-1) CameraController.LoadGameCamera() if SettingAPI.deviceLevel == 0 then AuxUtil.StopSSS() end CTL.Optimize.EnableAdaptiveLOD(false) AuxUtil.ReloadLanguage(Const_IDS) CTL.Sound.Init() CTL.Setting.LoginSync() LuaExt.FileWriteText("pkgver", AppInfo.marketVersion) AuxUtil.FirstGetDeviceLevel() CTL.Setting.EnforceAllSettings() local hasExecuted = PersistentData.DeviceData:Get("ExecuteIfLoadedAB") if hasExecuted == false then AuxUtil.WarmUpShaders() PersistentData.DeviceData:Set("ExecuteIfLoadedAB", true, true) end if MDL.Setting.HasKey(LuaConst.SettingKeyEnum.SettingQuality) then local settingQuality=MDL.Setting.GetKeyValue(LuaConst.SettingKeyEnum.SettingQuality) CTL.Setting.ForceSetQuality(settingQuality, MDL.Setting.SwitchLodType.Manual) end UIUtils.InitUICameraBlur() UIManager.OpenSpecialView("Debug/UIDebugView") UIManager.OpenSpecialView("ProfilerKit/UIAssetAnalysis") private.SetupEntity() --设置相机 AssetAnalysisTools.SetNormalCamera() AssetAnalysisTools.SetAssetAnalysisState(0) end function AssetAnalysisTools.SetAssetAnalysisState(state) currentAnalysisState = state + 1 AuxUtil.AssetAnalysis_SetAssetAnalysisState(state) end function private.SetupEntity() local cullingMode if GameAppInfo.IsVersionGreaterThan114000() then cullingMode = LuaConst.EntityCullingMode.NoCulling else cullingMode = false end curRenderEntity = AuxUtil.LoadRenderEntity(false, 13, 0, 1, -1, true, cullingMode) local modelPath = EmptyModelPath local pathId = UTL.String.GetIdByString(modelPath) curRenderEntity:SetModel(1, pathId, 0, 1, 0, 0, -1, 1, 1, 1) curRenderEntity:SetSoundListener(true) curRenderEntity:SetVisible(true) curRenderEntity:SetTrans(0, 0, 0, 0) AuxUtil.SetCurRenderEntity(curRenderEntity) end function AssetAnalysisTools.SetNormalCamera() CameraController.Instance:EnterLevel(2, 2) private.curCameraModel = 1 end function AssetAnalysisTools.SetPVPCamera() CameraController.Instance:EnterLevel(4, 4) private.curCameraModel = 2 end function AssetAnalysisTools.SetShowCamera() UIModelUtils.SetVirtualCamera(3, curRenderEntity.Transform) private.curCameraModel = 3 end function AssetAnalysisTools.SetHorseCamera() AuxUtil.AssetAnalysis_SetHorseCamera(curRenderEntity.GameObject) private.curCameraModel = 4 end function AssetAnalysisTools.SetTreasureCamera() AuxUtil.AssetAnalysis_SetTreasureCamera() private.curCameraModel = 5 end function AssetAnalysisTools.ExportProfilerData() local lod = CTL.Setting.GetLodLevel() local deviceModel = SystemInfo.deviceModel or "" local fitlerStr = "" if not string.isNilOrEmpty(assetFilterStr) then fitlerStr = string.gsub(assetFilterStr, "/", "") end local parentDir = "AssetAnalysisResult/" if not LuaExt.DirectoryExists(parentDir) then LuaExt.DirectoryCreate(parentDir) end local curDate = UTL.Time.OsDateOriginal("*t", os.time()) local timeStr = string.format("%s月%s日%s时%s分%s秒", curDate.month, curDate.day, curDate.hour, curDate.min, curDate.sec) local exportPath = string.format(parentDir..AssetAnalysisModules[currentAnalysisState] .. "-%s-%s-%s-LOD%s-%s-%s.csv", deviceModel, CameraModelStr[private.curCameraModel], AnalysisAssetModelStr[private.analysisAssetModel], lod, fitlerStr, timeStr) AuxUtil.AssetAnalysis_ExportData(exportPath) logging.log(LTAG.LOG, "analysis report file exported", exportPath) AssetAnalysisTools.ClearAssetRecorderInfo() AssetDataAnalysis.AnalysisProfilerData(exportPath) end --自动化分析使用,自动化性能分析前执行 function AssetAnalysisTools.OnPreprocessAssetAnalysis() print("AssetAnalysisTools.OnPreprocessAssetAnalysis") end --自动化分析使用,自动化性能分析后执行 function AssetAnalysisTools.OnPostprocessAssetAnalysis() print("AssetAnalysisTools.OnPostprocessAssetAnalysis") AssetDataAnalysis.OutputAnalysisResult2CSV() end function AssetAnalysisTools.ClearAssetRecorderInfo() AssetAnalysisTools.RenderEntityChangeModelEmpty() AssetAnalysisTools.StopEffect() AssetAnalysisTools.ReturnOther() AssetAnalysisTools.StopAssetAnalysis_Prefab() AssetAnalysisTools.StopAssetAnalysis_Effect() AssetAnalysisTools.StopAssetAnalysis_Other() AssetAnalysisTools.GC() AuxUtil.AssetAnalysis_ClearRecorderInfo() private.isInAssetAnalysis = false end function AssetAnalysisTools.RenderEntityChangeModel(modelPath) local pathId = UTL.String.GetIdByString(modelPath) curRenderEntity:ChangeModel(1, pathId, 0, 1, 0, 0, -1, 1, 1) end function AssetAnalysisTools.RenderEntityChangeModelEmpty() local pathId = UTL.String.GetIdByString(EmptyModelPath) curRenderEntity:ChangeModel(1, pathId, 0, 1, 0, 0, -1, 1, 1) end function AssetAnalysisTools.GC() AuxUtil.OnLowMemory(true) end function AssetAnalysisTools.PlayEffect(effectPath) local effectPathId = UTL.String.GetIdByString(effectPath) local effectId = curRenderEntity:PlayEffect(effectPathId, -1, true, 0, 13, 1) return effectId end function AssetAnalysisTools.StopEffect() curRenderEntity:BreakEffect() end function AssetAnalysisTools.ReturnOther() if not string.isNilOrEmpty(currentOtherInfo.otherPath) then TK2API.ReturnInstance(currentOtherInfo.otherPath, currentOtherInfo.otherObject) currentOtherInfo.otherPath = "" currentOtherInfo.otherObject = nil end end function AssetAnalysisTools.IsInAssetAnalysis() return private.isInAssetAnalysis end function AssetAnalysisTools.StartAssetAnalysis_Prefab(filterStr) private.isInAssetAnalysis = true private.analysisAssetModel = 1 assetFilterStr = filterStr if string.isNilOrEmpty(filterStr) then prefabPathListFilter = prefabPathList else prefabPathListFilter = {} for k, v in ipairs(prefabPathList) do if string.find(v, filterStr, 1, true) then table.insert(prefabPathListFilter, v) end end end AssetAnalysisTools.GC() --延迟1s等待GC完成,防止数据干扰 TimerUtil.Interval(function () LuaUpdater.StartRealTimeUpdate(private.OnRealTimeUpdate_Prefab) end,1,1) end function AssetAnalysisTools.StopAssetAnalysis_Prefab() LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Prefab) prefabUpdateFrameIndex = 0 currentPrefabIndex = 1 private.isInAssetAnalysis = false end function AssetAnalysisTools.StartAssetAnalysis_Effect(filterStr) private.isInAssetAnalysis = true private.analysisAssetModel = 2 assetFilterStr = filterStr if string.isNilOrEmpty(filterStr) then effectPathListFilter = effectPathList else effectPathListFilter = {} for k, v in ipairs(effectPathList) do if string.find(v, filterStr, 1, true) then table.insert(effectPathListFilter, v) end end end AssetAnalysisTools.GC() TimerUtil.Interval(function () LuaUpdater.StartRealTimeUpdate(private.OnRealTimeUpdate_Effect) end,1,1) end function AssetAnalysisTools.StopAssetAnalysis_Effect() LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Effect) effectUpdateFrameIndex = 0 currentEffectIndex = 1 private.isInAssetAnalysis = false end function AssetAnalysisTools.StartAssetAnalysis_Other(filterStr) private.isInAssetAnalysis = true private.analysisAssetModel = 3 assetFilterStr = filterStr if string.isNilOrEmpty(filterStr) then otherPathListFilter = otherPathList else otherPathListFilter = {} for k, v in ipairs(otherPathList) do if string.find(v, filterStr, 1, true) then table.insert(otherPathListFilter, v) end end end AssetAnalysisTools.GC() TimerUtil.Interval(function () LuaUpdater.StartRealTimeUpdate(private.OnRealTimeUpdate_Other) end,1,1) end function AssetAnalysisTools.StopAssetAnalysis_Other() LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Other) otherUpdateFrameIndex = 0 currentOtherIndex = 1 private.isInAssetAnalysis = false end function AssetAnalysisTools.ShowOKBox(title, content) UTL.MessageBox.ShowOKCancelBox(title, content, AssetAnalysisTools.GC, nil) end function AssetAnalysisTools.PauseAssetAnalysis() LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Prefab) LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Effect) LuaUpdater.StopRealTimeUpdate(private.OnRealTimeUpdate_Other) end function private.OnRealTimeUpdate_Prefab(deltaTime, timeSinceUpdate) --0帧的时候开始 if prefabUpdateFrameIndex == 0 then local prefabPathList = prefabPathListFilter --如果超过列表,关掉更新函数 if currentPrefabIndex > #prefabPathList then AssetAnalysisTools.StopAssetAnalysis_Prefab(true) AssetAnalysisTools.ExportProfilerData() AssetAnalysisTools.ShowOKBox("性能测试", "角色Prefab类型测试结束") return end if string.isNilOrEmpty(prefabPathList[currentPrefabIndex]) then currentPrefabIndex = currentPrefabIndex + 1 prefabUpdateFrameIndex = 0 return end local prefabPath = prefabPathList[currentPrefabIndex] local pathId = UTL.String.GetIdByString(prefabPath) xpcall(AssetAnalysisTools.RenderEntityChangeModel, private.ErrorMessage, prefabPath) AuxUtil.AssetAnalysis_StartRecorder(pathId) --AssetAnalysisTools.RenderEntityChangeModel(prefabPath) currentPrefabIndex = currentPrefabIndex + 1 end --结束,执行GC if prefabUpdateFrameIndex == ConstPrefabForceReturnFrameIndex then AssetAnalysisTools.RenderEntityChangeModelEmpty() end if prefabUpdateFrameIndex == ConstPrefabGCFrameIndex then AssetAnalysisTools.GC() end prefabUpdateFrameIndex = prefabUpdateFrameIndex + 1 --可以认为GC结束 if prefabUpdateFrameIndex == ConstTotalPrefabFrameIndex then prefabUpdateFrameIndex = 0 AuxUtil.AssetAnalysis_StopRecorder() end end function private.OnRealTimeUpdate_Effect(deltaTime, timeSinceUpdate) --0帧的时候开始 if effectUpdateFrameIndex == 0 then local effectPathList = effectPathListFilter --如果超过列表,关掉更新函数 if currentEffectIndex > #effectPathList then AssetAnalysisTools.StopAssetAnalysis_Effect(true) AssetAnalysisTools.ExportProfilerData() AssetAnalysisTools.ShowOKBox("性能测试", "特效类型测试结束") return end if string.isNilOrEmpty(effectPathList[currentEffectIndex]) then currentEffectIndex = currentEffectIndex + 1 effectUpdateFrameIndex = 0 return end local effectPath = effectPathList[currentEffectIndex] local pathId = UTL.String.GetIdByString(effectPath) xpcall(AssetAnalysisTools.PlayEffect, private.ErrorMessage, effectPath) AuxUtil.AssetAnalysis_StartRecorder(pathId) currentEffectIndex = currentEffectIndex + 1 end --结束 if effectUpdateFrameIndex == ConstEffectForceStopFrameIndex then AssetAnalysisTools.StopEffect() end --执行GC if effectUpdateFrameIndex == ConstEffectGCFrameIndex then AssetAnalysisTools.GC() end effectUpdateFrameIndex = effectUpdateFrameIndex + 1 --可以认为GC结束 if effectUpdateFrameIndex == ConstTotalEffectFrameIndex then effectUpdateFrameIndex = 0 AuxUtil.AssetAnalysis_StopRecorder() end end function private.OnRealTimeUpdate_Other(deltaTime, timeSinceUpdate) --0帧的时候开始 if otherUpdateFrameIndex == 0 then local otherPathList = otherPathListFilter --如果超过列表,关掉更新函数 if currentOtherIndex > #otherPathList then AssetAnalysisTools.StopAssetAnalysis_Other() AssetAnalysisTools.ExportProfilerData() AssetAnalysisTools.ShowOKBox("性能测试", "其他类型测试结束") return end if string.isNilOrEmpty(otherPathList[currentOtherIndex]) then currentOtherIndex = currentOtherIndex + 1 otherUpdateFrameIndex = 0 return end currentOtherInfo.otherPath = otherPathList[currentOtherIndex] local pathId = UTL.String.GetIdByString(currentOtherInfo.otherPath) currentOtherInfo.otherObject = TK2API.GetInstance(currentOtherInfo.otherPath) AuxUtil.AssetAnalysis_StartRecorder(pathId) currentOtherIndex = currentOtherIndex + 1 end --结束 if otherUpdateFrameIndex == ConstOtherForceStopFrameIndex then AssetAnalysisTools.ReturnOther() end --执行GC if otherUpdateFrameIndex == ConstOtherGCFrameIndex then AssetAnalysisTools.GC() end otherUpdateFrameIndex = otherUpdateFrameIndex + 1 --可以认为GC结束 if otherUpdateFrameIndex == ConstTotalOtherFrameIndex then otherUpdateFrameIndex = 0 AuxUtil.AssetAnalysis_StopRecorder() end end function private.ErrorMessage(msg) logging.error(LTAG.ERROR, "AssetError:", msg) end return AssetAnalysisTools