diff --git a/Scripts/Editor/NodeEditorGUI.cs b/Scripts/Editor/NodeEditorGUI.cs
index 476153d..41df407 100644
--- a/Scripts/Editor/NodeEditorGUI.cs
+++ b/Scripts/Editor/NodeEditorGUI.cs
@@ -75,6 +75,17 @@ namespace XNodeEditor {
public void ShowNodeContextMenu(Node node) {
GenericMenu contextMenu = new GenericMenu();
contextMenu.AddItem(new GUIContent("Remove"), false, () => graph.RemoveNode(node));
+ contextMenu.AddItem(new GUIContent("Duplicate"), false, () => {
+ Node n = graph.CopyNode(node);
+ n.position = node.position + new Vector2(30,30);
+ });
+ contextMenu.AddItem(new GUIContent("Move To Top"), false, () => {
+ int index;
+ while((index = graph.nodes.IndexOf(node)) != graph.nodes.Count-1) {
+ graph.nodes[index] = graph.nodes[index+1];
+ graph.nodes[index+1] = node;
+ }
+ });
AddCustomContextMenuItems(contextMenu, node);
contextMenu.DropDown(new Rect(Event.current.mousePosition, Vector2.zero));
}
diff --git a/Scripts/NodeGraph.cs b/Scripts/NodeGraph.cs
index 8253a42..f6ff86d 100644
--- a/Scripts/NodeGraph.cs
+++ b/Scripts/NodeGraph.cs
@@ -11,10 +11,12 @@ namespace XNode {
/// See:
[SerializeField] public List nodes = new List();
+ /// Add a node to the graph by type
public T AddNode() where T : Node {
return AddNode(typeof(T)) as T;
}
+ /// Add a node to the graph by type
public virtual Node AddNode(Type type) {
Node node = ScriptableObject.CreateInstance(type) as Node;
#if UNITY_EDITOR
@@ -28,6 +30,21 @@ namespace XNode {
return node;
}
+ /// Creates a copy of the original node in the graph
+ public virtual Node CopyNode(Node original) {
+ Node node = ScriptableObject.Instantiate(original);
+ node.ClearConnections();
+#if UNITY_EDITOR
+ if (!Application.isPlaying) {
+ UnityEditor.AssetDatabase.AddObjectToAsset(node, this);
+ UnityEditor.AssetDatabase.SaveAssets();
+ }
+#endif
+ nodes.Add(node);
+ node.graph = this;
+ return node;
+ }
+
/// Safely remove a node and all its connections
///
public void RemoveNode(Node node) {