插件加载进去后,在 Plugin 的构造方法内会调用一些方法来注册节点信息:
Plugin.RegisterTypeHandlers(_DesignerBaseDll);
Plugin.RegisterAgentTypes(_DesignerBaseDll);
Plugin.InitNodeGroups();
Plugin.RegisterNodeDesc(_DesignerBaseDll);
其中,RegisterNodeDesc 会根据节点的层次关系,生成一些描述节点。
这些描述节点会合并到 Plugin 类的 NodeGroup 类型的静态集合 _nodeGroups 中去, NodeGroup 是一种用于描述节点的、树状的结构类型。
在 BehaviocTreeList 类中有一个 LoadPlugins 方法会在 Workspace 发生变化的时候来进行调用,其会调用到一个 ToggleShowSelectedNodes 方法用于将刚刚得到的哪些描述信息来注册到 TreeView 来让屏幕上展示Node的结构,如下所示:

此外,在这个方法内也会调用 Register 方法创建Node类型所对应的 NodeTag 以用于后续生成时所需的一些信息。
以向行为树节点加入一个 True 节点为例:

在 BehaviorTreeView 类中有一个事件 BehaviorTreeView_DragDrop 会在你拖拽节点过来释放后触发,在经过多番校验后,会调用 InsertNewNode 方法来向目标节点进行插入新节点,根据对应的节点信息调用 newnode = Node.Create(nodetag.NodeType) 方法以创建新节点, InsertNewNode 方法签名如下:
/// <summary>
/// 把从节点浏览器中拖拽过来的节点连接到一个现有的节点上
/// </summary>
/// <param name="nvd"> 被连接到的节点,即目标节点 </param>
/// <param name="mode"> 连接的方式 </param>
/// <param name="nodetag"> 你想要创建的节点的tag,里面有类型信息 </param>
private void InsertNewNode(NodeViewData nvd, NodeAttachMode mode, NodeTag nodetag, PointF mousePos)
在这个方法中,会有很多的类型判断以采取不同的方案,在本例中,则会调用到 node.AddChild(_dragTargetConnector, newnode) 以将新创建的节点联系到目标节点上,在这个函数调用中,里面会有 connector.AcceptsChild(node) 方法的调用,以判断该目标节点能否接收这个新节点。
节点属性绘制以 Action 节点的 Method 属性为例,其绘制的效果如下:

在 PropertiesDock 类中,有一个 SelectedObject 属性用于保存当前选中的节点,在其 Set 函数中,会根据节点的类型来反射创建其相关属性,Method 即是其中之一。
在选中节点不为空的情况下,会调用方法 UpdateProperties 以绘制各属性。
在此方法中,会根据属性的类型,获取其对应的 Editor 的type,对于此例来说,调试的情况下可以看到类型是 DesignerMethodComboEnumEditor 。此类即Method属性的编辑器展示时的类型,其会缓存当前的Agent类型然后根据Agent的方法来改变枚举的值。
原文:https://www.cnblogs.com/lupin3/p/14386699.html