From df27e7ba75f19a521494a6ac20f83e9432b6e9e3 Mon Sep 17 00:00:00 2001 From: hevinci Date: Wed, 1 Feb 2023 18:59:47 +0800 Subject: [PATCH] update shader variant collector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化着色器变种收集代码 --- .../ShaderVariantCollector.cs | 177 ++++++++++-------- .../ShaderVariantCollectorSetting.cs | 5 + .../ShaderVariantCollectorWindow.cs | 58 +++++- .../ShaderVariantCollectorWindow.uxml | 11 +- 4 files changed, 165 insertions(+), 86 deletions(-) diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs index 1d69b1b..d9ef89d 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollector.cs @@ -12,134 +12,150 @@ namespace YooAsset.Editor { public static class ShaderVariantCollector { + private enum ESteps + { + None, + Prepare, + CollectAllMaterial, + CollectVariants, + CollectVariantsFinish, + WaitingDone, + } + private const float WaitMilliseconds = 1000f; - private static string _saveFilePath; - private static bool _isStarted = false; - private static readonly Stopwatch _elapsedTime = new Stopwatch(); + private static string _savePath; + private static string _packageName; private static Action _completedCallback; - private static void EditorUpdate() - { - // 注意:一定要延迟保存才会起效 - if (_isStarted && _elapsedTime.ElapsedMilliseconds > WaitMilliseconds) - { - _isStarted = false; - _elapsedTime.Stop(); - EditorApplication.update -= EditorUpdate; + private static ESteps _steps = ESteps.None; + private static Stopwatch _elapsedTime; + private static List _allMaterials; - // 保存结果 - ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_saveFilePath); - - // 创建清单 - CreateManifest(); - - Debug.Log($"搜集SVC完毕!"); - _completedCallback?.Invoke(); - } - } /// /// 开始收集 /// - public static void Run(string saveFilePath, Action completedCallback) + public static void Run(string savePath, string packageName, Action completedCallback) { - if (_isStarted) + if (_steps != ESteps.None) return; - if (Path.HasExtension(saveFilePath) == false) - saveFilePath = $"{saveFilePath}.shadervariants"; - if (Path.GetExtension(saveFilePath) != ".shadervariants") + if (Path.HasExtension(savePath) == false) + savePath = $"{savePath}.shadervariants"; + if (Path.GetExtension(savePath) != ".shadervariants") throw new System.Exception("Shader variant file extension is invalid."); + if (string.IsNullOrEmpty(packageName)) + throw new System.Exception("Package name is null or empty !"); // 注意:先删除再保存,否则ShaderVariantCollection内容将无法及时刷新 - AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath); - EditorTools.CreateFileDirectory(saveFilePath); - _saveFilePath = saveFilePath; + AssetDatabase.DeleteAsset(savePath); + EditorTools.CreateFileDirectory(savePath); + _savePath = savePath; + _packageName = packageName; _completedCallback = completedCallback; // 聚焦到游戏窗口 EditorTools.FocusUnityGameWindow(); - // 清空旧数据 - ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection(); - // 创建临时测试场景 CreateTempScene(); - // 收集着色器变种 - var materials = GetAllMaterials(); - CollectVariants(materials); - + _steps = ESteps.Prepare; EditorApplication.update += EditorUpdate; - _isStarted = true; - _elapsedTime.Reset(); - _elapsedTime.Start(); } + private static void EditorUpdate() + { + if (_steps == ESteps.None) + return; + + if (_steps == ESteps.Prepare) + { + ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection(); + _steps = ESteps.CollectAllMaterial; + return; + } + + if (_steps == ESteps.CollectAllMaterial) + { + _allMaterials = GetAllMaterials(); + _steps = ESteps.CollectVariants; + return; + } + + if (_steps == ESteps.CollectVariants) + { + CollectVariants(_allMaterials); + _steps = ESteps.CollectVariantsFinish; + return; + } + + if (_steps == ESteps.CollectVariantsFinish) + { + _elapsedTime = Stopwatch.StartNew(); + _steps = ESteps.WaitingDone; + return; + } + + if (_steps == ESteps.WaitingDone) + { + // 注意:一定要延迟保存才会起效 + if (_elapsedTime.ElapsedMilliseconds > WaitMilliseconds) + { + _elapsedTime.Stop(); + _steps = ESteps.None; + + // 保存结果并创建清单 + ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_savePath); + CreateManifest(); + + Debug.Log($"搜集SVC完毕!"); + EditorApplication.update -= EditorUpdate; + _completedCallback?.Invoke(); + } + } + } private static void CreateTempScene() { EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects); } - private static List GetAllMaterials() + private static List GetAllMaterials() { int progressValue = 0; List allAssets = new List(1000); // 获取所有打包的资源 - List allCollectAssetInfos = new List(); - List collectResults = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild); - foreach (var collectResult in collectResults) + CollectResult collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(EBuildMode.DryRunBuild, _packageName); + foreach (var assetInfo in collectResult.CollectAssets) { - allCollectAssetInfos.AddRange(collectResult.CollectAssets); - } - List allAssetPath = allCollectAssetInfos.Select(t => t.AssetPath).ToList(); - foreach (var assetPath in allAssetPath) - { - string[] depends = AssetDatabase.GetDependencies(assetPath, true); - foreach (var depend in depends) + string[] depends = AssetDatabase.GetDependencies(assetInfo.AssetPath, true); + foreach (var dependAsset in depends) { - if (allAssets.Contains(depend) == false) - allAssets.Add(depend); + if (allAssets.Contains(dependAsset) == false) + allAssets.Add(dependAsset); } - EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, allAssetPath.Count); + EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectResult.CollectAssets.Count); } EditorTools.ClearProgressBar(); // 搜集所有材质球 progressValue = 0; - var shaderDic = new Dictionary>(100); + List allMaterial = new List(1000); foreach (var assetPath in allAssets) { System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (assetType == typeof(UnityEngine.Material)) { - var material = AssetDatabase.LoadAssetAtPath(assetPath); - var shader = material.shader; - if (shader == null) - continue; - - if (shaderDic.ContainsKey(shader) == false) - { - shaderDic.Add(shader, new List()); - } - if (shaderDic[shader].Contains(material) == false) - { - shaderDic[shader].Add(material); - } + allMaterial.Add(assetPath); } EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count); } EditorTools.ClearProgressBar(); // 返回结果 - var materials = new List(1000); - foreach (var valuePair in shaderDic) - { - materials.AddRange(valuePair.Value); - } - return materials; + return allMaterial; } - private static void CollectVariants(List materials) + private static void CollectVariants(List materials) { Camera camera = Camera.main; if (camera == null) @@ -178,23 +194,28 @@ namespace YooAsset.Editor } EditorTools.ClearProgressBar(); } - private static void CreateSphere(Material material, Vector3 position, int index) + private static void CreateSphere(string assetPath, Vector3 position, int index) { + var material = AssetDatabase.LoadAssetAtPath(assetPath); + var shader = material.shader; + if (shader == null) + return; + var go = GameObject.CreatePrimitive(PrimitiveType.Sphere); go.GetComponent().material = material; go.transform.position = position; - go.name = $"Sphere_{index}|{material.name}"; + go.name = $"Sphere_{index} | {material.name}"; } private static void CreateManifest() { AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); - ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath(_saveFilePath); + ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath(_savePath); if (svc != null) { var wrapper = ShaderVariantCollectionManifest.Extract(svc); string jsonData = JsonUtility.ToJson(wrapper, true); - string savePath = _saveFilePath.Replace(".shadervariants", ".json"); + string savePath = _savePath.Replace(".shadervariants", ".json"); File.WriteAllText(savePath, jsonData); } diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs index d7e9851..320a4c7 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorSetting.cs @@ -8,5 +8,10 @@ namespace YooAsset.Editor /// 文件存储路径 /// public string SavePath = "Assets/MyShaderVariants.shadervariants"; + + /// + /// 收集的包裹名称 + /// + public string CollectPackage = string.Empty; } } \ No newline at end of file diff --git a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs index 9d8b9d9..29f1707 100644 --- a/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs +++ b/Assets/YooAsset/Editor/ShaderVariantCollector/ShaderVariantCollectorWindow.cs @@ -18,10 +18,13 @@ namespace YooAsset.Editor window.minSize = new Vector2(800, 600); } + private List _packageNames; + private Button _collectButton; private TextField _collectOutputField; private Label _currentShaderCountField; private Label _currentVariantCountField; + private PopupField _packageField; public void CreateGUI() { @@ -36,6 +39,9 @@ namespace YooAsset.Editor visualAsset.CloneTree(root); + // 包裹名称列表 + _packageNames = GetBuildPackageNames(); + // 文件输出目录 _collectOutputField = root.Q("CollectOutput"); _collectOutputField.SetValueWithoutNotify(ShaderVariantCollectorSettingData.Setting.SavePath); @@ -44,14 +50,34 @@ namespace YooAsset.Editor ShaderVariantCollectorSettingData.Setting.SavePath = _collectOutputField.value; }); + // 收集的包裹 + var packageContainer = root.Q("PackageContainer"); + if (_packageNames.Count > 0) + { + int defaultIndex = GetDefaultPackageIndex(ShaderVariantCollectorSettingData.Setting.CollectPackage); + _packageField = new PopupField(_packageNames, defaultIndex); + _packageField.label = "Package"; + _packageField.style.width = 350; + _packageField.RegisterValueChangedCallback(evt => + { + ShaderVariantCollectorSettingData.Setting.CollectPackage = _packageField.value; + }); + packageContainer.Add(_packageField); + } + else + { + _packageField = new PopupField(); + _packageField.label = "Package"; + _packageField.style.width = 350; + packageContainer.Add(_packageField); + } + _currentShaderCountField = root.Q