void Collect <T>(FlowGraph graph, MonoBehaviour mb, FlowMacro flowMacro, string hierachy, SuperUnit inSuperUnit = null) { if (graph.IsUnityNull()) { return; } foreach (var unit in graph.units) { var unitData = new UnitData() { unit = unit, flowGraph = graph, flowMacro = flowMacro, monoBehaviour = mb, hierachy = hierachy, superUnit = inSuperUnit }; unitList.Add(unitData); // Traverse into SuperUnit if (unit.GetType() == typeof(SuperUnit)) { var superUnit = unit as SuperUnit; var nestGraph = superUnit.nest.graph; if (!superUnit.IsUnityNull() && !nestGraph.IsUnityNull() && nestGraph != graph) { // Collect recursive var superUnitName = (!string.IsNullOrEmpty(nestGraph.title)) ? nestGraph.title : superUnit.ToString(); var newHierachy = $@"{hierachy} [<color=blue>{superUnitName}</color>]"; Collect <T>(nestGraph, mb, flowMacro, newHierachy, superUnit); // SuperUnit input (default value) foreach (var vid in nestGraph.valueInputDefinitions) { if (vid.type == typeof(T) && vid.hasDefaultValue) { // Collect unitData.AddPortData(vid); } } } } var unitType = unit.GetType(); PropertyInfo[] pis = unitType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var pi in pis) { if (pi.PropertyType == typeof(ValueInput)) { ValueInput vi = pi.GetValue(unit) as ValueInput; // Collect specify type only if (!vi.IsUnityNull() && vi.type == typeof(T)) { // Collect! unitData.AddPortData(pi, vi); } } else if (pi.PropertyType == typeof(ValueOutput)) { ValueOutput vo = pi.GetValue(unit) as ValueOutput; // Collect specify type only if (!vo.IsUnityNull() && vo.type == typeof(T)) { // Collect! unitData.AddPortData(pi, vo); } } } FieldInfo[] fis = unitType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (var fi in fis) { // Collect specify type only if (fi.FieldType == typeof(T)) { var ins = fi.GetCustomAttribute <InspectableAttribute>(); var head = fi.GetCustomAttribute <UnitHeaderInspectableAttribute>(); if (ins != null || head != null) { // Collect! unitData.AddPortData(fi); } } } } }