using System; using System.Text; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEditor.VFX; using UnityEngine.VFX; using UnityEngine.Profiling; using System.Reflection; using Object = UnityEngine.Object; namespace UnityEditor.VFX { [Serializable] struct VFXParameterInfo { public VFXParameterInfo(string exposedName, string realType) { name = exposedName; this.realType = realType; path = null; tooltip = null; defaultValue = null; min = Mathf.NegativeInfinity; max = Mathf.Infinity; descendantCount = 0; sheetType = null; enumValues = null; } public string name; public string path; public string tooltip; public string sheetType; public string realType; public VFXSerializableObject defaultValue; public float min; public float max; public List enumValues; public int descendantCount; public static VFXParameterInfo[] BuildParameterInfo(VFXGraph graph) { var categories = graph.UIInfos.categories; if (categories == null) categories = new List(); var parameters = graph.children.OfType().Where(t => t.exposed && (string.IsNullOrEmpty(t.category) || !categories.Any(u => u.name == t.category)) && !t.isOutput).OrderBy(t => t.order).ToArray(); var infos = new List(); BuildCategoryParameterInfo(parameters, infos); foreach (var cat in categories) { parameters = graph.children.OfType().Where(t => t.exposed && t.category == cat.name && !t.isOutput).OrderBy(t => t.order).ToArray(); if (parameters.Length > 0) { VFXParameterInfo paramInfo = new VFXParameterInfo(cat.name, ""); paramInfo.descendantCount = 0; infos.Add(paramInfo); BuildCategoryParameterInfo(parameters, infos); } } return infos.ToArray(); } static void BuildCategoryParameterInfo(VFXParameter[] parameters, List infos) { var subList = new List(); foreach (var parameter in parameters) { string rootFieldName = VisualEffectSerializationUtility.GetTypeField(parameter.type); VFXParameterInfo paramInfo = new VFXParameterInfo(parameter.exposedName, parameter.type.Name); paramInfo.tooltip = parameter.tooltip; if (rootFieldName != null) { paramInfo.sheetType = rootFieldName; paramInfo.path = paramInfo.name; if (parameter.valueFilter == VFXValueFilter.Range) { float min = (float)System.Convert.ChangeType(parameter.min, typeof(float)); float max = (float)System.Convert.ChangeType(parameter.max, typeof(float)); paramInfo.min = min; paramInfo.max = max; } else if (parameter.valueFilter == VFXValueFilter.Enum) { paramInfo.enumValues = parameter.enumValues.ToList(); } paramInfo.defaultValue = new VFXSerializableObject(parameter.type, parameter.value); paramInfo.descendantCount = 0; } else { paramInfo.descendantCount = RecurseBuildParameterInfo(subList, parameter.type, parameter.exposedName, parameter.value); } infos.Add(paramInfo); infos.AddRange(subList); subList.Clear(); } } static int RecurseBuildParameterInfo(List infos, System.Type type, string path, object obj) { if (!type.IsValueType) return 0; int count = 0; var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public); var subList = new List(); foreach (var field in fields) { var info = new VFXParameterInfo(field.Name, field.FieldType.Name); var subObj = field.GetValue(obj); info.path = path + "_" + field.Name; var tooltip = field.GetCustomAttributes(typeof(TooltipAttribute), true).FirstOrDefault() as TooltipAttribute; if (tooltip != null) { info.tooltip = tooltip.tooltip; } var fieldName = VisualEffectSerializationUtility.GetTypeField(field.FieldType); if (fieldName != null) { info.sheetType = fieldName; RangeAttribute attr = field.GetCustomAttributes(true).OfType().FirstOrDefault(); if (attr != null) { info.min = attr.min; info.max = attr.max; } info.descendantCount = 0; info.defaultValue = new VFXSerializableObject(field.FieldType, subObj); } else { if (field.FieldType == typeof(VFXCoordinateSpace)) // For space continue; info.descendantCount = RecurseBuildParameterInfo(subList, field.FieldType, info.path, subObj); } infos.Add(info); infos.AddRange(subList); subList.Clear(); count++; } return count; } } }