diff --git a/Scripts/Editor/Interfaces.meta b/Scripts/Editor/Interfaces.meta new file mode 100644 index 0000000..8c9618f --- /dev/null +++ b/Scripts/Editor/Interfaces.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ed2b909d4b55a0498bc7fcb43555699 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/Interfaces/ICustomEditor.cs b/Scripts/Editor/Interfaces/ICustomEditor.cs new file mode 100644 index 0000000..d87fd46 --- /dev/null +++ b/Scripts/Editor/Interfaces/ICustomEditor.cs @@ -0,0 +1,14 @@ +using UnityEditor; +using UnityEngine; + +namespace XNodeEditor { + /// + /// Workaround since c# doesn't support nested interfaces. + /// + /// Used with INodeEditor and INodeGraphEditor. + /// + public interface ICustomEditor { + T Target { get; } + SerializedObject SerializedObject { get; } + } +} \ No newline at end of file diff --git a/Scripts/Editor/Interfaces/ICustomEditor.cs.meta b/Scripts/Editor/Interfaces/ICustomEditor.cs.meta new file mode 100644 index 0000000..788dc4e --- /dev/null +++ b/Scripts/Editor/Interfaces/ICustomEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5085db84cab1cba42ad78c9310b87f36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/Interfaces/INodeEditor.cs b/Scripts/Editor/Interfaces/INodeEditor.cs new file mode 100644 index 0000000..eb62e65 --- /dev/null +++ b/Scripts/Editor/Interfaces/INodeEditor.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using XNode; + +namespace XNodeEditor { + public interface INodeGraphEditor { + INodeGraph target { get; } + void OnGUI(); + void OnOpen(); + Texture2D GetGridTexture(); + Texture2D GetSecondaryGridTexture(); + /// Return default settings for this graph type. This is the settings the user will load if no previous settings have been saved. + NodeEditorPreferences.Settings GetDefaultPreferences(); + /// Returns context node menu path. Null or empty strings for hidden nodes. + string GetNodeMenuName(Type type); + /// Add items for the context menu when right-clicking this node. Override to add custom menu items. + void AddContextMenuItems(GenericMenu menu); + Color GetPortColor(XNode.NodePort port); + Color GetTypeColor(Type type); + /// Create a node and save it in the graph asset + XNode.INode CreateNode(Type type, Vector2 position); + /// Creates a copy of the original node in the graph + XNode.INode CopyNode(XNode.INode original); + /// Safely remove a node and all its connections. + void RemoveNode(XNode.INode node); + } + + [AttributeUsage(AttributeTargets.Class)] + public class CustomNodeGraphEditorAttribute : Attribute, + XNodeEditor.Internal.INodeEditorAttrib { + private Type inspectedType; + public string editorPrefsKey; + /// Tells a NodeGraphEditor which Graph type it is an editor for + /// Type that this editor can edit + /// Define unique key for unique layout settings instance + public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings") { + this.inspectedType = inspectedType; + this.editorPrefsKey = editorPrefsKey; + } + + public Type GetInspectedType() { + return inspectedType; + } + } +} \ No newline at end of file diff --git a/Scripts/Editor/Interfaces/INodeEditor.cs.meta b/Scripts/Editor/Interfaces/INodeEditor.cs.meta new file mode 100644 index 0000000..57114eb --- /dev/null +++ b/Scripts/Editor/Interfaces/INodeEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9aa85d886a156c14eb60e06494ae40a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/Interfaces/INodeGraphEditor.cs b/Scripts/Editor/Interfaces/INodeGraphEditor.cs new file mode 100644 index 0000000..ce02796 --- /dev/null +++ b/Scripts/Editor/Interfaces/INodeGraphEditor.cs @@ -0,0 +1,16 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class INodeGraphEditor : MonoBehaviour { + + // Use this for initialization + void Start () { + + } + + // Update is called once per frame + void Update () { + + } +} diff --git a/Scripts/Editor/Interfaces/INodeGraphEditor.cs.meta b/Scripts/Editor/Interfaces/INodeGraphEditor.cs.meta new file mode 100644 index 0000000..8e4100c --- /dev/null +++ b/Scripts/Editor/Interfaces/INodeGraphEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 527d58696cdd32d429c4a4d93847ca2f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Editor/NodeEditorBase.cs b/Scripts/Editor/NodeEditorBase.cs index af371d6..39ae942 100644 --- a/Scripts/Editor/NodeEditorBase.cs +++ b/Scripts/Editor/NodeEditorBase.cs @@ -9,13 +9,13 @@ namespace XNodeEditor.Internal { /// Handles caching of custom editor classes and their target types. Accessible with GetEditor(Type type) /// Editor Type. Should be the type of the deriving script itself (eg. NodeEditor) /// Attribute Type. The attribute used to connect with the runtime type (eg. CustomNodeEditorAttribute) - /// Runtime Type. The Object this can be an editor for (eg. Node) - public abstract class NodeEditorBase : Editor where A : Attribute, INodeEditorAttrib where T : NodeEditorBase where K : UnityEngine.Object { + /// Runtime Type. The Object this can be an editor for (eg. INode ) + public abstract class NodeEditorBase : Editor where T : NodeEditorBase, ICustomEditor where A : Attribute, INodeEditorAttrib where K : class { /// Custom editors defined with [CustomNodeEditor] private static Dictionary editorTypes; private static Dictionary editors = new Dictionary(); public NodeEditorWindow window; - public new K target { get { return _target == base.target ? _target : _target = (K) base.target; } set { base.target = value; } } + public new K target { get { return _target as UnityEngine.Object == base.target ? _target : _target = base.target as K; } set { base.target = value as UnityEngine.Object; } } private K _target; public static T GetEditor(Q target, NodeEditorWindow window) where Q : class { diff --git a/Scripts/Editor/NodeGraphEditor.cs b/Scripts/Editor/NodeGraphEditor.cs index d0c4f71..f1304c2 100644 --- a/Scripts/Editor/NodeGraphEditor.cs +++ b/Scripts/Editor/NodeGraphEditor.cs @@ -3,13 +3,21 @@ using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; +using XNode; namespace XNodeEditor { - /// Base class to derive custom Node Graph editors from. Use this to override how graphs are drawn in the editor. + /// Base class to derive custom NodeGraph editors from. Use this to override how graphs are drawn in the editor. [CustomNodeGraphEditor(typeof(XNode.NodeGraph))] - public class NodeGraphEditor : XNodeEditor.Internal.NodeEditorBase { + public class NodeGraphEditor : XNodeEditor.Internal.NodeEditorBase, ICustomEditor, INodeGraphEditor { + + INodeGraph INodeGraphEditor.target { get { return base.target; } } + [Obsolete("Use window.position instead")] public Rect position { get { return window.position; } set { window.position = value; } } + + INodeGraph ICustomEditor.Target { get { return target as INodeGraph; } } + SerializedObject ICustomEditor.SerializedObject { get { return serializedObject; } } + /// Are we currently renaming a node? protected bool isRenaming; @@ -69,47 +77,48 @@ namespace XNodeEditor { } /// Create a node and save it in the graph asset - public virtual void CreateNode(Type type, Vector2 position) { - XNode.Node node = target.AddNode(type); - node.position = position; - if (string.IsNullOrEmpty(node.name)) node.name = UnityEditor.ObjectNames.NicifyVariableName(type.Name); - AssetDatabase.AddObjectToAsset(node, target); + public virtual XNode.INode CreateNode(Type type, Vector2 position) { + XNode.INode node = ((INodeGraph) target).AddNode(type); + node.Position = position; + if (string.IsNullOrEmpty(node.Name)) node.Name = UnityEditor.ObjectNames.NicifyVariableName(type.Name); + if (node is ScriptableObject) AssetDatabase.AddObjectToAsset(node as ScriptableObject, target); if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); NodeEditorWindow.RepaintAll(); + return node; } /// Creates a copy of the original node in the graph - public XNode.INode CopyNode(XNode.Node original) { - XNode.Node node = target.CopyNode( original); - node.name = original.name; - AssetDatabase.AddObjectToAsset(node, target); + public virtual XNode.INode CopyNode(XNode.INode original) { + XNode.INode node = ((INodeGraph) target).CopyNode(original); + node.Name = original.Name; + if (node is ScriptableObject) AssetDatabase.AddObjectToAsset(node as ScriptableObject, target); if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); return node; } /// Safely remove a node and all its connections. - public void RemoveNode(XNode.Node node) { - UnityEngine.Object.DestroyImmediate(node, true); - target.RemoveNode(node); + public void RemoveNode(XNode.INode node) { + UnityEngine.Object.DestroyImmediate(node as UnityEngine.Object, true); + ((INodeGraph) target).RemoveNode(node); if (NodeEditorPreferences.GetSettings().autoSave) AssetDatabase.SaveAssets(); } [AttributeUsage(AttributeTargets.Class)] public class CustomNodeGraphEditorAttribute : Attribute, - XNodeEditor.Internal.INodeEditorAttrib { - private Type inspectedType; - public string editorPrefsKey; - /// Tells a NodeGraphEditor which Graph type it is an editor for - /// Type that this editor can edit - /// Define unique key for unique layout settings instance - public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings") { - this.inspectedType = inspectedType; - this.editorPrefsKey = editorPrefsKey; - } + XNodeEditor.Internal.INodeEditorAttrib { + private Type inspectedType; + public string editorPrefsKey; + /// Tells a NodeGraphEditor which Graph type it is an editor for + /// Type that this editor can edit + /// Define unique key for unique layout settings instance + public CustomNodeGraphEditorAttribute(Type inspectedType, string editorPrefsKey = "xNode.Settings") { + this.inspectedType = inspectedType; + this.editorPrefsKey = editorPrefsKey; + } - public Type GetInspectedType() { - return inspectedType; + public Type GetInspectedType() { + return inspectedType; + } } - } } } \ No newline at end of file