using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using UnityEngine; using UnityEngine.Rendering; using UnityEditor; namespace YooAsset.Editor { public static class ShaderVariantCollectionReadme { [Serializable] public class ShaderVariantElement { /// /// Pass type to use in this variant. /// public PassType PassType; /// /// Array of shader keywords to use in this variant. /// public string[] Keywords; } [Serializable] public class ShaderVariantInfo { /// /// Shader asset path in editor. /// public string AssetPath; /// /// Shader name. /// public string ShaderName; /// /// Shader variants elements list. /// public List ShaderVariantElements = new List(1000); } [Serializable] public class ShaderVariantCollectionManifest { /// /// Number of shaders in this collection /// public int ShaderTotalCount; /// /// Number of total varians in this collection /// public int VariantTotalCount; /// /// Shader variants info list. /// public List ShaderVariantInfos = new List(1000); /// /// 添加着色器变种信息 /// public void AddShaderVariant(string assetPath, string shaderName, PassType passType, string[] keywords) { var info = GetOrCreateShaderVariantInfo(assetPath, shaderName); ShaderVariantElement element = new ShaderVariantElement(); element.PassType = passType; element.Keywords = keywords; info.ShaderVariantElements.Add(element); } private ShaderVariantInfo GetOrCreateShaderVariantInfo(string assetPath, string shaderName) { var selectList = ShaderVariantInfos.Where(t => t.ShaderName == shaderName && t.AssetPath == assetPath).ToList(); if (selectList.Count == 0) { ShaderVariantInfo newInfo = new ShaderVariantInfo(); newInfo.AssetPath = assetPath; newInfo.ShaderName = shaderName; ShaderVariantInfos.Add(newInfo); return newInfo; } if (selectList.Count != 1) throw new Exception("Should never get here !"); return selectList[0]; } } /// /// 解析SVC文件并将数据写入到清单 /// public static ShaderVariantCollectionManifest Extract(ShaderVariantCollection svc) { var manifest = new ShaderVariantCollectionManifest(); manifest.ShaderTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount(); manifest.VariantTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount(); using (var so = new SerializedObject(svc)) { var shaderArray = so.FindProperty("m_Shaders.Array"); if (shaderArray != null && shaderArray.isArray) { for (int i = 0; i < shaderArray.arraySize; ++i) { var shaderRef = shaderArray.FindPropertyRelative($"data[{i}].first"); var shaderVariantsArray = shaderArray.FindPropertyRelative($"data[{i}].second.variants"); if (shaderRef != null && shaderRef.propertyType == SerializedPropertyType.ObjectReference && shaderVariantsArray != null && shaderVariantsArray.isArray) { var shader = shaderRef.objectReferenceValue as Shader; if (shader == null) { throw new Exception("Invalid shader in ShaderVariantCollection file."); } string shaderAssetPath = AssetDatabase.GetAssetPath(shader); string shaderName = shader.name; // 添加变种信息 for (int j = 0; j < shaderVariantsArray.arraySize; ++j) { var propKeywords = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].keywords"); var propPassType = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].passType"); if (propKeywords != null && propPassType != null && propKeywords.propertyType == SerializedPropertyType.String) { string[] keywords = propKeywords.stringValue.Split(' '); PassType pathType = (PassType)propPassType.intValue; manifest.AddShaderVariant(shaderAssetPath, shaderName, pathType, keywords); } } } } } } return manifest; } } }