public virtual void AddChildNodes(NodeComponent nodeComponent, TreeViewItem parentTree, IList <TreeViewItem> rows) { var fields = EditorReflectionUtility.GetFields(nodeComponent.GetType()); foreach (var field in fields) { var fieldType = field.FieldType; if (field.IsDefinedAttribute(typeof(FieldConnectionAttribute))) { var attributes = EditorReflectionUtility.GetAttributes(field); var FCA = ReflectionUtils.GetAttribute <FieldConnectionAttribute>(attributes); bool isFlow = nodeComponent is Node && (nodeComponent as Node).IsFlowNode(); if (FCA.hideOnFlowNode && isFlow) { continue; } if (FCA.hideOnNotFlowNode && !isFlow) { continue; } if (fieldType == typeof(MemberData)) { if (FCA.isFlowConnection) { MemberData member = field.GetValueOptimized(nodeComponent) as MemberData; if (member != null) { if (!FCA.isFinishedFlow && field.Name != nameof(MultipurposeNode.onFinished)) { if (FCA.displayFlowInHierarchy) { var flowItem = CreateFlowTree( nodeComponent, field.Name, member, FCA.label != null ? FCA.label.text : field.Name ); parentTree.AddChild(flowItem); rows.Add(flowItem); manager.AddNodeTree(member, flowItem, rows); } else { manager.AddNodeTree(member, parentTree, rows); } } else { manager.AddNodeTree(member, parentTree, rows, false); } } } } else if (fieldType == typeof(List <MemberData>) && FCA.isFlowConnection) { List <MemberData> members = field.GetValueOptimized(nodeComponent) as List <MemberData>; if (members != null && members.Count > 0) { foreach (var member in members) { if (member != null && member.isAssigned && member.IsTargetingPinOrNode) { Node n = member.GetTargetNode(); if (n != null) { manager.AddNodes(n, parentTree, rows, isChildren: !FCA.isFinishedFlow && field.Name != nameof(MultipurposeNode.onFinished)); } } } } } } else if (fieldType == typeof(EventData)) { var blocks = field.GetValueOptimized(nodeComponent) as EventData; AddBlocks(blocks, field.Name, parentTree, rows); } } }