├── .gitignore
├── .gitlab-ci.yml
├── Attributes.cs
├── Attributes.cs.meta
├── DaGenGraph.asmdef
├── DaGenGraph.asmdef.meta
├── Edge.cs
├── Edge.cs.meta
├── Editor.meta
├── Editor
├── DaGenGraph.Editor.asmdef
├── DaGenGraph.Editor.asmdef.meta
├── DrawBase.cs
├── DrawBase.cs.meta
├── EdgeView.cs
├── EdgeView.cs.meta
├── GraphBackGround.cs
├── GraphBackGround.cs.meta
├── GraphHandle.cs
├── GraphHandle.cs.meta
├── GraphWindow.cs
├── GraphWindow.cs.meta
├── GraphWindowDraw.cs
├── GraphWindowDraw.cs.meta
├── GroupInfo.cs
├── GroupInfo.cs.meta
├── NodeView.cs
├── NodeView.cs.meta
├── Tool.meta
└── Tool
│ ├── ColorExtensions.cs
│ ├── ColorExtensions.cs.meta
│ ├── Styles.cs
│ ├── Styles.cs.meta
│ ├── UIColor.cs
│ └── UIColor.cs.meta
├── Example.meta
├── Example
├── DaGenGraph.Example.asmdef
├── DaGenGraph.Example.asmdef.meta
├── ExampleGraph.cs
├── ExampleGraph.cs.meta
├── ExampleGraphWindow.cs
├── ExampleGraphWindow.cs.meta
├── ExampleNode.cs
├── ExampleNode.cs.meta
├── ExampleNodeView.cs
└── ExampleNodeView.cs.meta
├── GraphBase.cs
├── GraphBase.cs.meta
├── JsonGraphBase.cs
├── JsonGraphBase.cs.meta
├── JsonNodeBase.cs
├── JsonNodeBase.cs.meta
├── NodeBase.cs
├── NodeBase.cs.meta
├── Port.cs
├── Port.cs.meta
├── Style.meta
├── Style
├── DarkSkin.guiskin
├── DarkSkin.guiskin.meta
├── UIColor.asset
└── UIColor.asset.meta
├── Texture.meta
├── Texture
├── BackgroundRoundDark.png
├── BackgroundRoundDark.png.meta
├── BackgroundSquareDark.png
├── BackgroundSquareDark.png.meta
├── ConnectionPointMinusNormalDark.png
├── ConnectionPointMinusNormalDark.png.meta
├── ConnectionPointMultipleConnectedNormalDark.png
├── ConnectionPointMultipleConnectedNormalDark.png.meta
├── ConnectionPointMultipleEmptyNormalDark.png
├── ConnectionPointMultipleEmptyNormalDark.png.meta
├── ConnectionPointOverrideConnectedNormalDark.png
├── ConnectionPointOverrideConnectedNormalDark.png.meta
├── ConnectionPointOverrideEmptyNormalDark.png
├── ConnectionPointOverrideEmptyNormalDark.png.meta
├── NodeBodyDark.png
├── NodeBodyDark.png.meta
├── NodeDotDark.png
├── NodeDotDark.png.meta
├── NodeFooterDark.png
├── NodeFooterDark.png.meta
├── NodeGlowDark.png
├── NodeGlowDark.png.meta
├── NodeHeaderDark.png
├── NodeHeaderDark.png.meta
├── NodeOutlineDark.png
└── NodeOutlineDark.png.meta
├── TypeHelper.cs
├── TypeHelper.cs.meta
├── ValueDropdownItem.cs
├── ValueDropdownItem.cs.meta
├── VirtualPoint.cs
├── VirtualPoint.cs.meta
├── package.json
└── package.json.meta
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 |
7 | # Autogenerated VS solution and project files
8 | ExportedObj/
9 | *.csproj
10 | *.unityproj
11 | *.sln
12 | *.suo
13 | *.tmp
14 | *.user
15 | *.userprefs
16 | *.pidb
17 | *.booproj
18 | *.svd
19 | .vs/
20 |
21 | # VScode ide files
22 | .vscode
23 |
24 | # Unity3D generated meta files
25 | *.pidb.meta
26 |
27 | # Unity3D Generated File On Crash Reports
28 | sysinfo.txt
29 |
30 | # Builds
31 | *.apk
32 |
33 | ============
34 | OS generated
35 | ============
36 | .DS_Store
37 | .DS_Store?
38 | ._*
39 | .Spotlight-V100
40 | .Trashes
41 | ehthumbs.db
42 | Thumbs.db
43 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/.gitlab-ci.yml
--------------------------------------------------------------------------------
/Attributes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | #if !ODIN_INSPECTOR
3 | using UnityEditor;
4 | #endif
5 | namespace DaGenGraph
6 | {
7 | public enum Ignore
8 | {
9 | All,
10 | Details,
11 | NodeView,
12 | }
13 |
14 | [AttributeUsage(AttributeTargets.Field)]
15 | public class DrawIgnoreAttribute : Attribute
16 | {
17 | public Ignore Ignore;
18 |
19 | public DrawIgnoreAttribute()
20 | {
21 | Ignore = Ignore.All;
22 | }
23 |
24 | public DrawIgnoreAttribute(Ignore type)
25 | {
26 | Ignore = type;
27 | }
28 | }
29 |
30 | [AttributeUsage(AttributeTargets.Class)]
31 | public class NodeViewTypeAttribute : Attribute
32 | {
33 | public NodeViewTypeAttribute(Type baseViewNode)
34 | {
35 | ViewType = baseViewNode;
36 | }
37 |
38 | public Type ViewType;
39 | }
40 |
41 | ///
42 | /// ScriptableObject专用,指定该项不是资源
43 | ///
44 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
45 | public class NotAssetsAttribute : Attribute
46 | {
47 |
48 | }
49 |
50 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
51 | public class PortGroupAttribute : Attribute
52 | {
53 | public int Group;
54 |
55 | public PortGroupAttribute(int group)
56 | {
57 | Group = group;
58 | }
59 | }
60 |
61 |
62 | #if !ODIN_INSPECTOR
63 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
64 | public class OnStateUpdateAttribute : Attribute
65 | {
66 | public string Action;
67 |
68 | public OnStateUpdateAttribute(string action) => this.Action = action;
69 | }
70 |
71 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
72 | public class OnCollectionChangedAttribute : Attribute
73 | {
74 | public string After;
75 | public OnCollectionChangedAttribute(string after) => this.After = after;
76 | }
77 |
78 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
79 | public class TypeFilterAttribute : Attribute
80 | {
81 | public string FilterGetter;
82 | public TypeFilterAttribute(string filterGetter) => this.FilterGetter = filterGetter;
83 | }
84 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
85 | public class HideReferenceObjectPickerAttribute : Attribute
86 | {
87 | }
88 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
89 | public class MinValueAttribute : Attribute
90 | {
91 | public double MinValue;
92 | public MinValueAttribute(double minValue) => this.MinValue = minValue;
93 | }
94 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
95 | public class MaxValueAttribute : Attribute
96 | {
97 | public double MaxValue;
98 | public MaxValueAttribute(double maxValue) => this.MaxValue = maxValue;
99 | }
100 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
101 | public class DisableInEditorModeAttribute : Attribute
102 | {
103 |
104 | }
105 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
106 | public class OnValueChangedAttribute : Attribute
107 | {
108 | public string Action;
109 |
110 | public OnValueChangedAttribute(string action)
111 | {
112 | Action = action;
113 | }
114 | }
115 |
116 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
117 | public class PropertyOrderAttribute : Attribute
118 | {
119 | public float Order;
120 | public PropertyOrderAttribute(){}
121 | public PropertyOrderAttribute(float order)
122 | {
123 | Order = order;
124 | }
125 | }
126 |
127 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
128 | public class BoxGroupAttribute : Attribute
129 | {
130 | public string GroupID;
131 |
132 | public BoxGroupAttribute(string groupID)
133 | {
134 | GroupID = groupID;
135 | }
136 | }
137 |
138 | [AttributeUsage(AttributeTargets.Method)]
139 | public class ButtonAttribute : Attribute
140 | {
141 | public string Name;
142 |
143 | public ButtonAttribute(string name)
144 | {
145 | Name = name;
146 | }
147 |
148 | }
149 |
150 | public class ReadOnlyAttribute : Attribute
151 | {
152 | }
153 |
154 | public class InfoBoxAttribute : Attribute
155 | {
156 |
157 | public string Message;
158 |
159 | public MessageType InfoMessageType;
160 |
161 | public InfoBoxAttribute(
162 | string message,
163 | MessageType infoMessageType = MessageType.Info)
164 | {
165 | this.Message = message;
166 | this.InfoMessageType = infoMessageType;
167 | }
168 |
169 | public InfoBoxAttribute(string message)
170 | {
171 | this.Message = message;
172 | this.InfoMessageType = MessageType.Info;
173 | }
174 | }
175 |
176 | public class LabelTextAttribute : Attribute
177 | {
178 | public LabelTextAttribute(string text)
179 | {
180 | Text = text;
181 | }
182 |
183 | public string Text;
184 | }
185 |
186 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
187 | public class ShowIfAttribute : Attribute
188 | {
189 |
190 | public string Condition;
191 | public object Value;
192 |
193 | public ShowIfAttribute(string condition)
194 | {
195 | Condition = condition;
196 | }
197 |
198 | public ShowIfAttribute(string condition, object optionalValue)
199 | {
200 | this.Condition = condition;
201 | this.Value = optionalValue;
202 | }
203 | }
204 |
205 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
206 | public class ValueDropdownAttribute : Attribute
207 | {
208 | public string ValuesGetter;
209 | public bool AppendNextDrawer;
210 | public ValueDropdownAttribute(string valuesGetter)
211 | {
212 | ValuesGetter = valuesGetter;
213 | }
214 | }
215 |
216 | #endif
217 | }
--------------------------------------------------------------------------------
/Attributes.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6e4ad200c9d8413b8b423dc29246170d
3 | timeCreated: 1737185096
--------------------------------------------------------------------------------
/DaGenGraph.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DaGenGraph",
3 | "rootNamespace": "",
4 | "references": [],
5 | "includePlatforms": [],
6 | "excludePlatforms": [],
7 | "allowUnsafeCode": false,
8 | "overrideReferences": false,
9 | "precompiledReferences": [],
10 | "autoReferenced": true,
11 | "defineConstraints": [],
12 | "versionDefines": [],
13 | "noEngineReferences": false
14 | }
--------------------------------------------------------------------------------
/DaGenGraph.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b637e77054d21444096d4d4e5637ed30
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Edge.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Unity.Collections;
3 | using UnityEngine;
4 |
5 | namespace DaGenGraph
6 | {
7 | public class Edge: ScriptableObject
8 | {
9 | #region Properties
10 |
11 | /// [Editor Only] Pings this Edge
12 | [NonSerialized] public bool ping;
13 | /// [Editor Only] ReSet Animation Time
14 | [NonSerialized] public bool reSetTime;
15 | [NonSerialized]public Vector2 inputEdgePoint;
16 | [NonSerialized]public Vector2 outputEdgePoint;
17 | #endregion
18 |
19 | #region public Variables
20 |
21 | public string id;
22 | public string inputNodeId;
23 | public string inputPortId;
24 | public string outputNodeId;
25 | public string outputPortId;
26 |
27 | #endregion
28 |
29 | #region Constructors
30 |
31 |
32 | /// Creates a new instance for this class between two ports (Input - Output or Output - Input)
33 | /// port One
34 | /// port Two
35 | public void Init(Port port1, Port port2)
36 | {
37 | GenerateNewId();
38 | if (port1.IsOutput() && port2.IsInput())
39 | {
40 | inputNodeId = port2.nodeId;
41 | inputPortId = port2.id;
42 | inputEdgePoint = port2.GetClosestEdgePointToPort(port2);
43 |
44 | outputNodeId = port1.nodeId;
45 | outputPortId = port1.id;
46 | outputEdgePoint = port1.GetClosestEdgePointToPort(port1);
47 | }
48 |
49 | if (port2.IsOutput() && port1.IsInput())
50 | {
51 | inputNodeId = port1.nodeId;
52 | inputPortId = port1.id;
53 | inputEdgePoint = port1.GetClosestEdgePointToPort(port1);
54 |
55 | outputNodeId = port2.nodeId;
56 | outputPortId = port2.id;
57 | outputEdgePoint = port2.GetClosestEdgePointToPort(port2);
58 | }
59 | }
60 |
61 | #endregion
62 |
63 | #region private Methods
64 |
65 | /// Generates a new id for this connections and returns it
66 | private string GenerateNewId()
67 | {
68 | id = Guid.NewGuid().ToString();
69 | return id;
70 | }
71 |
72 | #endregion
73 |
74 | }
75 | }
--------------------------------------------------------------------------------
/Edge.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 39d2f4c7ff7e4462835d2b5f6dcb6785
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: abd3eaa5e84b4c1da5b9f93b27ee0f28
3 | timeCreated: 1623032904
--------------------------------------------------------------------------------
/Editor/DaGenGraph.Editor.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DaGenGraph.Editor",
3 | "rootNamespace": "",
4 | "references": [
5 | "GUID:b637e77054d21444096d4d4e5637ed30"
6 | ],
7 | "includePlatforms": [],
8 | "excludePlatforms": [],
9 | "allowUnsafeCode": false,
10 | "overrideReferences": false,
11 | "precompiledReferences": [],
12 | "autoReferenced": true,
13 | "defineConstraints": [],
14 | "versionDefines": [],
15 | "noEngineReferences": false
16 | }
--------------------------------------------------------------------------------
/Editor/DaGenGraph.Editor.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 82c60e129e644f1a875828179b3e9c80
3 | timeCreated: 1623032884
--------------------------------------------------------------------------------
/Editor/DrawBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 40c13006090b4fdbaf0a069d11ab91e3
3 | timeCreated: 1737444475
--------------------------------------------------------------------------------
/Editor/EdgeView.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor.AnimatedValues;
2 | using UnityEngine;
3 |
4 | namespace DaGenGraph.Editor
5 | {
6 | public class EdgeView
7 | {
8 | /// The connection id. Every connection will have a record on two sockets (the output socket and the input socket)
9 | public string edgeId;
10 | /// Reference to the OutputPort Node of this connections
11 | public NodeBase outputNode;
12 | /// Reference to the OutputPort Port of the OutputPort Node of this connection
13 | public Port outputPort;
14 | /// Reference to the InputPort Node of this connection
15 | public NodeBase inputNode;
16 | /// Reference to the InputPort Port of the InputPort Node of this connection
17 | public Port inputPort;
18 | /// Reference to the OutputPort Virtual Point of this connection
19 | public VirtualPoint outputVirtualPoint;
20 | /// Reference to the InputPort Virtual Point of this connection
21 | public VirtualPoint inputVirtualPoint;
22 | /// Holds the last calculated value of the OutputPort Tangent in order to draw the connection curve (huge performance boost as we won't need to recalculate it on every frame)
23 | public Vector2 outputTangent = Vector2.zero;
24 | /// Holds the last calculated value of the InputPort Tangent in order to draw the connection curve (huge performance boost as we won't need to recalculate it on every frame)
25 | public Vector2 inputTangent = Vector2.zero;
26 | // public AnimBool ping = new AnimBool {speed = 0.6f};
27 | //TODO Edge Shader
28 | // /// Lightweight handles material
29 | // private static Material s_HandleMaterial;
30 | //
31 | // /// Returns a lightweight handles material
32 | // private static Material handleMaterial
33 | // {
34 | // get
35 | // {
36 | // if (s_HandleMaterial != null) return s_HandleMaterial;
37 | // Shader shader = Shader.Find("Hidden/Nody/LineDraw");
38 | // var m = new Material(shader) {hideFlags = HideFlags.HideAndDontSave};
39 | // s_HandleMaterial = m;
40 | // return s_HandleMaterial;
41 | // }
42 | // }
43 | }
44 | }
--------------------------------------------------------------------------------
/Editor/EdgeView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3aef23d0a7e74cdb8c058f30728ddd02
3 | timeCreated: 1623033614
--------------------------------------------------------------------------------
/Editor/GraphBackGround.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 | using UnityEngine.Rendering;
4 |
5 | namespace DaGenGraph.Editor
6 | {
7 | public static class GraphBackground
8 | {
9 | private const float MINOR_GRID_SIZE = 10f;
10 | private const float MAJOR_GRID_SIZE = 100f;
11 |
12 | private static readonly Color s_GridMinorColorDark = new Color(0f, 0f, 0f, 0.18f);
13 | private static readonly Color s_GridMajorColorDark = new Color(0f, 0f, 0f, 0.28f);
14 | private static readonly int s_HandleZTest = Shader.PropertyToID("_HandleZTest");
15 |
16 | public static void DrawGrid(Rect gridRect, float zoomLevel, Vector2 panOffset)
17 | {
18 | if (Event.current.type != EventType.Repaint) return;
19 |
20 | //draw background
21 | UnityEditor.Graphs.Styles.graphBackground.Draw(gridRect, false, false, false, false);
22 |
23 | HandleUtility.ApplyWireMaterial();
24 | GL.PushMatrix();
25 | GL.Begin(1);
26 | var t = Mathf.InverseLerp(0.1f, 1f, zoomLevel);
27 | DrawGridLines(gridRect, MINOR_GRID_SIZE * zoomLevel, Color.Lerp(Color.clear, s_GridMinorColorDark, t),
28 | panOffset);
29 | DrawGridLines(gridRect, MAJOR_GRID_SIZE * zoomLevel, Color.Lerp(s_GridMinorColorDark, s_GridMajorColorDark, t),
30 | panOffset);
31 | GL.End();
32 | GL.PopMatrix();
33 | }
34 |
35 | private static void DrawGridLines(Rect gridRect, float gridSize, Color gridColor, Vector2 panOffset)
36 | {
37 | //vertical lines
38 | GL.Color(gridColor);
39 | var scaledOffsetX = -panOffset.x + panOffset.x % gridSize;
40 | var x = gridRect.xMin - gridRect.xMin % gridSize + scaledOffsetX;
41 | while (x < (double) gridRect.xMax + scaledOffsetX)
42 | {
43 | DrawLine(new Vector2(x + panOffset.x, gridRect.yMin), new Vector2(x + panOffset.x, gridRect.yMax));
44 | x += gridSize;
45 | }
46 | //horizontal lines
47 | GL.Color(gridColor);
48 | var scaledOffsetY = -panOffset.y + panOffset.y % gridSize;
49 | var y = gridRect.yMin - gridRect.yMin % gridSize + scaledOffsetY;
50 | while (y < (double) gridRect.yMax + scaledOffsetY)
51 | {
52 | DrawLine(new Vector2(gridRect.xMin, y + panOffset.y), new Vector2(gridRect.xMax, y + panOffset.y));
53 | y += gridSize;
54 | }
55 | }
56 |
57 | private static void DrawLine(Vector2 p1, Vector2 p2)
58 | {
59 | GL.Vertex(p1);
60 | GL.Vertex(p2);
61 | }
62 |
63 | // Implementation from UnityEditor.HandleUtility
64 | private static class HandleUtility
65 | {
66 | private static Material s_HandleWireMaterial;
67 | private static Material s_HandleWireMaterial2D;
68 |
69 | internal static void ApplyWireMaterial(CompareFunction zTest = CompareFunction.Always)
70 | {
71 | var wireMaterial = HandleUtility.handleWireMaterial;
72 | wireMaterial.SetInt(s_HandleZTest, (int) zTest);
73 | wireMaterial.SetPass(0);
74 | }
75 |
76 | private static Material handleWireMaterial
77 | {
78 | get
79 | {
80 | InitHandleMaterials();
81 | return !Camera.current ? s_HandleWireMaterial2D : s_HandleWireMaterial;
82 | }
83 | }
84 |
85 | private static void InitHandleMaterials()
86 | {
87 | if (s_HandleWireMaterial) return;
88 | s_HandleWireMaterial = (Material) EditorGUIUtility.LoadRequired("SceneView/HandleLines.mat");
89 | s_HandleWireMaterial2D = (Material) EditorGUIUtility.LoadRequired("SceneView/2DHandleLines.mat");
90 | }
91 | }
92 | }
93 | }
--------------------------------------------------------------------------------
/Editor/GraphBackGround.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1483877cf997458686e059e413fa85e5
3 | timeCreated: 1623033535
--------------------------------------------------------------------------------
/Editor/GraphHandle.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2cfca6f381e44aad8f6d88641061575f
3 | timeCreated: 1623046865
--------------------------------------------------------------------------------
/Editor/GraphWindow.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Reflection;
4 | using UnityEditor;
5 | using UnityEditor.AnimatedValues;
6 | using UnityEngine;
7 |
8 | namespace DaGenGraph.Editor
9 | {
10 | public abstract partial class GraphWindow : DrawBase
11 | {
12 | protected GraphBase m_Graph;
13 | private GraphMode m_Mode = GraphMode.None;
14 | private float m_Timer;
15 | private float m_LastUpdateTime;
16 | private float m_AniTime;
17 | private bool m_AnimateInput;
18 | private bool m_AnimateOutput;
19 | private bool m_HasFocus;
20 | private float m_CurrentZoom = 1f;
21 | private Rect m_GraphAreaIncludingTab;
22 | private Rect m_ScaledGraphArea;
23 | private bool m_DrawInspector = true;
24 | private Dictionary m_NodeViews;
25 | private Dictionary> m_Points;
26 | private Dictionary m_Ports;
27 | private Dictionary m_EdgeViews;
28 |
29 | private float m_NodeInspectorWidth = 400;
30 | private float currentZoom
31 | {
32 | get
33 | {
34 | if (m_Graph != null)
35 | {
36 | m_CurrentZoom = m_Graph.currentZoom;
37 | }
38 |
39 | return m_CurrentZoom;
40 | }
41 | set
42 | {
43 | m_CurrentZoom = value;
44 | if (m_Graph != null)
45 | {
46 | m_Graph.currentZoom = m_CurrentZoom;
47 | }
48 | }
49 | }
50 |
51 | private Dictionary edgeViews
52 | {
53 | get
54 | {
55 | if (m_EdgeViews != null) return m_EdgeViews;
56 | m_EdgeViews = new Dictionary();
57 | foreach (var port in ports.Values)
58 | {
59 | for (int i = port.edges.Count - 1; i >= 0; i--)
60 | {
61 | var edgeId = port.edges[i];
62 | var edge = m_Graph.GetEdge(edgeId);
63 | if (edge == null)
64 | {
65 | port.edges.RemoveAt(i);
66 | continue;
67 | }
68 |
69 | if (!nodeViews.ContainsKey(edge.inputNodeId) ||
70 | !nodeViews.ContainsKey(edge.outputNodeId))
71 | {
72 | port.ContainsEdge(edge.id);
73 | continue;
74 | }
75 |
76 | //check if the EdgeViews id has been added to the dictionary
77 | if (!m_EdgeViews.ContainsKey(edge.id))
78 | m_EdgeViews.Add(edge.id, new EdgeView { edgeId = edge.id });
79 | if (edge.inputPortId == port.id)
80 | m_EdgeViews[edge.id].inputPort =
81 | port; //reference this Prot if it is the EdgeViews's InputProt
82 | if (edge.inputNodeId == port.nodeId)
83 | m_EdgeViews[edge.id].inputNode =
84 | nodeViews[port.nodeId].node; //reference this Prot's parent as the InputNode
85 | if (edge.outputPortId == port.id)
86 | m_EdgeViews[edge.id].outputPort =
87 | port; //reference this socket if it is the EdgeView's OutputProt
88 | if (edge.outputNodeId == port.nodeId)
89 | m_EdgeViews[edge.id].outputNode =
90 | nodeViews[port.nodeId].node; //reference this Prot's parent as the OutputNode
91 | }
92 | }
93 |
94 | return m_EdgeViews;
95 | }
96 | }
97 |
98 | private Dictionary ports
99 | {
100 | get
101 | {
102 | if (m_Ports != null)
103 | {
104 | return m_Ports;
105 | }
106 |
107 | m_Ports = new Dictionary();
108 | foreach (var nodeView in nodeViews.Values)
109 | {
110 | for (var i = nodeView.node.inputPorts.Count - 1; i >= 0; i--)
111 | {
112 | var inputSocket = nodeView.node.inputPorts[i];
113 | if (inputSocket == null)
114 | {
115 | nodeView.node.inputPorts.RemoveAt(i);
116 | continue;
117 | }
118 |
119 | m_Ports.Add(inputSocket.id, inputSocket);
120 | }
121 |
122 | for (int i = nodeView.node.outputPorts.Count - 1; i >= 0; i--)
123 | {
124 | Port outputSocket = nodeView.node.outputPorts[i];
125 | if (outputSocket == null)
126 | {
127 | nodeView.node.outputPorts.RemoveAt(i);
128 | continue;
129 | }
130 |
131 | m_Ports.Add(outputSocket.id, outputSocket);
132 | }
133 | }
134 |
135 | return m_Ports;
136 | }
137 | }
138 |
139 | private Dictionary> points
140 | {
141 | get
142 | {
143 | if (m_Points != null)
144 | {
145 | return m_Points;
146 | }
147 |
148 | m_Points = new Dictionary>();
149 | foreach (var nodeView in nodeViews.Values)
150 | {
151 | if (nodeView.node.inputPorts != null)
152 | {
153 | foreach (var port in nodeView.node.inputPorts)
154 | {
155 | if(port==null) continue;
156 | m_Points.Add(port.id, new List());
157 | foreach (var point in port.GetEdgePoints())
158 | {
159 | m_Points[port.id].Add(new VirtualPoint(nodeViews[port.nodeId].node, port,
160 | point + m_Graph.currentPanOffset / currentZoom, point));
161 | }
162 | }
163 | }
164 |
165 | if (nodeView.node.outputPorts != null)
166 | {
167 | foreach (var port in nodeView.node.outputPorts)
168 | {
169 | if(port==null) continue;
170 | m_Points.Add(port.id, new List());
171 | foreach (var point in port.GetEdgePoints())
172 | {
173 | m_Points[port.id].Add(new VirtualPoint(nodeViews[port.nodeId].node, port,
174 | point + m_Graph.currentPanOffset / currentZoom, point));
175 | }
176 | }
177 | }
178 | }
179 |
180 | return m_Points;
181 | }
182 | }
183 |
184 | private Dictionary nodeViews => m_NodeViews;
185 |
186 | protected virtual void OnEnable()
187 | {
188 | m_AltKeyPressedAnimBool = new AnimBool(false, Repaint);
189 | m_NodeViews = new Dictionary();
190 | AddButton(new GUIContent("新建"), InitGraph);
191 | AddButton(new GUIContent("打开"), LoadGraph);
192 | AddButton(new GUIContent("保存"), SaveGraph);
193 | AddButton(new GUIContent("详情面板"), ChangeDrawInspector, false);
194 | }
195 |
196 | private void OnGUI()
197 | {
198 | var evt = Event.current;
199 | if (evt.type is EventType.DragUpdated or EventType.DragPerform)
200 | {
201 | if (DragAndDrop.objectReferences.ToList().Exists(o => !(o is GameObject)))
202 | {
203 | return;
204 | }
205 |
206 | DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
207 | if (evt.type == EventType.DragPerform)
208 | {
209 | DragAndDrop.AcceptDrag();
210 | OnGameObjectsDragIn(DragAndDrop.objectReferences.Cast().ToArray(),
211 | evt.mousePosition);
212 | }
213 | }
214 |
215 | DrawViewGraph();
216 | }
217 |
218 | private void Update()
219 | {
220 | float curTime = Time.realtimeSinceStartup;
221 | m_LastUpdateTime = Mathf.Min(m_LastUpdateTime, curTime); //very important!!!
222 | m_Timer = curTime - m_LastUpdateTime;
223 | m_LastUpdateTime = curTime;
224 | }
225 |
226 | private void OnFocus()
227 | {
228 | m_HasFocus = true;
229 | }
230 |
231 | private void OnLostFocus()
232 | {
233 | m_HasFocus = false;
234 | // m_SelectedNodes.Clear();
235 | // UpdateNodesSelectedState(m_SelectedNodes);
236 | }
237 |
238 | private void ChangeDrawInspector()
239 | {
240 | m_DrawInspector = !m_DrawInspector;
241 | }
242 |
243 | private void DrawViewGraph()
244 | {
245 | float nodeInspectorWidth = m_DrawInspector?m_NodeInspectorWidth:0;
246 | ConstructGraphGUI();
247 | var graphViewArea = new Rect(0, 0, position.width - nodeInspectorWidth, position.height);
248 | GraphBackground.DrawGrid(graphViewArea, currentZoom, Vector2.zero);
249 | if(m_DrawInspector) DrawInspector(graphViewArea.width, nodeInspectorWidth);
250 | m_GraphAreaIncludingTab = new Rect(0, 20, position.width, position.height);
251 | m_ScaledGraphArea = new Rect(0, 0, graphViewArea.width / currentZoom, graphViewArea.height / currentZoom);
252 | var initialMatrix = GUI.matrix; //save initial matrix
253 | HandleMouseHover();
254 | GUI.EndClip();
255 | GUI.BeginClip(new Rect(m_GraphAreaIncludingTab.position, m_ScaledGraphArea.size));
256 | var translation = Matrix4x4.TRS(m_GraphAreaIncludingTab.position, Quaternion.identity, Vector3.one);
257 | var scale = Matrix4x4.Scale(Vector3.one * currentZoom);
258 | {
259 | GUI.matrix = translation * scale * translation.inverse;
260 | {
261 | DrawEdges();
262 | DrawNodes(graphViewArea);
263 | DrawPortsEdgePoints();
264 | DrawLineFromPortToPosition(m_ActivePort, Event.current.mousePosition);
265 | DrawSelectionBox();
266 | }
267 | }
268 | GUI.EndClip();
269 | GUI.BeginClip(m_GraphAreaIncludingTab);
270 | GUI.matrix = initialMatrix; //reset the matrix to the initial value
271 | DrawToolbar();
272 |
273 | HandleZoom();
274 | HandlePanning();
275 | HandleMouseRightClicks();
276 | HandleMouseMiddleClicks();
277 | HandleMouseLeftClicks();
278 | HandleKeys();
279 | WhileDraggingUpdateSelectedNodes();
280 | }
281 |
282 | private void WhileDraggingUpdateSelectedNodes()
283 | {
284 | if (m_Mode != GraphMode.Drag) return;
285 |
286 | var validatePointsDatabase = false; //bool that triggers a PointsDatabase validation
287 | var validateConnectionsDatabase = false; //bool that triggers a ConnectionsDatabase validation
288 |
289 | foreach (var selectedNode in m_SelectedNodes) //go through all the selected nodes
290 | {
291 | foreach (var virtualPoints in selectedNode.outputPorts.Select(outputSocket => points[outputSocket.id]))
292 | {
293 | if (virtualPoints == null)
294 | {
295 | validatePointsDatabase = true;
296 | continue;
297 | }
298 |
299 | foreach (var virtualPoint in virtualPoints)
300 | {
301 | if (virtualPoint == null) //point is null -> trigger validation
302 | {
303 | validatePointsDatabase = true;
304 | continue;
305 | }
306 |
307 | if (virtualPoint.node == null) //point parent Node is null -> trigger validation
308 | {
309 | validatePointsDatabase = true;
310 | continue;
311 | }
312 |
313 | virtualPoint
314 | .CalculateRect(); //recalculate the rect to reflect the new values (the new WorldPosition)
315 | }
316 | }
317 |
318 | foreach (Port inputSocket in selectedNode.inputPorts) //get the node's input sockets
319 | {
320 | List virtualPoints = points[inputSocket.id]; //get input socket's virtual points list
321 | if (virtualPoints == null) //list is null -> trigger validation
322 | {
323 | validatePointsDatabase = true;
324 | continue;
325 | }
326 |
327 | foreach (VirtualPoint virtualPoint in virtualPoints)
328 | {
329 | if (virtualPoint == null) //point is null -> trigger validation
330 | {
331 | validatePointsDatabase = true;
332 | continue;
333 | }
334 |
335 | if (virtualPoint.node == null) //point parent Node is null -> trigger validation
336 | {
337 | validatePointsDatabase = true;
338 | continue;
339 | }
340 |
341 | virtualPoint
342 | .CalculateRect(); //recalculate the rect to reflect the new values (the new WorldPosition)
343 | }
344 | }
345 |
346 | foreach (var ev in edgeViews.Values) //get all the virtual connections in the graph
347 | {
348 | //check the virtual connections for nulls -> if any null is found -> trigger validation
349 | if (ev == null ||
350 | ev.outputNode == null ||
351 | ev.outputPort == null ||
352 | ev.outputVirtualPoint == null ||
353 | ev.inputNode == null ||
354 | ev.inputPort == null ||
355 | ev.inputVirtualPoint == null)
356 | {
357 | validateConnectionsDatabase = true;
358 | continue;
359 | }
360 |
361 | if (ev.inputNode.id != selectedNode.id && ev.outputNode.id != selectedNode.id) continue;
362 | CalculateConnectionCurve(
363 | ev); //recalculate the connection curve to reflect the new values (the new WorldPosition)
364 | }
365 | }
366 |
367 | if (validatePointsDatabase)
368 | ValidatePointsDatabase();
369 | if (validateConnectionsDatabase)
370 | ValidateConnectionsDatabase();
371 | }
372 |
373 | private void ValidatePointsDatabase()
374 | {
375 | if (points == null) return;
376 | var invalidKeys = new List(); //temp keys list
377 | foreach (string key in points.Keys)
378 | {
379 | if (points[key] == null)
380 | {
381 | invalidKeys.Add(key); //null virtual points list -> remove key
382 | continue;
383 | }
384 |
385 | var vList = points[key];
386 | var foundInvalidVirtualPoint = false;
387 | foreach (var virtualPoint in vList)
388 | {
389 | if (virtualPoint == null)
390 | {
391 | foundInvalidVirtualPoint = true; //null virtual point -> mark virtual point as invalid
392 | break;
393 | }
394 |
395 | if (virtualPoint.node == null)
396 | {
397 | foundInvalidVirtualPoint =
398 | true; //null virtual point parent Node -> mark virtual point as invalid
399 | break;
400 | }
401 |
402 | if (virtualPoint.port == null)
403 | {
404 | foundInvalidVirtualPoint =
405 | true; //null virtual point parent Socket -> mark virtual point as invalid
406 | break;
407 | }
408 | }
409 |
410 | if (foundInvalidVirtualPoint)
411 | invalidKeys.Add(key); //found an invalid virtual point in the virtual points list -> remove key
412 | }
413 |
414 | foreach (string invalidKey in invalidKeys)
415 | {
416 | points.Remove(invalidKey); //remove invalid keys
417 | }
418 | }
419 |
420 | private void ValidateConnectionsDatabase()
421 | {
422 | if (m_EdgeViews == null) return;
423 | var invalidKeys = new List(); //temp keys list
424 | foreach (var key in edgeViews.Keys)
425 | {
426 | if (edgeViews[key] == null)
427 | {
428 | invalidKeys.Add(key); //null virtual connection -> remove key
429 | continue;
430 | }
431 |
432 | var edgeView = edgeViews[key];
433 | if (edgeView.outputNode == null)
434 | {
435 | invalidKeys.Add(key); //null output node -> remove key
436 | continue;
437 | }
438 |
439 | if (edgeView.inputNode == null)
440 | {
441 | invalidKeys.Add(key); //null input node -> remove key
442 | continue;
443 | }
444 |
445 | if (edgeView.outputPort == null)
446 | {
447 | invalidKeys.Add(key); //null output socket -> remove key
448 | continue;
449 | }
450 |
451 | if (edgeView.inputPort == null) invalidKeys.Add(key); //null input socket -> remove key
452 | }
453 |
454 | foreach (string invalidKey in invalidKeys)
455 | {
456 | edgeViews.Remove(invalidKey); //remove invalid keys
457 | }
458 | }
459 |
460 | private void ConstructGraphGUI()
461 | {
462 | if (m_Graph == null) return;
463 | if (m_NodeViews!=null && m_NodeViews.Count != m_Graph.values.Count)
464 | {
465 | nodeViews.Clear();
466 | foreach (var item in m_Graph.values)
467 | {
468 | CreateNodeView(item);
469 | }
470 | }
471 | m_Points = null;
472 | m_Ports = null;
473 | m_EdgeViews = null;
474 | m_Points = points;
475 | m_Ports = ports;
476 | m_EdgeViews = edgeViews;
477 | //calculate all the connection points initial values
478 | CalculateAllPointRects();
479 | //calculate all the connections initial values
480 | //we do this here because in normal operation we want to update only the connections that are referencing nodes that are being dragged
481 | CalculateAllConnectionCurves();
482 | //update the visual state of all the connection points
483 | UpdateVirtualPointsIsOccupiedStates();
484 | //check for errors
485 | CheckAllNodesForErrors();
486 | }
487 |
488 | private void CalculateAllPointRects()
489 | {
490 | foreach (string key in points.Keys)
491 | foreach (VirtualPoint virtualPoint in points[key])
492 | virtualPoint.CalculateRect();
493 | }
494 |
495 | private void CalculateAllConnectionCurves()
496 | {
497 | foreach (EdgeView edgeView in m_EdgeViews.Values)
498 | {
499 | if (edgeView == null ||
500 | edgeView.outputNode == null ||
501 | edgeView.outputPort == null ||
502 | edgeView.inputNode == null ||
503 | edgeView.inputPort == null)
504 | continue;
505 |
506 | CalculateConnectionCurve(edgeView);
507 | }
508 | }
509 |
510 | private void CalculateConnectionCurve(EdgeView ev)
511 | {
512 | //get the lists of all the calculated virtual points for both Ports
513 | var outputVirtualPoints = points[ev.outputPort.id];
514 | var inputVirtualPoints = points[ev.inputPort.id];
515 |
516 | //get both OutputPort and InputPort rects converted to WorldSpace
517 | var outputPortWorldRect = GetPortWorldRect(ev.outputPort);
518 | var inputPortWorldRect = GetPortWorldRect(ev.inputPort);
519 |
520 | //get position values needed to determine the connection points and curve settings
521 | var outputPortCenter = outputPortWorldRect.center.x;
522 | var inputPortCenter = inputPortWorldRect.center.x;
523 |
524 | //get the closest virtual points for both Ports
525 | float minDistance = 100000;
526 | if (m_Graph.leftInRightOut)
527 | {
528 | ev.outputVirtualPoint = outputVirtualPoints[1];
529 | ev.inputVirtualPoint = inputVirtualPoints[0];
530 | minDistance = Vector2.Distance(ev.outputVirtualPoint.rect.position, ev.inputVirtualPoint.rect.position);
531 | }
532 | else
533 | {
534 | foreach (var outputVirtualPoint in outputVirtualPoints)
535 | {
536 | foreach (var inputVirtualPoint in inputVirtualPoints)
537 | {
538 | var currentDistance = Vector2.Distance(outputVirtualPoint.rect.position,
539 | inputVirtualPoint.rect.position);
540 | if (currentDistance > minDistance) continue;
541 | ev.outputVirtualPoint = outputVirtualPoint;
542 | ev.inputVirtualPoint = inputVirtualPoint;
543 | minDistance = currentDistance;
544 | }
545 | }
546 | }
547 |
548 | //set both the output and the input points as their respective tangents
549 | var zoomedPanOffset = m_Graph.currentPanOffset / currentZoom;
550 |
551 | var outputPoint = ev.outputVirtualPoint.rect.position - zoomedPanOffset;
552 | var inputPoint = ev.inputVirtualPoint.rect.position - zoomedPanOffset;
553 | var outputNodeWidth = ev.outputNode.GetWidth();
554 | var inputNodeWidth = ev.inputNode.GetWidth();
555 | var widthDifference = outputNodeWidth > inputNodeWidth
556 | ? outputNodeWidth - inputNodeWidth
557 | : inputNodeWidth - outputNodeWidth;
558 |
559 | ev.outputTangent = outputPoint + zoomedPanOffset;
560 | ev.inputTangent = inputPoint + zoomedPanOffset;
561 |
562 | //UP TO THIS POINT WE HAVE A STRAIGHT LINE
563 | //from here we start calculating the custom tangent values -> thus turning our connection line into a dynamic curve
564 |
565 | Vector2 outputTangentArcDirection; //output point tangent
566 | Vector2 inputTangentArcDirection; //input point tangent
567 |
568 | //OUTPUT RIGHT CONNECTION
569 | if (outputPortCenter < inputPortCenter && outputPortCenter <= inputPoint.x ||
570 | outputPortCenter >= inputPortCenter && outputPoint.x >= inputPortCenter &&
571 | outputPortCenter <= inputPoint.x)
572 | {
573 | if (outputPoint.x <= inputPortCenter + widthDifference / 2 && inputPortCenter > outputPoint.x)
574 | {
575 | outputTangentArcDirection = Vector2.right;
576 | inputTangentArcDirection = Vector2.left;
577 | }
578 | else
579 | {
580 | outputTangentArcDirection = Vector2.right;
581 | inputTangentArcDirection = Vector2.right;
582 | }
583 | }
584 | //OUTPUT LEFT CONNECTION
585 | else
586 | {
587 | if (outputPoint.x >= inputPortCenter)
588 | {
589 | outputTangentArcDirection = Vector2.left;
590 | inputTangentArcDirection = Vector2.right;
591 | }
592 | else
593 | {
594 | outputTangentArcDirection = Vector2.left;
595 | inputTangentArcDirection = Vector2.left;
596 | }
597 | }
598 |
599 | //set the curve strength (curvature) to be dynamic, by taking into account the distance between the connection points
600 | var outputCurveStrength = minDistance * (0.48f + ev.outputPort.curveModifier);
601 | var inputCurveStrength = minDistance * (0.48f + ev.inputPort.curveModifier);
602 | //update the tangents with the dynamic values
603 | ev.outputTangent += outputTangentArcDirection * outputCurveStrength;
604 | ev.inputTangent += inputTangentArcDirection * inputCurveStrength;
605 | }
606 |
607 | private Rect GetPortWorldRect(Port port)
608 | {
609 | if (port == null) return new Rect();
610 | var parentNode = nodeViews[port.nodeId].node;
611 | if (parentNode == null) return new Rect();
612 | var socketWorldRect = new Rect(parentNode.GetX(),
613 | parentNode.GetY() + port.GetY(),
614 | port.GetWidth(),
615 | port.GetHeight());
616 | return socketWorldRect;
617 | }
618 |
619 | private void CheckAllNodesForErrors()
620 | {
621 | foreach (var nodeView in nodeViews.Values)
622 | {
623 | nodeView.node.CheckForErrors();
624 | }
625 |
626 | Repaint();
627 | }
628 |
629 | private enum GraphMode
630 | {
631 | None,
632 | Connect,
633 | Select,
634 | Drag,
635 | Pan,
636 | Delete
637 | }
638 |
639 | private enum GraphAction
640 | {
641 | Copy,
642 | Connect,
643 | CreateNode,
644 | DeleteNodes,
645 | DeselectAll,
646 | Disconnect,
647 | Paste,
648 | SelectAll,
649 | SelectNodes
650 | }
651 |
652 | private class SelectPoint
653 | {
654 | public readonly float x;
655 | public readonly float y;
656 |
657 | public SelectPoint(Vector2 position)
658 | {
659 | x = position.x;
660 | y = position.y;
661 | }
662 | }
663 | }
664 |
665 |
666 | public abstract partial class GraphWindow : GraphWindow where T : GraphBase
667 | {
668 | public T m_Graph => base.m_Graph as T;
669 | protected sealed override GraphBase CreateGraphBase()
670 | {
671 | return CreateGraph();
672 | }
673 |
674 | protected abstract T CreateGraph();
675 |
676 | protected sealed override GraphBase LoadGraphBase()
677 | {
678 | return LoadGraph();
679 | }
680 |
681 | protected abstract T LoadGraph();
682 | }
683 | }
--------------------------------------------------------------------------------
/Editor/GraphWindow.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b8733c1abfab03248a66a813490370f2
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor/GraphWindowDraw.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using UnityEngine;
6 | using UnityEditor;
7 |
8 | namespace DaGenGraph.Editor
9 | {
10 | public abstract partial class GraphWindow
11 | {
12 | #region GUIStyles
13 |
14 | private static GUIStyle s_DotStyle;
15 | private static GUIStyle s_ConnectionPointOverrideEmpty;
16 | private static GUIStyle s_ConnectionPointOverrideConnected;
17 | private static GUIStyle s_ConnectionPointMultipleEmpty;
18 | private static GUIStyle s_ConnectionPointMultipleConnected;
19 | private static GUIStyle s_ConnectionPointMinus;
20 |
21 | private static GUIStyle dotStyle
22 | {
23 | get { return s_DotStyle ?? (s_DotStyle = Styles.GetStyle("NodeDot")); }
24 | }
25 |
26 | private static GUIStyle edgePointOverrideEmpty
27 | {
28 | get
29 | {
30 | return s_ConnectionPointOverrideEmpty ??
31 | (s_ConnectionPointOverrideEmpty = Styles.GetStyle("ConnectionPointOverrideEmpty"));
32 | }
33 | }
34 |
35 | private static GUIStyle edgePointOverrideConnected
36 | {
37 | get
38 | {
39 | return s_ConnectionPointOverrideConnected ?? (s_ConnectionPointOverrideConnected =
40 | Styles.GetStyle("ConnectionPointOverrideConnected"));
41 | }
42 | }
43 |
44 | private static GUIStyle edgePointMultipleEmpty
45 | {
46 | get
47 | {
48 | return s_ConnectionPointMultipleEmpty ??
49 | (s_ConnectionPointMultipleEmpty = Styles.GetStyle("ConnectionPointMultipleEmpty"));
50 | }
51 | }
52 |
53 | private static GUIStyle edgePointMultipleConnected
54 | {
55 | get
56 | {
57 | return s_ConnectionPointMultipleConnected ?? (s_ConnectionPointMultipleConnected =
58 | Styles.GetStyle("ConnectionPointMultipleConnected"));
59 | }
60 | }
61 |
62 | private static GUIStyle edgePointMinus
63 | {
64 | get { return s_ConnectionPointMinus ?? (s_ConnectionPointMinus = Styles.GetStyle("ConnectionPointMinus")); }
65 | }
66 |
67 | #endregion
68 |
69 | #region Private Variables
70 |
71 | private delegate void DrawToolbarHandler();
72 |
73 | private List m_DrawToolbarHandlers=new List();
74 | private List m_DrawToolbarHandlersRight=new List();
75 | private Color m_CreateEdgeLineColor = Color.white;
76 | private Color m_ConnectionBackgroundColor;
77 | private Color m_EdgeColor;
78 | private Color m_DotColor;
79 | private Color m_InputColor;
80 | private Color m_NormalColor;
81 | private Color m_OutputColor;
82 | private Vector3 m_DotPoint;
83 | private Vector3[] m_BezierPoints;
84 | private float m_ConnectionAlpha;
85 | private float m_DotSize;
86 | private int m_DotPointIndex;
87 | private int m_NumberOfPoints;
88 |
89 |
90 | #endregion
91 |
92 | #region DrawEdges
93 |
94 | private void DrawEdges()
95 | {
96 | if (currentZoom <= 0.2f) return;
97 | if (m_NodeViews == null) return;
98 | m_AniTime += m_Timer;
99 | if (m_AniTime >= 3)
100 | {
101 | m_AniTime = 0;
102 | }
103 |
104 | foreach (var edgeView in edgeViews.Values)
105 | {
106 | if (edgeView.outputNode == null || edgeView.inputNode == null)
107 | {
108 | continue;
109 | }
110 |
111 | //if both nodes are not visible -> do not draw the edge
112 | if (!m_NodeViews[edgeView.inputNode.id].isVisible && !m_NodeViews[edgeView.inputNode.id].isVisible)
113 | {
114 | continue;
115 | }
116 |
117 | if (edgeView.outputVirtualPoint == null || edgeView.inputVirtualPoint == null)
118 | {
119 | continue;
120 | }
121 |
122 | DrawEdgeCurve(edgeView);
123 | }
124 | }
125 |
126 | private void DrawEdgeCurve(EdgeView edge)
127 | {
128 | //connect
129 | m_ConnectionAlpha = 1f;
130 | if (m_Mode == GraphMode.Connect) m_ConnectionAlpha = 0.5f;
131 |
132 | m_NormalColor = UColor.GetColor().edgeNormalColor;
133 | m_OutputColor = UColor.GetColor().edgeOutputColor;
134 | m_InputColor = UColor.GetColor().edgeInputColor;
135 | m_NormalColor.a = m_ConnectionAlpha;
136 | m_OutputColor.a = m_ConnectionAlpha;
137 | m_InputColor.a = m_ConnectionAlpha;
138 | m_EdgeColor = m_NormalColor;
139 | m_AnimateInput = false;
140 | m_AnimateOutput = false;
141 |
142 | //A node is selected and the Alt Key is not pressed -> show the edge color depending on socket type of this node (if it is an output or an input one)
143 | if (m_SelectedNodes.Count == 1 && !altKeyPressed)
144 | {
145 | NodeBase selectedNode = m_SelectedNodes[0];
146 | if (selectedNode == null) return;
147 | if (selectedNode.ContainsEdge(edge.edgeId))
148 | {
149 | if (selectedNode == edge.outputNode)
150 | {
151 | //color for output edge
152 | m_EdgeColor = m_OutputColor;
153 | m_AnimateOutput = true;
154 | }
155 |
156 | if (selectedNode == edge.inputNode)
157 | {
158 | //color for input edge
159 | m_EdgeColor = m_InputColor;
160 | m_AnimateInput = true;
161 | }
162 | }
163 | }
164 |
165 | float currentCurveWidth = 3;
166 | if (EditorApplication.isPlaying)
167 | {
168 | if (m_Graph.GetEdge(edge.edgeId).ping)
169 | {
170 | m_EdgeColor = m_OutputColor;
171 | m_AnimateOutput = true;
172 | if (m_Graph.GetEdge(edge.edgeId).reSetTime)
173 | {
174 | m_AniTime = 0;
175 | m_Graph.GetEdge(edge.edgeId).reSetTime = false;
176 | }
177 | }
178 | else if (m_Graph.GetEdge(edge.edgeId).ping)
179 | {
180 | m_EdgeColor = m_InputColor;
181 | m_AnimateInput = true;
182 | if (m_Graph.GetEdge(edge.edgeId).reSetTime)
183 | {
184 | m_AniTime = 0;
185 | m_Graph.GetEdge(edge.edgeId).reSetTime = false;
186 | }
187 | }
188 | }
189 | else if (m_Graph.GetEdge(edge.edgeId).ping ||
190 | m_Graph.GetEdge(edge.edgeId).ping)
191 | {
192 | m_Graph.GetEdge(edge.edgeId).ping = false;
193 | m_Graph.GetEdge(edge.edgeId).ping = false;
194 | }
195 |
196 | m_DotColor = m_EdgeColor;
197 | if (altKeyPressed) //delete mode is enabled -> check if we should color the edge to RED
198 | {
199 | //check this edge's points by testing if the mouse if hovering over one of this edge's virtual points
200 | bool colorTheConnectionRed = edge.inputVirtualPoint == m_CurrentHoveredVirtualPoint ||
201 | edge.outputVirtualPoint == m_CurrentHoveredVirtualPoint;
202 | if (colorTheConnectionRed)
203 | {
204 | //set the edge color to RED -> as the developer might want to remove this edge
205 | m_EdgeColor = Color.red;
206 | //make the red curve just a tiny bit more thick to make it stand out even better
207 | currentCurveWidth += 1;
208 | }
209 | }
210 |
211 | m_ConnectionBackgroundColor = new Color(m_EdgeColor.r * 0.2f,
212 | m_EdgeColor.g * 0.2f,
213 | m_EdgeColor.b * 0.2f,
214 | m_ConnectionAlpha - 0.2f);
215 |
216 | //HandleUtility.handleMaterial.SetPass(0);
217 | Handles.DrawBezier(edge.outputVirtualPoint.rect.position,
218 | edge.inputVirtualPoint.rect.position,
219 | edge.outputTangent,
220 | edge.inputTangent,
221 | m_ConnectionBackgroundColor,
222 | null,
223 | currentCurveWidth + 2);
224 | Handles.DrawBezier(edge.outputVirtualPoint.rect.position,
225 | edge.inputVirtualPoint.rect.position,
226 | edge.outputTangent,
227 | edge.inputTangent,
228 | m_EdgeColor,
229 | null,
230 | currentCurveWidth);
231 | //if the window does not have focus -> return (DO NOT PLAY ANIMATION)
232 | //if (!m_HasFocus) return;
233 | //if the mouse is not inside the window -> return (DO NOT PLAY ANIMATION)
234 | //if (!MouseInsideWindow) return;
235 | if (!m_AnimateInput && !m_AnimateOutput)
236 | {
237 | //if the animation is not enabled for both points -> return (DO NOT PLAY ANIMATION)
238 | return;
239 | }
240 |
241 | //points multiplier - useful for a smooth dot travel - smaller means fewer travel point (makes the point 'jumpy') and higher means more travel points (make the point move smoothly)
242 | m_NumberOfPoints =
243 | (int)(Vector2.Distance(edge.outputVirtualPoint.rect.position, edge.inputVirtualPoint.rect.position) *
244 | 3);
245 | if (m_NumberOfPoints <= 0) return;
246 | m_BezierPoints = Handles.MakeBezierPoints(edge.outputVirtualPoint.rect.position,
247 | edge.inputVirtualPoint.rect.position,
248 | edge.outputTangent,
249 | edge.inputTangent,
250 | m_NumberOfPoints);
251 | m_DotPointIndex = 0;
252 | //we set the number of points as the bezierPoints length - 1
253 | m_NumberOfPoints--;
254 | if (m_AnimateInput)
255 | {
256 | m_DotPointIndex = (int)(m_AniTime * m_NumberOfPoints);
257 | }
258 | else if (m_AnimateOutput)
259 | {
260 | m_DotPointIndex = m_NumberOfPoints - (int)((1 - m_AniTime) * m_NumberOfPoints);
261 | }
262 |
263 | m_DotPointIndex = Mathf.Clamp(m_DotPointIndex, 0, m_NumberOfPoints);
264 | //reset edge's ping
265 | if (m_Graph.GetEdge(edge.edgeId).ping && m_DotPointIndex >= m_NumberOfPoints)
266 | {
267 | m_Graph.GetEdge(edge.edgeId).ping = false;
268 | }
269 |
270 | m_DotPoint = m_BezierPoints[m_DotPointIndex];
271 | m_DotSize = currentCurveWidth * 2;
272 | //make the dot a bit brighter
273 | m_DotColor = new Color(m_DotColor.r * 1.2f, m_DotColor.g * 1.2f, m_DotColor.b * 1.2f, m_DotColor.a);
274 |
275 | GUI.color = m_DotColor;
276 | GUI.Box(new Rect(m_DotPoint.x - m_DotSize / 2, m_DotPoint.y - m_DotSize / 2, m_DotSize, m_DotSize), "",
277 | dotStyle);
278 | GUI.color = Color.white;
279 | }
280 |
281 | #endregion
282 |
283 | #region DrawNodes
284 |
285 | private void DrawNodes(Rect graphArea)
286 | {
287 | BeginWindows();
288 | foreach (var nodeView in m_NodeViews.Values)
289 | {
290 | nodeView.zoomedBeyondPortDrawThreshold = currentZoom <= 0.4f;
291 | nodeView.DrawNodeGUI(graphArea, m_Graph.currentPanOffset, currentZoom);
292 | }
293 |
294 | EndWindows();
295 | }
296 |
297 | #endregion
298 |
299 | #region DrawPortsEdgePoints
300 |
301 | private void DrawPortsEdgePoints()
302 | {
303 | if (currentZoom <= 0.4f) return;
304 | foreach (var port in ports.Values)
305 | {
306 | DrawPortEdgePoints(port); //draw the edge points
307 | }
308 | }
309 |
310 | private void DrawPortEdgePoints(Port port)
311 | {
312 | foreach (var virtualPoint in points[port.id])
313 | {
314 | var mouseIsOverThisPoint = virtualPoint == m_CurrentHoveredVirtualPoint;
315 | if (m_AltKeyPressedAnimBool.faded > 0.5f && virtualPoint.isConnected)
316 | {
317 | //set the virtualPoint delete color to RED
318 | //set the virtualPoint style to show to the dev that he can disconnect the socket (it's a minus sign)
319 | DrawEdgePoint(virtualPoint, mouseIsOverThisPoint, Styles.GetStyle("ConnectionPointMinus"),
320 | Color.red);
321 | continue;
322 | }
323 |
324 | var pointColor = port.IsInput() ? UColor.GetColor().portInputColor : UColor.GetColor().portOutputColor;
325 | GUIStyle pointStyle;
326 | switch (port.GetConnectionMode())
327 | {
328 | case EdgeMode.Override:
329 | pointStyle = virtualPoint.isConnected ? edgePointOverrideConnected : edgePointOverrideEmpty;
330 | break;
331 | case EdgeMode.Multiple:
332 | pointStyle = virtualPoint.isConnected ? edgePointMultipleConnected : edgePointMultipleEmpty;
333 | break;
334 | default:
335 | throw new ArgumentOutOfRangeException();
336 | }
337 |
338 | DrawEdgePoint(virtualPoint, mouseIsOverThisPoint, pointStyle, pointColor);
339 | }
340 | }
341 |
342 | private void DrawEdgePoint(VirtualPoint virtualPoint, bool mouseIsOverThisPoint, GUIStyle pointStyle,
343 | Color pointColor)
344 | {
345 | pointColor.a = virtualPoint.isConnected || mouseIsOverThisPoint ? 1f : 0.8f;
346 | //this makes an unoccupied connector a bit smaller than an occupied one (looks nicer)
347 | var occupiedRatioChange = virtualPoint.isConnected ? 1f : 0.8f;
348 | var pointWidth = 16f * occupiedRatioChange * (mouseIsOverThisPoint ? 1.2f : 1f);
349 | var pointHeight = 16f * occupiedRatioChange * (mouseIsOverThisPoint ? 1.2f : 1f);
350 | var pointRect = new Rect(virtualPoint.rect.position.x - pointWidth / 2,
351 | virtualPoint.rect.position.y - pointHeight / 2,
352 | pointWidth,
353 | pointHeight);
354 | GUI.color = pointColor;
355 | GUI.Box(pointRect, GUIContent.none, pointStyle);
356 | GUI.color = Color.white;
357 | }
358 |
359 | #endregion
360 |
361 | #region DrawLineFromPortToPosition
362 |
363 | private void DrawLineFromPortToPosition(Port activePort, Vector2 worldPosition)
364 | {
365 | if (m_Mode != GraphMode.Connect) return;
366 | if (currentZoom <= 0.4f) return;
367 | var from = GetClosestEdgePointWorldPositionFromPortToMousePosition(activePort,
368 | worldPosition / currentZoom);
369 | var to = worldPosition;
370 | float edgeLineWidth = 3;
371 | var edgeBackgroundColor = new Color(m_CreateEdgeLineColor.r * 0.2f,
372 | m_CreateEdgeLineColor.g * 0.2f, m_CreateEdgeLineColor.b * 0.2f, 0.8f);
373 | Handles.DrawBezier(from, to, to, from, edgeBackgroundColor, null, edgeLineWidth + 2);
374 | Handles.DrawBezier(from, to, to, from, m_CreateEdgeLineColor, null, edgeLineWidth);
375 | var dotSize = edgeLineWidth * 3;
376 | GUI.color = new Color(m_CreateEdgeLineColor.r * 1.2f, m_CreateEdgeLineColor.g * 1.2f,
377 | m_CreateEdgeLineColor.b * 1.2f, 1f);
378 | GUI.Box(new Rect(to.x - dotSize / 2, to.y - dotSize / 2, dotSize, dotSize), "", dotStyle);
379 | GUI.color = Color.white;
380 | HandleUtility.Repaint();
381 | Repaint();
382 | }
383 |
384 | private Vector2 GetClosestEdgePointWorldPositionFromPortToMousePosition(Port port, Vector2 mousePosition)
385 | {
386 | var parentNode = nodeViews[port.nodeId].node;
387 | if (parentNode == null) return Vector2.zero;
388 | var pointsInWorldSpace = GetPortEdgePointsInWorldSpace(port, parentNode);
389 | float minDistance = 100000;
390 | var worldPosition = parentNode.GetPosition();
391 | foreach (Vector2 edgePointWorldPosition in pointsInWorldSpace)
392 | {
393 | float currentDistance = Vector2.Distance(edgePointWorldPosition, mousePosition);
394 | if (currentDistance > minDistance) continue;
395 | worldPosition = edgePointWorldPosition;
396 | minDistance = currentDistance;
397 | }
398 |
399 | return worldPosition;
400 | }
401 |
402 | private IEnumerable GetPortEdgePointsInWorldSpace(Port port, NodeBase parentNode)
403 | {
404 | var pointsInWorldSpace = new List();
405 | if (port == null) return pointsInWorldSpace;
406 | if (parentNode == null) return pointsInWorldSpace;
407 | foreach (Vector2 edgePoint in port.GetEdgePoints())
408 | {
409 | var socketWorldRect = new Rect(parentNode.GetX(),
410 | parentNode.GetY() + port.GetY(),
411 | port.GetWidth(),
412 | port.GetHeight());
413 |
414 | socketWorldRect.position +=
415 | m_Graph.currentPanOffset / currentZoom; //this is the calculated socketGridRect
416 | pointsInWorldSpace.Add(new Vector2(socketWorldRect.x + edgePoint.x + 8,
417 | socketWorldRect.y + edgePoint.y + 8));
418 | }
419 |
420 | return pointsInWorldSpace;
421 | }
422 |
423 | #endregion
424 |
425 | #region DrawSelectionBox
426 |
427 | private void DrawSelectionBox()
428 | {
429 | if (m_Mode != GraphMode.Select) return;
430 | Color initialColor = GUI.color;
431 | GUI.color = (EditorGUIUtility.isProSkin ? new Color(0f, 0f, 0f, 0.3f) : new Color(1, 1, 1, 0.3f));
432 | var sty = Styles.GetStyle("BackgroundSquare");
433 | GUI.Label(m_SelectionRect, string.Empty, sty);
434 | GUI.color = initialColor;
435 | }
436 |
437 | #endregion
438 |
439 | #region DrawToolbar
440 |
441 | protected virtual void AddButton(GUIContent content, Action callback,bool left = true,
442 | params GUILayoutOption[] options)
443 | {
444 | if (left)
445 | {
446 | m_DrawToolbarHandlers.Add(() =>
447 | {
448 | if (GUILayout.Button(content, options))
449 | {
450 | callback.Invoke();
451 | }
452 | });
453 | }
454 | else
455 | {
456 | m_DrawToolbarHandlersRight.Add(() =>
457 | {
458 | if (GUILayout.Button(content, options))
459 | {
460 | callback.Invoke();
461 | }
462 | });
463 | }
464 | }
465 |
466 | private void DrawToolbar()
467 | {
468 | GUILayout.BeginHorizontal(EditorStyles.toolbar);
469 | foreach (var drawToolbarHandler in m_DrawToolbarHandlers)
470 | {
471 | drawToolbarHandler.Invoke();
472 | }
473 |
474 | GUILayout.FlexibleSpace();
475 | foreach (var drawToolbarHandler in m_DrawToolbarHandlersRight)
476 | {
477 | drawToolbarHandler.Invoke();
478 | }
479 | GUILayout.EndHorizontal();
480 | }
481 |
482 | #endregion
483 |
484 | #region DrawInspector
485 |
486 | private Vector2 nodeScrollPos;
487 | private Vector2 graphScrollPos;
488 | private bool foldGraph;
489 | private Dictionary foldNode = new Dictionary();
490 | private void DrawInspector(float start,float width)
491 | {
492 | bool showNodeView = m_Graph!=null && m_SelectedNodes!=null && m_SelectedNodes.Count>0;
493 | var inspectorArea = new Rect(start, 20, width, position.height-20);
494 | GUILayout.BeginArea(inspectorArea);
495 | foldGraph = EditorGUILayout.BeginFoldoutHeaderGroup(foldGraph, m_Graph.name);
496 | if (foldGraph)
497 | {
498 | graphScrollPos = EditorGUILayout.BeginScrollView(graphScrollPos, GUILayout.Width(inspectorArea.width), GUILayout.Height(showNodeView?200:inspectorArea.height-20));
499 | DrawGraphInspector();
500 | EditorGUILayout.EndScrollView();
501 | }
502 | EditorGUILayout.EndFoldoutHeaderGroup();
503 | if (showNodeView)
504 | {
505 | nodeScrollPos = EditorGUILayout.BeginScrollView(nodeScrollPos, GUILayout.Width(inspectorArea.width), GUILayout.Height(inspectorArea.height-(foldGraph?225:25)));
506 | for (int i = 0; i < m_SelectedNodes.Count; i++)
507 | {
508 | var node = m_SelectedNodes[i];
509 | if (node == null) continue;
510 | if(!nodeViews.TryGetValue(node.id,out var view)) continue;
511 | if (!foldNode.TryGetValue(node.id, out var fold))
512 | {
513 | fold = false;
514 | foldNode[m_SelectedNodes[i].id] = fold;
515 | }
516 | fold = EditorGUILayout.BeginFoldoutHeaderGroup(fold, $"{node.name}({node.id})");
517 | if (fold)
518 | {
519 | EditorGUILayout.Space(10);
520 | //nodeView自己决定展示
521 | view.DrawInspector(true);
522 | }
523 | foldNode[m_SelectedNodes[i].id] = fold;
524 | EditorGUILayout.EndFoldoutHeaderGroup();
525 | }
526 | EditorGUILayout.EndScrollView();
527 | }
528 | GUILayout.EndArea();
529 | }
530 |
531 | protected virtual void DrawGraphInspector()
532 | {
533 | DrawObjectInspector(m_Graph, true);
534 | }
535 | #endregion
536 | }
537 | }
--------------------------------------------------------------------------------
/Editor/GraphWindowDraw.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9f2a082a15c94cba9c7f7b1119fd643f
3 | timeCreated: 1623033172
--------------------------------------------------------------------------------
/Editor/GroupInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 |
5 | namespace DaGenGraph.Editor
6 | {
7 | public interface ISort
8 | {
9 | public float MinSort { get; }
10 | }
11 | public class GroupItem:ISort
12 | {
13 | public float MinSort { get; set; }
14 | public string GroupId;
15 | public List Members = new ();
16 | }
17 |
18 | public class MemberItem:ISort
19 | {
20 | public float MinSort{ get; set; }
21 | public MemberInfo Member;
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/Editor/GroupInfo.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c59bfa784a3d48f1bd30966a15085581
3 | timeCreated: 1737624988
--------------------------------------------------------------------------------
/Editor/NodeView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using UnityEditor;
5 | using UnityEngine;
6 |
7 | namespace DaGenGraph.Editor
8 | {
9 | public class NodeView : DrawBase
10 | {
11 | #region Private Variables
12 |
13 | private NodeBase m_Node;
14 | private GraphWindow m_graphWindow;
15 | private int m_WindowId;
16 | private GraphBase m_Graph;
17 | private Vector2 m_DeleteButtonSize;
18 | private Vector2 m_Offset;
19 | private Rect m_DrawRect;
20 | public bool isVisible = true;
21 | public bool zoomedBeyondPortDrawThreshold = false;
22 | public bool isSelected;
23 | private Rect m_GlowRect;
24 | private Rect m_HeaderRect;
25 | private Rect m_HeaderHoverRect;
26 | private Rect m_HeaderIconRect;
27 | private Rect m_HeaderTitleRect;
28 | private Rect m_BodyRect;
29 | private Rect m_FooterRect;
30 | private Rect m_NodeOutlineRect;
31 | private Color m_NodeGlowColor;
32 | private Color m_NodeHeaderAndFooterBackgroundColor;
33 | private Color m_RootNodeHeaderAndFooterBackgroundColor;
34 | private Color m_NodeBodyColor;
35 | private Color m_NodeOutlineColor;
36 | private Color m_HeaderTextAndIconColor;
37 |
38 | private HashSet foldoutState = new HashSet();
39 |
40 | #endregion
41 |
42 | #region Properties
43 |
44 | public int windowId => m_WindowId;
45 | public NodeBase node => m_Node;
46 | public GraphBase graph => m_Graph;
47 | public float x => m_Node.GetX();
48 | public float y => m_Node.GetY();
49 | public float width => m_Node.GetWidth();
50 | public float height => m_Node.GetHeight();
51 | public Vector2 position => m_Node.GetPosition();
52 | public Vector2 size => m_Node.GetSize();
53 | public Rect rect => m_Node.GetRect();
54 | public Rect drawRect => m_DrawRect;
55 | protected float dynamicHeight { get; set; }
56 |
57 | public GraphWindow graphWindow => m_graphWindow;
58 | #endregion
59 |
60 | #region GUIStyles
61 |
62 | private static GUIStyle s_NodeArea;
63 | private static GUIStyle nodeArea => s_NodeArea ??= Styles.GetStyle("NodeArea");
64 | private static GUIStyle s_NodeBody;
65 | protected static GUIStyle nodeBody => s_NodeBody ??= Styles.GetStyle("NodeBody");
66 | private static GUIStyle s_NodeOutline;
67 | protected static GUIStyle nodeOutline => s_NodeOutline ??= Styles.GetStyle("NodeOutline");
68 | private static GUIStyle s_NodeGlow;
69 | protected static GUIStyle nodeGlowStyle => s_NodeGlow ??= Styles.GetStyle("NodeGlow");
70 | private static GUIStyle s_Dot;
71 | private static GUIStyle nodeDot => s_Dot ??= Styles.GetStyle("NodeDot");
72 | private static GUIStyle s_NodeHeader;
73 | private static GUIStyle nodeHeader => s_NodeHeader ??= Styles.GetStyle("NodeHeader");
74 | private static GUIStyle s_NodeFooter;
75 | private static GUIStyle nodeFooter => s_NodeFooter ??= Styles.GetStyle("NodeFooter");
76 | private static GUIStyle s_NodeHorizontalDivider;
77 |
78 | private static GUIStyle nodeHorizontalDivider =>
79 | s_NodeHorizontalDivider ??= Styles.GetStyle("NodeHorizontalDivider");
80 |
81 | #endregion
82 |
83 | #region Static Variables
84 |
85 | private static readonly float s_HeaderHeight = 32;
86 | private static readonly float s_HeaderIconSize = 20;
87 | private static float headerIconPadding => (s_HeaderHeight - s_HeaderIconSize) / 2;
88 |
89 | #endregion
90 |
91 | #region Virtual Methods
92 |
93 | public virtual void Init(int windowId, NodeBase node, GraphBase graph, GraphWindow graphWindow)
94 | {
95 | m_WindowId = windowId;
96 | m_Node = node;
97 | m_Graph = graph;
98 | m_graphWindow = graphWindow;
99 | m_Node.onDeletePort += OnDeletePort;
100 | }
101 |
102 | public virtual void OnDoubleClick(EditorWindow window)
103 | {
104 | }
105 |
106 | public virtual void OnUnFocus(EditorWindow window)
107 | {
108 | GUI.FocusControl(null);
109 | }
110 |
111 | protected virtual void OnNodeGUI()
112 | {
113 | DrawNodeBody();
114 | DrawNodePorts();
115 | }
116 |
117 | protected virtual GUIStyle GetIconStyle()
118 | {
119 | return nodeDot;
120 | }
121 |
122 | protected virtual Rect DrawPort(Port port)
123 | {
124 | //set Port to the left side of the node
125 | port.SetX(0);
126 | //set the y to the current draw height
127 | port.SetY(dynamicHeight);
128 | //set the Port width as the node width
129 | port.SetWidth(node.GetWidth());
130 | port.SetHeight(24f);
131 | if (zoomedBeyondPortDrawThreshold) return port.GetRect();
132 |
133 | //set the Port color to white or black - depending on the current skin - (we assume it's not connected)
134 | var portColor = Color.gray;
135 | var dividerColor = Color.gray;
136 |
137 | //check if the Port is connected in order to color the divider to the input or output color
138 | if (port.IsConnected())
139 | {
140 | portColor = port.IsInput() ? UColor.GetColor().portInputColor : UColor.GetColor().portOutputColor;
141 | dividerColor = UColor.GetColor().nodeDividerColor;
142 | }
143 |
144 | //in order not to overpower the design with bold colors -> we make the color fade out a bit in order to make the graph easier on the eyes
145 | var opacity = 0.3f;
146 | portColor.a = opacity;
147 | dividerColor.a = opacity * 0.8f;
148 |
149 | //check if we are in delete mode -> if true -> set the socket color to red (ONLY if the socket can be deleted)
150 | if (m_graphWindow.altKeyPressed)
151 | {
152 | //since we're in delete mode and this socket can be deConnect -> set its color to red
153 | if (port.IsConnected())
154 | {
155 | portColor = Color.red;
156 | dividerColor = Color.red;
157 | }
158 |
159 | //since we're in delete mode -> make the socket color a bit stronger (regardless if it can be deleted or not) -> this is a design choice
160 | portColor.a = opacity * 1.2f;
161 | dividerColor.a = opacity * 1.2f;
162 | }
163 |
164 | //calculate the top divider rect position and size -> this is the thin line at the bottom of every Port (design choice)
165 | var topDividerRect = new Rect(port.GetRect().x + 6, port.GetRect().y + 1f, port.GetRect().width - 12, 1);
166 |
167 | //color the gui to the defined Port color
168 | GUI.color = dividerColor;
169 | //DRAW the horizontal divider at the top of the Port
170 | GUI.Box(topDividerRect, GUIContent.none, nodeHorizontalDivider);
171 | //reset the gui color
172 | GUI.color = Color.white;
173 |
174 | //calculate the bottom divider rect position and size -> this is the thin line at the bottom of every Port (design choice)
175 | var bottomDividerRect = new Rect(port.GetRect().x + 6, port.GetRect().y + port.GetRect().height - 1,
176 | port.GetRect().width - 12, 1);
177 |
178 | //color the gui to the defined Port color
179 | GUI.color = dividerColor;
180 | //DRAW the horizontal divider at the bottom of the Port
181 | GUI.Box(bottomDividerRect, GUIContent.none, nodeHorizontalDivider);
182 | //reset the gui color
183 | GUI.color = Color.white;
184 | var label = port.portName;
185 | var areaRect = new Rect(port.GetX() + 24, port.GetY(), port.GetWidth() - 48, port.GetHeight());
186 | GUILayout.BeginArea(areaRect);
187 | {
188 | GUILayout.BeginHorizontal();
189 | {
190 | var labelStyle = Styles.GetStyle("NodePortText");
191 | var content = new GUIContent(label);
192 | var contentSize = labelStyle.CalcSize(content);
193 | GUILayout.BeginVertical(GUILayout.Width(contentSize.x), GUILayout.Height(port.GetHeight()));
194 | {
195 | GUILayout.Space((port.GetHeight() - contentSize.y) / 2);
196 | GUILayout.Label(content, labelStyle, GUILayout.Width(contentSize.x));
197 | }
198 | GUILayout.EndVertical();
199 | }
200 | GUILayout.EndHorizontal();
201 | }
202 | GUILayout.EndArea();
203 | //calculate the Port hover rect -> this is the 'selection' box that appears when the mouse is over the Port
204 | port.UpdateHoverRect();
205 | if (port.showHover.faded > 0.01f)
206 | {
207 | var animatedRect = new Rect(port.hoverRect.x,
208 | port.hoverRect.y + port.hoverRect.height * (1 - port.showHover.faded),
209 | port.hoverRect.width,
210 | port.hoverRect.height * port.showHover.faded);
211 |
212 | if (port.IsConnected())
213 | {
214 | switch (port.GetDirection())
215 | {
216 | case PortDirection.Input:
217 | GUI.color = UColor.GetColor().portInputColor.WithAlpha(0.1f);
218 | break;
219 | case PortDirection.Output:
220 | GUI.color = UColor.GetColor().portInputColor.WithAlpha(0.1f);
221 | break;
222 | default: throw new ArgumentOutOfRangeException();
223 | }
224 | }
225 |
226 | //color the gui to the defined Port color
227 | GUI.color = portColor;
228 | //DRAW the animated overlay when the mouse is hovering over this Port
229 | GUI.Box(animatedRect, new GUIContent(label), nodeHorizontalDivider);
230 | GUI.color = Color.white; //reset the gui color
231 | }
232 |
233 | return port.GetRect();
234 | }
235 |
236 | #endregion
237 |
238 | #region Protected Methods
239 |
240 | protected void DrawNodeBody()
241 | {
242 | var initialColor = GUI.color;
243 | dynamicHeight = 0;
244 | m_DrawRect = new Rect(0, 0, width, height); //get node draw rect
245 |
246 | var leftX = m_DrawRect.x + 6;
247 | var bodyWidth = m_DrawRect.width - 12;
248 |
249 | m_GlowRect = new Rect(m_DrawRect.x, m_DrawRect.y, m_DrawRect.width, m_DrawRect.height - 2);
250 | dynamicHeight += 6;
251 | m_HeaderRect = new Rect(leftX, dynamicHeight, bodyWidth, s_HeaderHeight);
252 | m_HeaderIconRect = new Rect(m_HeaderRect.x + headerIconPadding * 2f, m_HeaderRect.y + headerIconPadding + 1,
253 | s_HeaderIconSize, s_HeaderIconSize);
254 | m_HeaderTitleRect = new Rect(m_HeaderIconRect.xMax + headerIconPadding * 1.5f, m_HeaderIconRect.y,
255 | m_HeaderRect.width - (s_HeaderIconSize + headerIconPadding * 5), m_HeaderIconRect.height);
256 | dynamicHeight += m_HeaderRect.height;
257 | var footerHeight = 10f;
258 | var bodyHeight = m_DrawRect.height - 32f - 2f - footerHeight - 12;
259 | m_BodyRect = new Rect(leftX, dynamicHeight, bodyWidth, bodyHeight);
260 | m_FooterRect = new Rect(leftX, m_DrawRect.height - footerHeight - 8, bodyWidth, footerHeight);
261 | m_NodeOutlineRect = new Rect(m_DrawRect.x, m_DrawRect.y, m_DrawRect.width, m_DrawRect.height - 2);
262 |
263 | GUI.color = m_NodeGlowColor;
264 | GUI.Box(m_GlowRect, GUIContent.none, nodeGlowStyle); //node glow
265 |
266 | GUI.color = m_Graph.startNodeId == node.id ? m_RootNodeHeaderAndFooterBackgroundColor:m_NodeHeaderAndFooterBackgroundColor;
267 | GUI.Box(m_HeaderRect, GUIContent.none, nodeHeader); //header background
268 |
269 | GUI.color = m_HeaderTextAndIconColor;
270 | GUI.Box(m_HeaderIconRect, GUIContent.none, GetIconStyle()); //header icon
271 |
272 | GUI.color = initialColor;
273 | GUIStyle titleStyle = Styles.GetStyle("NodeHeaderText");
274 | GUI.Label(m_HeaderTitleRect, node.name, titleStyle /*titleStyle8*/); //header title
275 |
276 | GUI.color = m_NodeBodyColor;
277 | GUI.Box(m_BodyRect, GUIContent.none, nodeBody); //body background
278 |
279 | GUI.color = m_Graph.startNodeId == node.id ? m_RootNodeHeaderAndFooterBackgroundColor:m_NodeHeaderAndFooterBackgroundColor;
280 | GUI.Box(m_FooterRect, GUIContent.none, nodeFooter); //footer background
281 |
282 | GUI.color = m_NodeOutlineColor;
283 | GUI.Box(m_NodeOutlineRect, GUIContent.none, nodeOutline); //node outline
284 |
285 | GUI.color = initialColor; //reset colors
286 | }
287 |
288 | protected void DrawNodePorts()
289 | {
290 | DrawPortsList(node.inputPorts);
291 | var inspectorArea = new Rect(20, dynamicHeight + 5, width - 40, height);
292 | GUILayout.BeginArea(inspectorArea);
293 | dynamicHeight += DrawInspector();
294 | GUILayout.EndArea();
295 | dynamicHeight += 5;
296 | DrawPortsList(node.outputPorts);
297 | }
298 |
299 | protected void DrawPortsList(List ports)
300 | {
301 | if (ports == null) return;
302 | foreach (Port port in ports)
303 | {
304 | //Update HEIGHT
305 | dynamicHeight += DrawPort(port).height;
306 | }
307 | }
308 |
309 | protected void UpdateNodeWidth(float width)
310 | {
311 | m_Node.SetWidth(width);
312 | }
313 |
314 | protected void UpdateNodeHeight(float height)
315 | {
316 | m_Node.SetHeight(height);
317 | }
318 |
319 | protected void UpdateNodePosition(Vector2 position)
320 | {
321 | m_Node.SetPosition(position);
322 | }
323 |
324 | #endregion
325 |
326 | #region Public Methods
327 |
328 | public void DrawNodeGUI(Rect graphArea, Vector2 panOffset, float zoomLevel)
329 | {
330 | m_Offset = panOffset;
331 | Vector2 windowToGridPosition = m_Node.GetPosition() + m_Offset / zoomLevel;
332 | var clientRect = new Rect(windowToGridPosition, m_Node.GetSize());
333 | GUI.Window(m_WindowId, clientRect, DrawNode, string.Empty, nodeArea);
334 | }
335 |
336 | public virtual float DrawInspector(bool isDetails = false)
337 | {
338 | return DrawObjectInspector(node, isDetails);
339 | }
340 |
341 | #endregion
342 |
343 | #region Private Methods
344 |
345 | private void UpdateColors()
346 | {
347 | m_NodeGlowColor = UColor.GetColor().nodeGlowColor;
348 | m_NodeBodyColor = UColor.GetColor().nodeBodyColor;
349 |
350 | m_HeaderTextAndIconColor = UColor.GetColor().nodeHeaderIconColor;
351 | if (node.GetHasErrors())
352 | {
353 | m_HeaderTextAndIconColor = Color.red;
354 | }
355 |
356 | m_NodeOutlineColor = UColor.GetColor().nodeOutlineColor;
357 | m_NodeOutlineColor.a = GUI.color.a * (isSelected ? 1 : node.isHovered ? 0.4f : 0);
358 | m_NodeHeaderAndFooterBackgroundColor = UColor.GetColor().nodeHeaderAndFooterBackgroundColor;
359 | m_RootNodeHeaderAndFooterBackgroundColor = UColor.GetColor().nodeRootHeaderAndFooterBackgroundColor;
360 | //NODE SELECETD COLOR
361 | if (EditorApplication.isPlaying)
362 | {
363 | if (node.ping)
364 | {
365 | m_NodeOutlineColor = UColor.GetColor().nodePlayingOutlineColor;
366 | }
367 | }
368 | else if (node.ping)
369 | {
370 | node.ping = false;
371 | }
372 | }
373 |
374 | private void DrawNode(int id)
375 | {
376 | var color = GUI.color;
377 | UpdateColors();
378 | OnNodeGUI();
379 | GUI.color = color;
380 | dynamicHeight += m_FooterRect.height + 6 + 2;
381 | UpdateNodeHeight(dynamicHeight);
382 | }
383 |
384 | private void OnDeletePort(Port port)
385 | {
386 | m_graphWindow.DisconnectPort(port);
387 | }
388 |
389 | #endregion
390 |
391 | }
392 |
393 | public abstract class NodeView : NodeView where T : NodeBase
394 | {
395 | public T node => base.node as T;
396 | }
397 | }
--------------------------------------------------------------------------------
/Editor/NodeView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8fdb86a6483146188a515b76b2df8054
3 | timeCreated: 1623033482
--------------------------------------------------------------------------------
/Editor/Tool.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b06523df268d46c89eeb8b0f23024dac
3 | timeCreated: 1623034539
--------------------------------------------------------------------------------
/Editor/Tool/ColorExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Runtime.InteropServices;
5 | using UnityEditor;
6 | using UnityEngine;
7 |
8 | namespace DaGenGraph.Editor
9 | {
10 | public static class ColorExtensions
11 | {
12 | public static Color WithAlpha(this Color color, float alpha)
13 | {
14 | return new Color(color.r, color.g, color.b, alpha);
15 | }
16 | public static Color ColorFrom256(this Color color, float r, float g, float b, float a = 255)
17 | {
18 | return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
19 | }
20 | public static Color Lighter(this Color color)
21 | {
22 | return new Color(color.r + 0.0625f,color.g + 0.0625f,color.b + 0.0625f,color.a);
23 | }
24 | public static Color Darker(this Color color)
25 | {
26 | return new Color(color.r - 0.0625f,color.g - 0.0625f,color.b - 0.0625f,color.a);
27 | }
28 | public static Color FromHex(this Color color, string hexValue, float alpha = 1)
29 | {
30 | if (string.IsNullOrEmpty(hexValue)) return Color.clear;
31 |
32 | if (hexValue[0] == '#') hexValue = hexValue.TrimStart('#');
33 | if (hexValue.Length > 6) hexValue = hexValue.Remove(6, hexValue.Length - 6);
34 |
35 | var value = int.Parse(hexValue, (System.Globalization.NumberStyles) NumberStyles.HexNumber);
36 | var r = value >> 16 & 255;
37 | var g = value >> 8 & 255;
38 | var b = value & 255;
39 | var a = 255 * alpha;
40 | return new Color().ColorFrom256(r, g, b, a);
41 | }
42 | [Flags]
43 | [ComVisible(true)]
44 | [Serializable]
45 | public enum NumberStyles
46 | {
47 | None = 0,
48 | AllowLeadingWhite = 1,
49 | AllowTrailingWhite = 2,
50 | AllowLeadingSign = 4,
51 | AllowTrailingSign = 8,
52 | AllowParentheses = 16, // 0x00000010
53 | AllowDecimalPoint = 32, // 0x00000020
54 | AllowThousands = 64, // 0x00000040
55 | AllowExponent = 128, // 0x00000080
56 | AllowCurrencySymbol = 256, // 0x00000100
57 | AllowHexSpecifier = 512, // 0x00000200
58 | Integer = AllowLeadingSign | AllowTrailingWhite | AllowLeadingWhite, // 0x00000007
59 | HexNumber = AllowHexSpecifier | AllowTrailingWhite | AllowLeadingWhite, // 0x00000203
60 | Number = Integer | AllowThousands | AllowDecimalPoint | AllowTrailingSign, // 0x0000006F
61 | Float = Integer | AllowExponent | AllowDecimalPoint, // 0x000000A7
62 | Currency = Number | AllowCurrencySymbol | AllowParentheses, // 0x0000017F
63 | Any = Currency | AllowExponent, // 0x000001FF
64 | }
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/Editor/Tool/ColorExtensions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1138513f102c2b247a9fdec283c60539
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Editor/Tool/Styles.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEditor;
3 | using UnityEngine;
4 |
5 | namespace DaGenGraph.Editor
6 | {
7 | public class Styles
8 | {
9 | private static readonly string DarkSkinPath = "Packages/com.lifang.dagen/Style/DarkSkin.guiskin";
10 |
11 | private static GUISkin s_darkSkin;
12 |
13 | private static GUISkin DarkSkin =>
14 | s_darkSkin == null ?
15 | (s_darkSkin = AssetDatabase.LoadAssetAtPath(DarkSkinPath))
16 | : s_darkSkin;
17 |
18 |
19 | private static Dictionary s_darkStyles;
20 |
21 | private static Dictionary DarkStyles
22 | {
23 | get { return s_darkStyles ?? (s_darkStyles = new Dictionary()); }
24 | }
25 |
26 | public static GUIStyle GetStyle(string styleName)
27 | {
28 | if (DarkStyles.ContainsKey(styleName)) return DarkStyles[styleName];
29 | var newDarkStyle = DarkSkin.GetStyle(styleName);
30 | if (newDarkStyle != null) DarkStyles.Add(styleName, newDarkStyle);
31 | return new GUIStyle(newDarkStyle);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/Editor/Tool/Styles.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9db978ce4acd47b6bd5e8d8f08593045
3 | timeCreated: 1621936952
--------------------------------------------------------------------------------
/Editor/Tool/UIColor.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 |
4 | namespace DaGenGraph.Editor
5 | {
6 | [CreateAssetMenu(fileName = "UIColor", menuName = "DaGenGraph/UIColor", order = 0)]
7 | public class UIColor : ScriptableObject
8 | {
9 | [Tooltip("Node的边缘光颜色")] public Color nodeGlowColor;
10 | [Tooltip("Node的页眉和页脚背景颜色")] public Color nodeHeaderAndFooterBackgroundColor;
11 | [Tooltip("起始Node的页眉和页脚背景颜色")] public Color nodeRootHeaderAndFooterBackgroundColor;
12 | [Tooltip("Node的主体颜色")] public Color nodeBodyColor;
13 | [Tooltip("Node的选中框颜色")] public Color nodeOutlineColor;
14 | [Tooltip("Node的运行状态下选中框的颜色")] public Color nodePlayingOutlineColor;
15 | [Tooltip("Node的Icon颜色")] public Color nodeHeaderIconColor;
16 | [Tooltip("Node的分割线颜色")] public Color nodeDividerColor;
17 | [Tooltip("InputPort的颜色")] public Color portInputColor;
18 | [Tooltip("OutputPort的颜色")] public Color portOutputColor;
19 | [Tooltip("InputEdge被选中的颜色")] public Color edgeInputColor;
20 | [Tooltip("OutputEdge被选中的颜色")] public Color edgeOutputColor;
21 | [Tooltip("Edge正常的颜色")] public Color edgeNormalColor;
22 | }
23 |
24 | public class UColor
25 | {
26 | private static UIColor s_UIColor;
27 |
28 | private static UIColor uiColor
29 | {
30 | get
31 | {
32 | if (s_UIColor == null)
33 | {
34 | s_UIColor = AssetDatabase.LoadAssetAtPath("Packages/com.lifang.dagen/Style/UIColor.asset");
35 | }
36 |
37 | return s_UIColor;
38 | }
39 | }
40 |
41 | public static UIColor GetColor()
42 | {
43 | return uiColor;
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/Editor/Tool/UIColor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8d62153adfe14b47838b7e9be2b9ab2b
3 | timeCreated: 1625450541
--------------------------------------------------------------------------------
/Example.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bb37d781f8ea4539b09e4e14de4ab4a4
3 | timeCreated: 1736996880
--------------------------------------------------------------------------------
/Example/DaGenGraph.Example.asmdef:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DaGenGraph.Example",
3 | "rootNamespace": "",
4 | "references": [
5 | "GUID:82c60e129e644f1a875828179b3e9c80",
6 | "GUID:b637e77054d21444096d4d4e5637ed30"
7 | ],
8 | "includePlatforms": [
9 | "Editor"
10 | ],
11 | "excludePlatforms": [],
12 | "allowUnsafeCode": false,
13 | "overrideReferences": false,
14 | "precompiledReferences": [],
15 | "autoReferenced": true,
16 | "defineConstraints": [],
17 | "versionDefines": [],
18 | "noEngineReferences": false
19 | }
--------------------------------------------------------------------------------
/Example/DaGenGraph.Example.asmdef.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2fbbf606bcf587849ba86e94fdf333e4
3 | AssemblyDefinitionImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Example/ExampleGraph.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace DaGenGraph.Example
4 | {
5 | public class ExampleGraph: GraphBase
6 | {
7 |
8 | }
9 | }
--------------------------------------------------------------------------------
/Example/ExampleGraph.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d68e754e6a434fc0b8d21577b44e01ac
3 | timeCreated: 1736998217
--------------------------------------------------------------------------------
/Example/ExampleGraphWindow.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using DaGenGraph.Editor;
4 | using UnityEditor;
5 | using UnityEditor.Callbacks;
6 | using UnityEngine;
7 |
8 | namespace DaGenGraph.Example
9 | {
10 | public class ExampleGraphWindow: GraphWindow
11 | {
12 | private string path;
13 | internal static ExampleGraphWindow instance
14 | {
15 | get
16 | {
17 | if (s_Instance != null) return s_Instance;
18 | var windows = Resources.FindObjectsOfTypeAll();
19 | s_Instance = windows.Length > 0 ? windows[0] : null;
20 | if (s_Instance != null) return s_Instance;
21 | s_Instance = CreateWindow();
22 | return s_Instance;
23 | }
24 | }
25 |
26 | private static ExampleGraphWindow s_Instance;
27 |
28 | [MenuItem("DaGenGraph/ExampleGraphWindow")]
29 | public static void GetWindow()
30 | {
31 | instance.titleContent = new GUIContent("ExampleGraphWindow");
32 | instance.Show();
33 | instance.InitGraph();
34 | }
35 | [OnOpenAsset(0)]
36 | public static bool OnBaseDataOpened(int instanceID, int line)
37 | {
38 | var data = EditorUtility.InstanceIDToObject(instanceID) as ExampleGraph;
39 | if (data != null)
40 | {
41 | var path = AssetDatabase.GetAssetPath(data);
42 | instance.Show();
43 | instance.path = path;
44 | instance.SetGraph(data);
45 | }
46 | return data != null;
47 | }
48 | protected override void InitGraph()
49 | {
50 | path = null;
51 | base.InitGraph();
52 | }
53 |
54 | protected override ExampleGraph CreateGraph()
55 | {
56 | return CreateInstance();
57 | }
58 |
59 | protected override ExampleGraph LoadGraph()
60 | {
61 | string searchPath = EditorUtility.OpenFilePanel($"新建{nameof(ExampleGraph)}配置文件", "Assets", "asset");
62 | if (!string.IsNullOrEmpty(searchPath))
63 | {
64 | searchPath = "Assets/"+searchPath.Split("/Assets/")[1];
65 | var obj = AssetDatabase.LoadAssetAtPath(searchPath);
66 | if (obj == null) return null;
67 | path = searchPath;
68 | return obj;
69 | }
70 | return null;
71 | }
72 |
73 | protected override void SaveGraph()
74 | {
75 | if (string.IsNullOrEmpty(path))
76 | {
77 | string searchPath = EditorUtility.SaveFilePanel($"新建{nameof(ExampleGraph)}配置文件", "Assets",
78 | nameof(ExampleGraph), "asset");
79 | if (string.IsNullOrEmpty(searchPath)) return;
80 |
81 | path = "Assets/"+searchPath.Split("/Assets/")[1];
82 | AssetDatabase.CreateAsset(m_Graph,path);
83 | }
84 | else
85 | {
86 | EditorUtility.SetDirty(m_Graph);
87 | }
88 | AssetDatabase.SaveAssets();
89 | AssetDatabase.Refresh();
90 | }
91 |
92 | protected override void AddGraphMenuItems(GenericMenu menu)
93 | {
94 | var current = Event.current;
95 | base.AddGraphMenuItems(menu);
96 | menu.AddItem(new GUIContent("New/Node"), false, () =>
97 | {
98 | if (m_Graph == null)
99 | {
100 | InitGraph();
101 | }
102 | if (string.IsNullOrEmpty(path))
103 | {
104 | string searchPath = EditorUtility.SaveFilePanel($"新建{nameof(ExampleGraph)}配置文件", "Assets",
105 | nameof(ExampleGraph), "asset");
106 | if (string.IsNullOrEmpty(searchPath)) return ;
107 |
108 | path = "Assets/"+searchPath.Split("/Assets/")[1];
109 | AssetDatabase.CreateAsset(m_Graph,path);
110 | AssetDatabase.SaveAssets();
111 | AssetDatabase.Refresh();
112 | }
113 | CreateNodeView(m_Graph.CreateNode(current.mousePosition));
114 | });
115 | }
116 |
117 | protected override void AddNodeMenuItems(GenericMenu menu, NodeBase nodeBase)
118 | {
119 | base.AddNodeMenuItems(menu, nodeBase);
120 | menu.AddItem(new GUIContent("AddInputPort"), false,
121 | () => { nodeBase.AddInputPort("InputName", EdgeMode.Multiple, true, true); });
122 | menu.AddItem(new GUIContent("AddOutputPort"), false,
123 | () => { nodeBase.AddOutputPort("OutputName", EdgeMode.Multiple, true, true); });
124 | }
125 |
126 | protected override void AddPortMenuItems(GenericMenu menu, Port port, bool isLine = false)
127 | {
128 | base.AddPortMenuItems(menu, port, isLine);
129 | if(!isLine)
130 | menu.AddItem(new GUIContent("Delete"), false, () => { RemovePort(port); });
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/Example/ExampleGraphWindow.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 752f5a2d02c24b7f90837f158fb38a93
3 | timeCreated: 1736996916
--------------------------------------------------------------------------------
/Example/ExampleNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using UnityEditor;
4 | #if ODIN_INSPECTOR
5 | using Sirenix.OdinInspector;
6 | #endif
7 | using UnityEngine;
8 |
9 | namespace DaGenGraph.Example
10 | {
11 | [Serializable]
12 | public class TestClass
13 | {
14 | public string TestClassText;
15 | }
16 | [NodeViewType(typeof(ExampleNodeView))]
17 | public class ExampleNode: NodeBase
18 | {
19 | public string Text;
20 | [Min(10)]
21 | public int Number;
22 |
23 | [Min(10)][ValueDropdown("@Error(123)")]
24 | public int NumberValueDropdown;
25 | [DrawIgnore(Ignore.NodeView)]
26 | public Vector4 Vector4;
27 |
28 | [ReadOnly]
29 | public Ignore Ignore;
30 |
31 | [Range(-20,20)]
32 | public float Range;
33 |
34 | [Tooltip("测试Tooltip")]
35 | public Color Color;
36 |
37 | [ReadOnly]
38 | public TestClass TestClass;
39 |
40 | public int[] IntArray;
41 | public List RectList;
42 | public List TestClasses;
43 |
44 | //详情面板选择有bug
45 | [NonSerialized][OnValueChanged(nameof(SetPath))][BoxGroup("Group")]
46 | public GameObject GameObject;
47 |
48 | public void SetPath()
49 | {
50 | if (GameObject == null) Path = null;
51 | var path = AssetDatabase.GetAssetPath(GameObject);
52 | if (path.StartsWith("Assets/AssetsPackage/"))
53 | {
54 | Path = path.Replace("Assets/AssetsPackage/","");
55 | }
56 | else
57 | {
58 | Path = null;
59 | }
60 | }
61 | [BoxGroup("Group")][Button("ButtonTest")]
62 | public void Preview()
63 | {
64 | if (string.IsNullOrEmpty(Path)) return;
65 | if (!Path.StartsWith("Assets/AssetsPackage/"))
66 | GameObject = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/AssetsPackage/" +Path);
67 | else
68 | GameObject = UnityEditor.AssetDatabase.LoadAssetAtPath(Path);
69 |
70 | }
71 | [ReadOnly] [BoxGroup("Group")]
72 | public string Path;
73 |
74 | [NonSerialized]
75 | public Sprite Sprite;
76 |
77 | public AnimationCurve AnimationCurve;
78 | [Space(15)][PropertyOrder]
79 | public Rect Rect;
80 | [NotAssets][Header("Header")][InfoBox("注意:除数不能为0")]
81 | public NodeBase NodeBase;
82 |
83 | public Dictionary TestClassDic;
84 | public override void AddDefaultPorts()
85 | {
86 | AddOutputPort("DefaultOutputName", EdgeMode.Multiple, true, true);
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/Example/ExampleNode.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 89cbec8b868f400ea8556d2253b0ebd9
3 | timeCreated: 1737095529
--------------------------------------------------------------------------------
/Example/ExampleNodeView.cs:
--------------------------------------------------------------------------------
1 | using DaGenGraph.Editor;
2 |
3 | namespace DaGenGraph.Example
4 | {
5 | public class ExampleNodeView : NodeView
6 | {
7 | public override float DrawInspector(bool isDetails = false)
8 | {
9 | return base.DrawInspector(isDetails);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/ExampleNodeView.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2ad4f30b38bb4d988cfadd0398bf3bd4
3 | timeCreated: 1737101823
--------------------------------------------------------------------------------
/GraphBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using UnityEngine;
5 |
6 | namespace DaGenGraph
7 | {
8 | [Serializable]
9 | public abstract class GraphBase: ScriptableObject
10 | {
11 | [HideInInspector]
12 | public Vector2 currentPanOffset = Vector2.zero;
13 | [HideInInspector]
14 | public float currentZoom = 1f;
15 | [HideInInspector]
16 | public int windowID;
17 | [HideInInspector]
18 | public string startNodeId;
19 | [HideInInspector]
20 | public bool leftInRightOut;
21 | [HideInInspector]
22 | public List values = new();
23 | [HideInInspector]
24 | public List edges = new();
25 | protected virtual T CreateNodeBase() where T: NodeBase
26 | {
27 | var node = CreateInstance() ;
28 | node.name = "Node";
29 | #if UNITY_EDITOR
30 | try
31 | {
32 | UnityEditor.AssetDatabase.AddObjectToAsset(node, this);
33 | }
34 | catch (Exception ex)
35 | {
36 | Debug.LogError(ex);
37 | return null;
38 | }
39 | #endif
40 | return node;
41 | }
42 |
43 | protected virtual void DeleteNodeBase(T nodeBase) where T: NodeBase
44 | {
45 | DestroyImmediate(nodeBase,true);
46 | }
47 |
48 | public NodeBase GetStartNode()
49 | {
50 | return FindNode(startNodeId);
51 | }
52 |
53 | public NodeBase FindNode(string nodeId)
54 | {
55 | if (!string.IsNullOrEmpty(nodeId))
56 | {
57 | for (int i = 0; i < values.Count; i++)
58 | {
59 | if (values[i].id == nodeId)
60 | {
61 | return values[i];
62 | }
63 | }
64 | }
65 |
66 | return null;
67 | }
68 |
69 | public T CreateNode(Vector2 pos, string nodeName = "Node", bool isRoot = false) where T: NodeBase
70 | {
71 | var node = CreateNodeBase();
72 | node.InitNode(WorldToGridPosition(pos), nodeName);
73 | values.Add(node);
74 | if ((isRoot || string.IsNullOrEmpty(startNodeId)) && values.Count>0)
75 | {
76 | startNodeId = values.First().id;
77 | }
78 | node.AddDefaultPorts();
79 | return node;
80 | }
81 |
82 | public void RemoveNode(string nodeId)
83 | {
84 | if (!string.IsNullOrEmpty(nodeId))
85 | {
86 | for (int i = 0; i < values.Count; i++)
87 | {
88 | if (values[i].id == nodeId)
89 | {
90 | DeleteNodeBase(values[i]);
91 | values.RemoveAt(i);
92 | break;
93 | }
94 | }
95 | }
96 | }
97 |
98 | public Vector2 WorldToGridPosition(Vector2 worldPosition)
99 | {
100 | return (worldPosition - currentPanOffset) / currentZoom;
101 | }
102 |
103 | public Edge GetEdge(string edgeId)
104 | {
105 | for (int i = 0; i < edges.Count; i++)
106 | {
107 | if (edges[i].id == edgeId)
108 | {
109 | return edges[i];
110 | }
111 | }
112 | return null;
113 | }
114 |
115 | public Edge CreateEdge(Port outputPort, Port inputPort)
116 | {
117 | var edge = CreateEdgeBase();
118 | edge.Init(outputPort, inputPort);
119 | edges.Add(edge);
120 | outputPort.edges.Add(edge.id);
121 | inputPort.edges.Add(edge.id);
122 | return edge;
123 | }
124 |
125 | public void RemoveEdge(string edgeId)
126 | {
127 | if (!string.IsNullOrEmpty(edgeId))
128 | {
129 | for (int i = 0; i < edges.Count; i++)
130 | {
131 | if (edges[i].id == edgeId)
132 | {
133 | var edge = edges[i];
134 | edges.RemoveAt(i);
135 | DestroyImmediate(edge, true);
136 | break;
137 | }
138 | }
139 | }
140 |
141 | }
142 |
143 | protected virtual Edge CreateEdgeBase()
144 | {
145 | var edge = CreateInstance() ;
146 | edge.name = "Edge";
147 | #if UNITY_EDITOR
148 | try
149 | {
150 | UnityEditor.AssetDatabase.AddObjectToAsset(edge, this);
151 | }
152 | catch (Exception ex)
153 | {
154 | Debug.LogError(ex);
155 | return null;
156 | }
157 | #endif
158 | return edge;
159 | }
160 |
161 | protected virtual void RemoveEdgeBase(Edge edge)
162 | {
163 | DestroyImmediate(edge,true);
164 | }
165 | }
166 | }
--------------------------------------------------------------------------------
/GraphBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f68572d430994f109868d8323a74d065
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/JsonGraphBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DaGenGraph
4 | {
5 | public abstract class JsonGraphBase: GraphBase
6 | {
7 | protected override T CreateNodeBase()
8 | {
9 | var node = Activator.CreateInstance() ;
10 | node.name = "Node";
11 | return node;
12 | }
13 |
14 | protected override void DeleteNodeBase(T nodeBase)
15 | {
16 |
17 | }
18 |
19 | protected override Edge CreateEdgeBase()
20 | {
21 | var edge = Activator.CreateInstance() ;
22 | edge.name = "Edge";
23 | return edge;
24 | }
25 |
26 | protected override void RemoveEdgeBase(Edge edge)
27 | {
28 |
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/JsonGraphBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5a017f59f3d24e86849d851b82e8eea5
3 | timeCreated: 1737339544
--------------------------------------------------------------------------------
/JsonNodeBase.cs:
--------------------------------------------------------------------------------
1 | namespace DaGenGraph
2 | {
3 | public abstract class JsonNodeBase:NodeBase
4 | {
5 | protected override Port CreatePortBase()
6 | {
7 | var node = CreateInstance();
8 | node.name = "Port";
9 | return node;
10 | }
11 |
12 | protected override void DeletePortBase(Port port)
13 | {
14 |
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/JsonNodeBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 72cb48469c7c4c3a81b4288b0390b6c3
3 | timeCreated: 1737339449
--------------------------------------------------------------------------------
/NodeBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using UnityEngine;
5 |
6 | namespace DaGenGraph
7 | {
8 | [Serializable]
9 | public abstract class NodeBase: ScriptableObject
10 | {
11 | #region public Variables
12 |
13 | [DrawIgnore] public List inputPorts;
14 | [DrawIgnore] public List outputPorts;
15 | [DrawIgnore] public bool allowDuplicateNodeName;
16 | [DrawIgnore] public bool allowEmptyNodeName;
17 | [DrawIgnore] public bool canBeDeleted;
18 | [DrawIgnore] public float height;
19 | [DrawIgnore] public float width;
20 | [DrawIgnore] public float x;
21 | [DrawIgnore] public float y;
22 | [DrawIgnore] public int minimumInputPortsCount;
23 | [DrawIgnore] public int minimumOutputPortsCount;
24 | [DrawIgnore] public string id;
25 | [DrawIgnore] public bool isHovered;
26 | [DrawIgnore] public bool errorNodeNameIsEmpty;
27 | [DrawIgnore] public bool errorDuplicateNameFoundInGraph;
28 |
29 | /// Trigger a visual cue for this node, in the Editor, at runtime. Mostly used when this node has been activated
30 | [DrawIgnore] public bool ping;
31 |
32 | public event DeletePortDelegate onDeletePort;
33 |
34 | public delegate void DeletePortDelegate(Port port);
35 |
36 | #endregion
37 |
38 | #region Editor
39 |
40 | public virtual bool GetHasErrors() => errorNodeNameIsEmpty || errorDuplicateNameFoundInGraph;
41 |
42 |
43 | /// Returns the first input port. If there isn't one, it returns null
44 | public Port GetFirstInputPort() => inputPorts.Count > 0 ? inputPorts[0] : null;
45 |
46 | /// Returns the first output port. If there isn't one, it returns null
47 | public Port GetFirstOutputPort() => outputPorts.Count > 0 ? outputPorts[0] : null;
48 |
49 |
50 | private void CheckThatNodeNameIsNotEmpty()
51 | {
52 | #if UNITY_EDITOR
53 | errorNodeNameIsEmpty = false;
54 | if (allowEmptyNodeName) return;
55 | errorNodeNameIsEmpty = string.IsNullOrEmpty(name.Trim());
56 | #endif
57 | }
58 |
59 | ///
60 | /// Checks if this node has any errors. Because each type of node can have different errors, this method is used to define said custom errors and reflect that in the NodeGraph (for the NodeGUI) and in the Inspector (for
61 | /// the NodeEditor)
62 | ///
63 | public virtual void CheckForErrors()
64 | {
65 | #if UNITY_EDITOR
66 | CheckThatNodeNameIsNotEmpty();
67 | #endif
68 | }
69 |
70 | #endregion
71 |
72 | #region Protected Methods
73 |
74 |
75 | /// Set to allow this node to have an empty node name
76 | /// Disable error for empty node name
77 | protected void SetAllowEmptyNodeName(bool value)
78 | {
79 | allowEmptyNodeName = value;
80 | }
81 |
82 | /// Set to allow this node to have a duplicate node name
83 | /// Disable error for duplicate node name
84 | protected void SetAllowDuplicateNodeName(bool value)
85 | {
86 | allowDuplicateNodeName = value;
87 | }
88 |
89 | #endregion
90 |
91 | #region Public Methods
92 |
93 | /// Returns the x coordinate of this node
94 | public float GetX()
95 | {
96 | return x;
97 | }
98 |
99 | /// Returns the y coordinate of this node
100 | public float GetY()
101 | {
102 | return y;
103 | }
104 |
105 | /// Returns the width of this node
106 | public float GetWidth()
107 | {
108 | return width;
109 | }
110 |
111 | /// Returns the height of this node
112 | public float GetHeight()
113 | {
114 | return height;
115 | }
116 |
117 | /// Returns the position of this node
118 | public Vector2 GetPosition()
119 | {
120 | return new Vector2(x, y);
121 | }
122 |
123 | /// Returns the size of this node (x is width, y is height)
124 | public Vector2 GetSize()
125 | {
126 | return new Vector2(GetWidth(), height);
127 | }
128 |
129 | /// Returns the Rect of this node
130 | public Rect GetRect()
131 | {
132 | return new Rect(x, y, GetWidth(), height);
133 | }
134 |
135 | public Rect GetFooterRect()
136 | {
137 | return new Rect(GetX() + 6, GetY() - 6 + GetHeight() - 10, GetWidth() - 12, 10);
138 | }
139 |
140 | /// Returns the Rect of this node's header
141 | public Rect GetHeaderRect()
142 | {
143 | return new Rect(GetX() + 6, GetY() + 6, GetWidth() - 12, 32);
144 | }
145 |
146 | /// Set the name for this node
147 | /// The new node name value
148 | public void SetName(string value)
149 | {
150 | name = value;
151 | }
152 |
153 | /// Set the position of this node's Rect
154 | /// The new position value
155 | public void SetPosition(Vector2 position)
156 | {
157 | x = position.x;
158 | y = position.y;
159 | }
160 |
161 | /// Set the position of this node's Rect
162 | /// The new x coordinate value
163 | /// The new y coordinate value
164 | public void SetPosition(float x, float y)
165 | {
166 | this.x = x;
167 | this.y = y;
168 | }
169 |
170 | /// Set the Rect values for this node
171 | /// The new rect values
172 | public void SetRect(Rect rect)
173 | {
174 | x = rect.x;
175 | y = rect.y;
176 | width = rect.width;
177 | height = rect.height;
178 | }
179 |
180 | /// Set the Rect values for this node
181 | /// The new position value
182 | /// The new size value
183 | public void SetRect(Vector2 position, Vector2 size)
184 | {
185 | x = position.x;
186 | y = position.y;
187 | width = size.x;
188 | height = size.y;
189 | }
190 |
191 | /// Set the Rect values for this node
192 | /// The new x coordinate value
193 | /// The new y coordinate value
194 | /// The new width value
195 | /// The new height value
196 | public void SetRect(float x, float y, float width, float height)
197 | {
198 | this.x = x;
199 | this.x = y;
200 | this.width = width;
201 | this.height = height;
202 | }
203 |
204 | /// Set the size of this node's Rect
205 | /// The new node size (x is width, y is height)
206 | public void SetSize(Vector2 size)
207 | {
208 | width = size.x;
209 | height = size.y;
210 | }
211 |
212 | /// Set the size of this node's Rect
213 | /// The new width value
214 | /// The new height value
215 | public void SetSize(float width, float height)
216 | {
217 | this.width = width;
218 | this.height = height;
219 | }
220 |
221 | /// Set the width of this node's Rect
222 | /// The new width value
223 | public void SetWidth(float value)
224 | {
225 | width = value;
226 | }
227 |
228 | /// Set the height of this node's Rect
229 | /// The new height value
230 | public void SetHeight(float value)
231 | {
232 | height = value;
233 | }
234 |
235 | /// Set the x coordinate of this node's Rect
236 | /// The new x value
237 | public void SetX(float value)
238 | {
239 | x = value;
240 | }
241 |
242 | /// Set the y coordinate of this node's Rect
243 | /// The new y value
244 | public void SetY(float value)
245 | {
246 | y = value;
247 | }
248 | /// Convenience method to add a new input port to this node
249 | /// The name of the port (if null or empty, it will be auto-generated)
250 | /// The port edge mode (Multiple/Override)
251 | /// The port edge points locations (if null or empty, it will automatically add two edge points to the left of and the right of the port)
252 | /// Determines if this port is a special port that cannot be deleted
253 | /// Determines if this port is a special port that cannot be reordered
254 | public Port AddInputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, EdgeType edgeType,
255 | bool canBeReordered = true) where T: Port
256 | {
257 | return AddPort(portName, PortDirection.Input, edgeMode, canBeDeleted, canBeReordered, edgeType);
258 | }
259 | /// Convenience method to add a new input port to this node
260 | /// The name of the port (if null or empty, it will be auto-generated)
261 | /// The port edge mode (Multiple/Override)
262 | /// The port edge points locations (if null or empty, it will automatically add two edge points to the left of and the right of the port)
263 | /// Determines if this port is a special port that cannot be deleted
264 | /// Determines if this port is a special port that cannot be reordered
265 | public Port AddInputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, EdgeType edgeType,
266 | bool canBeReordered = true)
267 | {
268 | return AddPort(portName, PortDirection.Input, edgeMode, canBeDeleted, canBeReordered, edgeType);
269 | }
270 |
271 | /// Convenience method to add a new input port to this node. This port will have two edge points automatically added to it and they will be to the left of and the right the port
272 | /// The name of the port (if null or empty, it will be auto-generated)
273 | /// The port edge mode (Multiple/Override)
274 | /// Determines if this port is a special port that cannot be deleted
275 | /// Determines if this port is a special port that cannot be reordered
276 | public Port AddInputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, bool canBeReordered)
277 | {
278 | return AddPort(portName, PortDirection.Input, edgeMode, canBeDeleted,
279 | canBeReordered);
280 | }
281 |
282 | /// Convenience method to add a new input port to this node. This port will have two edge points automatically added to it and they will be to the left of and the right the port
283 | /// The port edge mode (Multiple/Override)
284 | /// Determines if this port is a special port that cannot be deleted
285 | /// Determines if this port is a special port that cannot be reordered
286 | public Port AddInputPort(EdgeMode edgeMode, bool canBeDeleted, bool canBeReordered)
287 | {
288 | return AddPort("", PortDirection.Input, edgeMode, canBeDeleted,
289 | canBeReordered);
290 | }
291 | /// Convenience method to add a new output port to this node
292 | /// The name of the port (if null or empty, it will be auto-generated)
293 | /// The port edge mode (Multiple/Override)
294 | /// The port edge points locations (if null or empty, it will automatically add two edge points to the left of and the right of the port)
295 | /// Determines if this port is a special port that cannot be deleted
296 | /// Determines if this port is a special port that cannot be reordered
297 | public Port AddOutputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, EdgeType edgeType ,
298 | bool canBeReordered) where T: Port
299 | {
300 | return AddPort(portName, PortDirection.Output, edgeMode, canBeDeleted, canBeReordered,edgeType);
301 | }
302 | /// Convenience method to add a new output port to this node
303 | /// The name of the port (if null or empty, it will be auto-generated)
304 | /// The port edge mode (Multiple/Override)
305 | /// The port edge points locations (if null or empty, it will automatically add two edge points to the left of and the right of the port)
306 | /// Determines if this port is a special port that cannot be deleted
307 | /// Determines if this port is a special port that cannot be reordered
308 | public Port AddOutputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, EdgeType edgeType ,
309 | bool canBeReordered)
310 | {
311 | return AddPort(portName, PortDirection.Output, edgeMode, canBeDeleted, canBeReordered,edgeType);
312 | }
313 |
314 | /// Convenience method to add a new output port to this node. This port will have two edge points automatically added to it and they will be to the left of and the right the port
315 | /// The name of the port (if null or empty, it will be auto-generated)
316 | /// The port edge mode (Multiple/Override)
317 | /// Determines if this port is a special port that cannot be deleted
318 | /// Determines if this port is a special port that cannot be reordered
319 | public Port AddOutputPort(string portName, EdgeMode edgeMode, bool canBeDeleted, bool canBeReordered)
320 | {
321 | return AddPort(portName, PortDirection.Output, edgeMode, canBeDeleted, canBeReordered);
322 | }
323 |
324 | /// Convenience method to add a new output port to this node. This port will have two edge points automatically added to it and they will be to the left of and the right the port
325 | /// The port edge mode (Multiple/Override)
326 | /// Determines if this port is a special port that cannot be deleted
327 | /// Determines if this port is a special port that cannot be reordered
328 | public Port AddOutputPort(EdgeMode edgeMode, bool canBeDeleted, bool canBeReordered)
329 | {
330 | return AddPort("", PortDirection.Output, edgeMode, canBeDeleted, canBeReordered);
331 | }
332 |
333 | /// Returns TRUE if the target port can be deleted, after checking is it is marked as 'deletable' and that by deleting it the node minimum ports count does not go below the set threshold
334 | /// Target port
335 | public bool CanDeletePort(Port port)
336 | {
337 | //if port is market as cannot be deleted -> return false -> do not allow the dev to delete this port
338 | if (!port.canBeDeleted) return false;
339 | //if port is input -> make sure the node has a minimum input ports count before allowing deletion
340 | if (port.IsInput()) return inputPorts.Count > minimumInputPortsCount;
341 | //if port is output -> make sure the node has a minimum output ports count before allowing deletion
342 | if (port.IsOutput()) return outputPorts.Count > minimumOutputPortsCount;
343 | //event though the port can be deleted -> the node needs to hold a minimum number of ports and will not allow to delete this port
344 | return false;
345 | }
346 |
347 | /// Returns TRUE if a edge with the given id can be found on one of this node's ports
348 | /// Target edge id
349 | public bool ContainsEdge(string edgeId)
350 | {
351 | foreach (var port in inputPorts)
352 | {
353 | if (port.edges.Contains(edgeId)) return true;
354 | }
355 |
356 | foreach (var port in outputPorts)
357 | {
358 | if (port.edges.Contains(edgeId)) return true;
359 | }
360 | return false;
361 | }
362 |
363 | ///
364 | ///
365 | ///
366 | ///
367 | public void DeletePort(Port port)
368 | {
369 | if (port.IsInput()) inputPorts.Remove(port);
370 | if (port.IsOutput()) outputPorts.Remove(port);
371 | onDeletePort?.Invoke(port);
372 | DeletePortBase(port);
373 | }
374 | #endregion
375 |
376 | #region Private Methods
377 |
378 | /// Adds a port to this node
379 | /// The name of the port (if null or empty, it will be auto-generated)
380 | /// The port direction (Input/Output)
381 | /// The port edge mode (Multiple/Override)
382 | /// The port edge points locations (if null or empty, it will automatically add two edge points to the left of and the right of the port)
383 | /// Determines if this port is a special port that cannot be deleted
384 | /// Determines if this port is a special port that cannot be reordered
385 | private Port AddPort(string portName, PortDirection direction, EdgeMode edgeMode,
386 | bool canBeDeleted, bool canBeReordered , EdgeType edgeType = EdgeType.Both)where T:Port
387 | {
388 | string baseName = portName;
389 | var portNames = new List();
390 | int counter = 1;
391 | switch (direction)
392 | {
393 | case PortDirection.Input:
394 | foreach (Port port in inputPorts)
395 | portNames.Add(port.portName);
396 | if (string.IsNullOrEmpty(baseName))
397 | {
398 | baseName = "InputPort_";
399 | portName = baseName + counter++;
400 | }
401 |
402 | while (portNames.Contains(portName))
403 | {
404 | portName = baseName + counter++;
405 | }
406 |
407 | var inputPort = CreatePortBase();
408 | inputPort.Init(this, portName, direction, edgeMode, edgeType, canBeDeleted, canBeReordered);
409 | inputPorts.Add(inputPort);
410 | return inputPort;
411 | case PortDirection.Output:
412 | foreach (Port port in outputPorts)
413 | portNames.Add(port.portName);
414 | if (string.IsNullOrEmpty(baseName))
415 | {
416 | baseName = "OutputPort_";
417 | portName = baseName + counter++;
418 | }
419 |
420 | while (portNames.Contains(portName))
421 | {
422 | portName = baseName + counter++;
423 | }
424 | var outputPort = CreatePortBase();
425 | outputPort.Init(this, portName, direction, edgeMode, edgeType, canBeDeleted, canBeReordered);
426 | outputPorts.Add(outputPort);
427 | return outputPort;
428 | default:
429 | throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
430 | }
431 | }
432 |
433 | /// Generates a new unique node id for this node and returns the newly generated id value
434 | private void GenerateNewId()
435 | {
436 | id = Guid.NewGuid().ToString();
437 | }
438 |
439 | #endregion
440 |
441 | #region Public virtual Methods
442 |
443 | protected virtual Port CreatePortBase() where T:Port
444 | {
445 | var port = CreateInstance();
446 | port.name = "Port";
447 | #if UNITY_EDITOR
448 | try
449 | {
450 | UnityEditor.AssetDatabase.AddObjectToAsset(port, this);
451 | }
452 | catch (Exception ex)
453 | {
454 | Debug.LogError(ex);
455 | return null;
456 | }
457 | #endif
458 | return port;
459 | }
460 |
461 | protected virtual void DeletePortBase(Port port)
462 | {
463 | DestroyImmediate(port,true);
464 | }
465 |
466 | /// OnEnterNode is called on the frame when this node becomes active just before any of the node's Update methods are called for the first time
467 | /// The node that was active before this one
468 | /// The edge that activated this node
469 | public virtual void OnEnter(NodeBase previousActiveNode, Edge edge)
470 | {
471 | ping = true;
472 | }
473 |
474 | /// OnExitNode is called just before this node becomes inactive
475 | /// The node that will become active next
476 | /// The edge that activates the next node
477 | public virtual void OnExit(NodeBase nextActiveNode, Edge edge)
478 | {
479 | ping = false;
480 | if (edge != null)
481 | {
482 | edge.ping = true;
483 | edge.reSetTime = true;
484 | }
485 | }
486 |
487 | public virtual void InitNode(Vector2 pos, string nodeName, int minInputPortsCount = 0, int minOutputPortsCount = 0)
488 | {
489 | name = nodeName;
490 | GenerateNewId();
491 | inputPorts = new List();
492 | outputPorts = new List();
493 | canBeDeleted = true;
494 | this.minimumInputPortsCount = minInputPortsCount;
495 | this.minimumOutputPortsCount = minOutputPortsCount;
496 | x = pos.x;
497 | y = pos.y;
498 | width = 260f;
499 | height = 200f;
500 | }
501 |
502 | public abstract void AddDefaultPorts();
503 |
504 | #endregion
505 | }
506 | }
--------------------------------------------------------------------------------
/NodeBase.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 625d46cb5a0c45ae94f424854f1741a0
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Port.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using UnityEngine;
5 |
6 | namespace DaGenGraph
7 | {
8 | public class Port: ScriptableObject
9 | {
10 |
11 | #region public Variables
12 |
13 | #if UNITY_EDITOR
14 | [NonSerialized] public UnityEditor.AnimatedValues.AnimBool showHover = new (false);
15 | #endif
16 | [NonSerialized] public Rect hoverRect;
17 | [NonSerialized] private List edgePoints;
18 |
19 | public EdgeType edgeType;
20 | public List edges;
21 | public PortDirection direction;
22 | public EdgeMode edgeMode;
23 | public bool canBeDeleted;
24 | public bool canBeReordered;
25 | public float curveModifier;
26 | public float height;
27 | public float width;
28 | public float x;
29 | public float y;
30 | public string id;
31 | public string nodeId;
32 | public string portName;
33 |
34 | #endregion
35 |
36 | #region public Methods
37 |
38 | public void Init(NodeBase node, string portName, PortDirection direction, EdgeMode edgeMode, EdgeType edgeType, bool canBeDeleted, bool canBeReordered)
39 | {
40 | GenerateNewId();
41 | nodeId = node.id;
42 | this.portName = portName;
43 | this.direction = direction;
44 | this.edgeMode = edgeMode;
45 | this.edgeType = edgeType;
46 | this.canBeDeleted = canBeDeleted;
47 | this.canBeReordered = canBeReordered;
48 | edges = new List();
49 | curveModifier = 0;
50 | }
51 |
52 | public List GetEdgePoints()
53 | {
54 | if (edgePoints == null)
55 | {
56 | if (edgeType == EdgeType.Both)
57 | {
58 | edgePoints = GetLeftAndRightEdgePoints();
59 | }
60 | else if (edgeType == EdgeType.Left)
61 | {
62 | edgePoints = new List();
63 | edgePoints.Add(GetLeftEdgePointPosition());
64 | }
65 | else if (edgeType == EdgeType.Right)
66 | {
67 | edgePoints = new List();
68 | edgePoints.Add(GetRightEdgePointPosition());
69 | }
70 | }
71 |
72 | return edgePoints;
73 | }
74 | /// Returns TRUE if this port has at least one edge (it checks the Connections count)
75 | public bool IsConnected() => edges.Count > 0;
76 |
77 | /// Returns TRUE if this is an Input port
78 | public bool IsInput() => direction == PortDirection.Input;
79 |
80 | /// Returns TRUE if this is an Output port
81 | public bool IsOutput() => direction == PortDirection.Output;
82 |
83 | /// Returns TRUE if this port can establish only ONE edge
84 | public bool OverrideConnection() => edgeMode == EdgeMode.Override;
85 | /// Returns TRUE if this port can establish multiple edges
86 | public bool GetAcceptsMultipleConnections() => edgeMode == EdgeMode.Multiple;
87 | /// [Editor Only] Returns the height of this port
88 | public float GetHeight()
89 | {
90 | return height;
91 | }
92 | /// [Editor Only] Returns the position of this port
93 | public Vector2 GetPosition()
94 | {
95 | return new Vector2(x, y);
96 | }
97 | /// [Editor Only] Returns the Rect of this port
98 | public Rect GetRect()
99 | {
100 | return new Rect(x, y, width, height);
101 | }
102 | /// [Editor Only] Returns the size of this port (x is width, y is height)
103 | public Vector2 GetSize()
104 | {
105 | return new Vector2(width, height);
106 | }
107 | /// [Editor Only] Returns the width of this port
108 | public float GetWidth()
109 | {
110 | return width;
111 | }
112 | /// [Editor Only] Returns the x coordinate of this port
113 | public float GetX()
114 | {
115 | return x;
116 | }
117 | /// [Editor Only] Returns the y coordinate of this port
118 | public float GetY()
119 | {
120 | return y;
121 | }
122 | ///
123 | /// Returns the edge mode this port has (Multiple/Override)
124 | ///
125 | /// The edge mode determines if this port can establish multiple edge or just one
126 | ///
127 | public EdgeMode GetConnectionMode()
128 | {
129 | return edgeMode;
130 | }
131 | /// Returns the direction this port has (Input/Output)
132 | public PortDirection GetDirection()
133 | {
134 | return direction;
135 | }
136 |
137 | /// Returns a IEnumerable of all the Edge ids of this Port
138 | public IEnumerable GetEdgeIds()
139 | {
140 | return edges.ToList();
141 | }
142 |
143 | /// [Editor Only] Sets the height of this port's Rect
144 | /// The new height value
145 | public void SetHeight(float value)
146 | {
147 | height = value;
148 | }
149 | /// Set the name for this port
150 | /// The new port name value
151 | public void SetName(string value)
152 | {
153 | portName = value;
154 | }
155 | /// [Editor Only] Sets the position of this port's Rect
156 | /// The new position value
157 | public void SetPosition(Vector2 position)
158 | {
159 | x = position.x;
160 | y = position.y;
161 | }
162 | /// [Editor Only] Sets the position of this port's Rect
163 | /// The new x coordinate value
164 | /// The new y coordinate value
165 | public void SetPosition(float x, float y)
166 | {
167 | this.x = x;
168 | this.y = y;
169 | }
170 | /// [Editor Only] Sets the Rect value for this port
171 | /// The new rect values
172 | public void SetRect(Rect rect)
173 | {
174 | x = rect.x;
175 | y = rect.y;
176 | width = rect.width;
177 | height = rect.height;
178 | RefreshPoints();
179 | }
180 | /// [Editor Only] Sets the Rect values for this port
181 | /// The new position value
182 | /// The new size value
183 | public void SetRect(Vector2 position, Vector2 size)
184 | {
185 | x = position.x;
186 | y = position.y;
187 | width = size.x;
188 | height = size.y;
189 | RefreshPoints();
190 | }
191 | /// [Editor Only] Sets the Rect values for this port
192 | /// The new x coordinate value
193 | /// The new y coordinate value
194 | /// The new width value
195 | /// The new height value
196 | public void SetRect(float x, float y, float width, float height)
197 | {
198 | this.x = x;
199 | this.x = y;
200 | this.width = width;
201 | this.height = height;
202 | RefreshPoints();
203 | }
204 | /// [Editor Only] Sets the size of this port's Rect
205 | /// The new port size (x is width, y is height)
206 | public void SetSize(Vector2 size)
207 | {
208 | width = size.x;
209 | height = size.y;
210 | RefreshPoints();
211 | }
212 | /// [Editor Only] Sets the size of this port's Rect
213 | /// The new width value
214 | /// The new height value
215 | public void SetSize(float width, float height)
216 | {
217 | this.width = width;
218 | this.height = height;
219 | RefreshPoints();
220 | }
221 | /// [Editor Only] Sets the width of this port's Rect
222 | /// The new width value
223 | public void SetWidth(float value)
224 | {
225 | width = value;
226 | RefreshPoints();
227 | }
228 | /// [Editor Only] Sets the x coordinate of this port's Rect
229 | /// The new x value
230 | public void SetX(float value)
231 | {
232 | x = value;
233 | }
234 | /// [Editor Only] Sets the y coordinate of this port's Rect
235 | /// The new y value
236 | public void SetY(float value)
237 | {
238 | y = value;
239 | }
240 | /// [Editor Only] Updates the port hover Rect. This is the 'selection' box that appears when the mouse is over the port
241 | public void UpdateHoverRect()
242 | {
243 | hoverRect = new Rect(GetRect().x + 6,
244 | GetRect().y + 2,
245 | GetRect().width - 12,
246 | GetRect().height - 3);
247 | }
248 | /// Returns TRUE if this port can connect to another port
249 | /// The other port we are trying to determine if this port can connect to
250 | /// If true, this check will not make sure that the sockets valueTypes match
251 | public virtual bool CanConnect(Port other,GraphBase graphBase, bool ignoreValueType = false)
252 | {
253 | if (other == null) return false; //check that the other port is not null
254 | if (IsConnectedToPort(other.id,graphBase))return false; //check that this port is not already connected to the other port
255 | if (id == other.id) return false; //make sure we're not trying to connect the same port
256 | if (nodeId == other.nodeId) return false; //check that we are not connecting sockets on the same baseNode
257 | if (IsInput() && other.IsInput()) return false; //check that the sockets are not both input sockets
258 | if (IsOutput() && other.IsOutput()) return false; //check that the sockets are not both output sockets
259 | if (!ignoreValueType)
260 | {
261 | var attributes1 = GetType().GetCustomAttributes(typeof(PortGroupAttribute), true);
262 | var attributes2 = other.GetType().GetCustomAttributes(typeof(PortGroupAttribute), true);
263 | if (attributes1.Length > 0 || attributes2.Length > 0)
264 | {
265 | HashSet temp = new HashSet();
266 | foreach (PortGroupAttribute item in attributes1)
267 | {
268 | temp.Add(item.Group);
269 | }
270 | foreach (PortGroupAttribute item in attributes2)
271 | {
272 | if (temp.Contains(item.Group))
273 | {
274 | return true;
275 | }
276 | }
277 | return false;
278 | }
279 | }
280 | return true;
281 | }
282 |
283 | /// Removes a edge with the given edge id from this Port
284 | /// The edge id we want removed from this Port
285 | public void RemoveEdge(string edgeId)
286 | {
287 | //if the connections list does not contain this connection id -> return;
288 | if (!ContainsEdge(edgeId)) return;
289 | //iterate through all the connections list
290 | for (var i = edges.Count - 1; i >= 0; i--)
291 | {
292 | //if a connection has the given connection id -> remove connection
293 | if (edges[i] == edgeId)
294 | {
295 | edges.RemoveAt(i);
296 | }
297 | }
298 | }
299 |
300 | /// Returns TRUE if this port contains a edge with the given edge id
301 | /// The edge id to search for
302 | public bool ContainsEdge(string edgeId)
303 | {
304 | return edges.Any(edge => edge == edgeId);
305 | }
306 |
307 | /// [Editor Only] Returns the closest own Edge point to the closest Edge point on the other Port
308 | public Vector2 GetClosestEdgePointToPort(Port other)
309 | {
310 | if (edgeType == EdgeType.Left)
311 | {
312 | return GetLeftEdgePointPosition();
313 | }
314 | if (edgeType == EdgeType.Right)
315 | {
316 | return GetRightEdgePointPosition();
317 | }
318 |
319 | var edgePoints = GetLeftAndRightEdgePoints();
320 | //arbitrary value that will surely be greater than any other possible distance
321 | float minDistance = 100000;
322 | //set the closest point as the first connection point
323 | var closestPoint = edgePoints[0];
324 | //iterate through this port's own connection points list
325 | foreach (var ownPoint in edgePoints)
326 | {
327 | foreach (var distance in other.GetEdgePoints().Select(otherPoint => Vector2.Distance(ownPoint, otherPoint)).Where(distance => !(distance > minDistance)))
328 | {
329 | //the distance is smaller than the current minimum distance -> update the selected connection point
330 | closestPoint =ownPoint;
331 | //update the current minimum distance
332 | minDistance = distance;
333 | }
334 | }
335 | return closestPoint; //return the closest Edge point
336 | }
337 |
338 | /// Remove ALL the Edges this Port has, by clearing the Edges list
339 | public void Disconnect()
340 | {
341 | edges.Clear();
342 | }
343 |
344 | /// Disconnect this port from the given node id
345 | /// The node id we want this port to disconnect from
346 | public void DisconnectFromNode(string nodeId, GraphBase graphBase)
347 | {
348 | if (!IsConnected()) return;
349 | for (int i = edges.Count - 1; i >= 0; i--)
350 | {
351 | var edge = graphBase.GetEdge(edges[i]);
352 | if (IsInput() && edge.outputNodeId == nodeId) edges.RemoveAt(i);
353 | if (IsOutput() && edge.inputNodeId == nodeId) edges.RemoveAt(i);
354 | }
355 | }
356 |
357 | #endregion
358 |
359 | #region private Methods
360 |
361 | /// Returns TRUE if this port is connected to the given port id
362 | /// The port id to search for and determine if this port is connected to or not
363 | private bool IsConnectedToPort(string portId, GraphBase graphBase)
364 | {
365 | foreach (var edgeId in edges) //iterate through all the connections list
366 | {
367 | var edge = graphBase.GetEdge(edgeId);
368 | if (IsInput() && edge.outputPortId == portId)return true; //if this is an input port -> look for the port id at the output port of the connection
369 | if (IsOutput() && edge.inputPortId == portId)return true; //if this is an output port -> look for the port id at the input port of the connection
370 | }
371 | return false;
372 | }
373 |
374 | /// Generates a new unique port id for this port and returns the newly generated id value
375 | private string GenerateNewId()
376 | {
377 | id = Guid.NewGuid().ToString();
378 | return id;
379 | }
380 |
381 | /// Returns a list of two Edge points positions to the left of and the right of the Port
382 | private List GetLeftAndRightEdgePoints()
383 | {
384 | return new List { GetLeftEdgePointPosition(), GetRightEdgePointPosition() };
385 | }
386 |
387 | /// Returns the default left edge point position for a Port
388 | private Vector2 GetLeftEdgePointPosition()
389 | {
390 | return new Vector2(-2f, 24f / 2 - 16f / 2);
391 | }
392 |
393 | /// Returns the default right edge point position for a Port
394 | private Vector2 GetRightEdgePointPosition()
395 | {
396 | return new Vector2(GetWidth() + 2f - 16f, 24f / 2 - 16f / 2);
397 | }
398 |
399 | private void RefreshPoints()
400 | {
401 | if (edgeType == EdgeType.Right || edgeType == EdgeType.Both)
402 | {
403 | edgePoints = null;
404 | }
405 | }
406 |
407 | #endregion
408 | }
409 | public enum PortDirection
410 | {
411 | ///
412 | /// An input Socket can only connect to an output Socket
413 | ///
414 | Input,
415 |
416 | ///
417 | /// An output Socket can only connect to an input Socket
418 | ///
419 | Output
420 | }
421 | public enum EdgeMode
422 | {
423 | ///
424 | /// Socket can have only one Connection at a time (overriding any existing edge upon establishing a new edge)
425 | ///
426 | Override,
427 |
428 | ///
429 | /// Socket can have multiple edges
430 | ///
431 | Multiple
432 | }
433 |
434 | public enum EdgeType
435 | {
436 | Both,
437 | Left,
438 | Right,
439 | }
440 | }
--------------------------------------------------------------------------------
/Port.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f45fe4a9053241e882561ab9bdb8808d
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/Style.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: de0c4ae6c7c56f14ebe9a93cff8c0e6b
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Style/DarkSkin.guiskin.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a18d7875d2eeed046a71750d5f627c02
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 0
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Style/UIColor.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!114 &11400000
4 | MonoBehaviour:
5 | m_ObjectHideFlags: 0
6 | m_CorrespondingSourceObject: {fileID: 0}
7 | m_PrefabInstance: {fileID: 0}
8 | m_PrefabAsset: {fileID: 0}
9 | m_GameObject: {fileID: 0}
10 | m_Enabled: 1
11 | m_EditorHideFlags: 0
12 | m_Script: {fileID: 11500000, guid: 8d62153adfe14b47838b7e9be2b9ab2b, type: 3}
13 | m_Name: UIColor
14 | m_EditorClassIdentifier:
15 | nodeGlowColor: {r: 1, g: 1, b: 1, a: 1}
16 | nodeHeaderAndFooterBackgroundColor: {r: 0.745283, g: 0.745283, b: 0.745283, a: 1}
17 | nodeRootHeaderAndFooterBackgroundColor: {r: 0.3207547, g: 0.3207547, b: 0.3207547, a: 1}
18 | nodeBodyColor: {r: 0, g: 0.6603774, b: 0.6130958, a: 1}
19 | nodeOutlineColor: {r: 1, g: 0, b: 0.51282024, a: 1}
20 | nodePlayingOutlineColor: {r: 0, g: 1, b: 0.017543793, a: 1}
21 | nodeHeaderIconColor: {r: 1, g: 1, b: 1, a: 1}
22 | nodeDividerColor: {r: 0, g: 1, b: 0.3212328, a: 1}
23 | portInputColor: {r: 0, g: 1, b: 0.025779486, a: 1}
24 | portOutputColor: {r: 1, g: 0.058691405, b: 0, a: 1}
25 | edgeInputColor: {r: 0.25207186, g: 0, b: 1, a: 1}
26 | edgeOutputColor: {r: 1, g: 0, b: 0, a: 1}
27 | edgeNormalColor: {r: 1, g: 1, b: 1, a: 1}
28 |
--------------------------------------------------------------------------------
/Style/UIColor.asset.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: db078a4c96d3fe54dbe436c8e7963fac
3 | NativeFormatImporter:
4 | externalObjects: {}
5 | mainObjectFileID: 0
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Texture.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2516abda0ad71bf4ab4a561090c12637
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Texture/BackgroundRoundDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/BackgroundRoundDark.png
--------------------------------------------------------------------------------
/Texture/BackgroundRoundDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d0c7f8a268cfaeb45a576684ce3edaa4
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/BackgroundSquareDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/BackgroundSquareDark.png
--------------------------------------------------------------------------------
/Texture/BackgroundSquareDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b2a41e5dfd241744788de35afe042c13
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/ConnectionPointMinusNormalDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/ConnectionPointMinusNormalDark.png
--------------------------------------------------------------------------------
/Texture/ConnectionPointMinusNormalDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ce385a70de9ce4d46acde9230be7aefb
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/ConnectionPointMultipleConnectedNormalDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/ConnectionPointMultipleConnectedNormalDark.png
--------------------------------------------------------------------------------
/Texture/ConnectionPointMultipleConnectedNormalDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 958dcd11d63b3e9499a5710a5d79b3d2
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/ConnectionPointMultipleEmptyNormalDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/ConnectionPointMultipleEmptyNormalDark.png
--------------------------------------------------------------------------------
/Texture/ConnectionPointMultipleEmptyNormalDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6432d91a530b9fc44bb5efe4a9b9d677
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/ConnectionPointOverrideConnectedNormalDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/ConnectionPointOverrideConnectedNormalDark.png
--------------------------------------------------------------------------------
/Texture/ConnectionPointOverrideConnectedNormalDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 23d40362666faa3429adcc2f4da7352a
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/ConnectionPointOverrideEmptyNormalDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/ConnectionPointOverrideEmptyNormalDark.png
--------------------------------------------------------------------------------
/Texture/ConnectionPointOverrideEmptyNormalDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a86dcb6588d244c45a9d133ed3aff02f
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeBodyDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeBodyDark.png
--------------------------------------------------------------------------------
/Texture/NodeBodyDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 02094ede464c3cb4ba9fdcee94d3ffd6
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeDotDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeDotDark.png
--------------------------------------------------------------------------------
/Texture/NodeDotDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a2c2695b73307594b8d3238ae8f22b19
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeFooterDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeFooterDark.png
--------------------------------------------------------------------------------
/Texture/NodeFooterDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b20417cd8c9477248949ac0e1b247203
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeGlowDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeGlowDark.png
--------------------------------------------------------------------------------
/Texture/NodeGlowDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fde6953e0ea02fc43a180aea33806755
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeHeaderDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeHeaderDark.png
--------------------------------------------------------------------------------
/Texture/NodeHeaderDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: a789fa4c8d4b1d04ca1bb22147703bda
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/Texture/NodeOutlineDark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LiFang7/DaGenGraph/ee17db390decfb8b5769e8b80f034d9f97871247/Texture/NodeOutlineDark.png
--------------------------------------------------------------------------------
/Texture/NodeOutlineDark.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: fe3572699d3d15f40b25795ea68a0cfe
3 | TextureImporter:
4 | internalIDToNameTable: []
5 | externalObjects: {}
6 | serializedVersion: 11
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | streamingMipmaps: 0
25 | streamingMipmapsPriority: 0
26 | grayScaleToAlpha: 0
27 | generateCubemap: 6
28 | cubemapConvolution: 0
29 | seamlessCubemap: 0
30 | textureFormat: 1
31 | maxTextureSize: 2048
32 | textureSettings:
33 | serializedVersion: 2
34 | filterMode: -1
35 | aniso: 1
36 | mipBias: -100
37 | wrapU: 1
38 | wrapV: 1
39 | wrapW: -1
40 | nPOTScale: 0
41 | lightmap: 0
42 | compressionQuality: 50
43 | spriteMode: 0
44 | spriteExtrude: 1
45 | spriteMeshType: 1
46 | alignment: 0
47 | spritePivot: {x: 0.5, y: 0.5}
48 | spritePixelsToUnits: 100
49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
50 | spriteGenerateFallbackPhysicsShape: 1
51 | alphaUsage: 1
52 | alphaIsTransparency: 1
53 | spriteTessellationDetail: -1
54 | textureType: 2
55 | textureShape: 1
56 | singleChannelComponent: 0
57 | maxTextureSizeSet: 0
58 | compressionQualitySet: 0
59 | textureFormatSet: 0
60 | applyGammaDecoding: 0
61 | platformSettings:
62 | - serializedVersion: 3
63 | buildTarget: DefaultTexturePlatform
64 | maxTextureSize: 2048
65 | resizeAlgorithm: 0
66 | textureFormat: -1
67 | textureCompression: 1
68 | compressionQuality: 50
69 | crunchedCompression: 0
70 | allowsAlphaSplitting: 0
71 | overridden: 0
72 | androidETC2FallbackOverride: 0
73 | forceMaximumCompressionQuality_BC6H_BC7: 0
74 | - serializedVersion: 3
75 | buildTarget: Standalone
76 | maxTextureSize: 2048
77 | resizeAlgorithm: 0
78 | textureFormat: -1
79 | textureCompression: 1
80 | compressionQuality: 50
81 | crunchedCompression: 0
82 | allowsAlphaSplitting: 0
83 | overridden: 0
84 | androidETC2FallbackOverride: 0
85 | forceMaximumCompressionQuality_BC6H_BC7: 0
86 | - serializedVersion: 3
87 | buildTarget: iPhone
88 | maxTextureSize: 2048
89 | resizeAlgorithm: 0
90 | textureFormat: -1
91 | textureCompression: 1
92 | compressionQuality: 50
93 | crunchedCompression: 0
94 | allowsAlphaSplitting: 0
95 | overridden: 0
96 | androidETC2FallbackOverride: 0
97 | forceMaximumCompressionQuality_BC6H_BC7: 0
98 | - serializedVersion: 3
99 | buildTarget: Android
100 | maxTextureSize: 2048
101 | resizeAlgorithm: 0
102 | textureFormat: -1
103 | textureCompression: 1
104 | compressionQuality: 50
105 | crunchedCompression: 0
106 | allowsAlphaSplitting: 0
107 | overridden: 0
108 | androidETC2FallbackOverride: 0
109 | forceMaximumCompressionQuality_BC6H_BC7: 0
110 | spriteSheet:
111 | serializedVersion: 2
112 | sprites: []
113 | outline: []
114 | physicsShape: []
115 | bones: []
116 | spriteID:
117 | internalID: 0
118 | vertices: []
119 | indices:
120 | edges: []
121 | weights: []
122 | secondaryTextures: []
123 | spritePackingTag:
124 | pSDRemoveMatte: 0
125 | pSDShowRemoveMatteOption: 0
126 | userData:
127 | assetBundleName:
128 | assetBundleVariant:
129 |
--------------------------------------------------------------------------------
/TypeHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | #if ODIN_INSPECTOR
5 | using Sirenix.OdinInspector;
6 | #endif
7 | namespace DaGenGraph
8 | {
9 | public static class TypeHelper
10 | {
11 | ///
12 | /// Cached Models
13 | ///
14 | private static readonly Dictionary TypeCodes = new Dictionary(30)
15 | {
16 | {typeof(byte).FullName, typeof(byte)},
17 | {typeof(sbyte).FullName, typeof(sbyte)},
18 | {typeof(short).FullName, typeof(short)},
19 | {typeof(ushort).FullName, typeof(ushort)},
20 | {typeof(int).FullName, typeof(int)},
21 | {typeof(uint).FullName, typeof(uint)},
22 | {typeof(long).FullName, typeof(long)},
23 | {typeof(ulong).FullName, typeof(ulong)},
24 | {typeof(float).FullName, typeof(float)},
25 | {typeof(double).FullName, typeof(double)},
26 | {typeof(decimal).FullName, typeof(decimal)},
27 | {typeof(char).FullName, typeof(char)},
28 | {typeof(bool).FullName, typeof(bool)},
29 | {typeof(string).FullName, typeof(string)},
30 | {typeof(DateTime).FullName, typeof(DateTime)}
31 | };
32 | private static Dictionary> subTypes = new Dictionary>();
33 | private static Dictionary fullNames = new Dictionary();
34 | private static Dictionary tempType = new Dictionary();
35 | public static List GetSubClassList(FieldInfo fieldInfo, Type type, out string[] names)
36 | {
37 | if (type == null)
38 | {
39 | names = null;
40 | return null;
41 | }
42 | fullNames.TryGetValue(type, out names);
43 | if (subTypes.TryGetValue(type, out var res)) return res;
44 | res = new List();
45 | if (!type.IsAbstract)
46 | {
47 | res.Add(type);
48 | }
49 | var assemblies = AppDomain.CurrentDomain.GetAssemblies();
50 | for (int i = 0; i < assemblies.Length; i++)
51 | {
52 | var types = assemblies[i].GetTypes();
53 | foreach (var item in types)
54 | {
55 | if (item.IsClass && !item.IsAbstract && type.IsAssignableFrom(item))
56 | {
57 | res.Add(item);
58 | }
59 | }
60 | }
61 |
62 | names = new string[res.Count];
63 | for (int i = 0; i < names.Length; i++)
64 | {
65 | if (res[i].GetCustomAttribute(typeof(LabelTextAttribute)) is LabelTextAttribute labelTextAttribute)
66 | {
67 | names[i] = labelTextAttribute.Text;
68 | }
69 | else
70 | {
71 | names[i] = res[i].FullName;
72 | }
73 | }
74 | fullNames.Add(type, names);
75 | subTypes.Add(type,res);
76 | return res;
77 | }
78 | public static Type FindType(string name)
79 | {
80 | if(TypeCodes.TryGetValue(name,out var type))
81 | {
82 | return type;
83 | }
84 | if (tempType.TryGetValue(name, out type))
85 | {
86 | return type;
87 | }
88 | var assemblies = AppDomain.CurrentDomain.GetAssemblies();
89 | for (int i = 0; i < assemblies.Length; i++)
90 | {
91 | var types = assemblies[i].GetTypes();
92 | foreach (var item in types)
93 | {
94 | if (item.IsClass)
95 | {
96 | if (item.FullName == name)
97 | {
98 | tempType.Add(name,item);
99 | return item;
100 | }
101 | if (item.Name == name)
102 | {
103 | type = item;
104 | }
105 | }
106 | }
107 | }
108 |
109 | if (type != null)
110 | {
111 | tempType.Add(name,type);
112 | }
113 | return type;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/TypeHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5b9d16a7d9fb4a458493dd1721764cec
3 | timeCreated: 1737198597
--------------------------------------------------------------------------------
/ValueDropdownItem.cs:
--------------------------------------------------------------------------------
1 | #if !ODIN_INSPECTOR
2 | namespace DaGenGraph
3 | {
4 | ///
5 | ///
6 | ///
7 | public interface IValueDropdownItem
8 | {
9 | /// Gets the label for the dropdown item.
10 | /// The label text for the item.
11 | string GetText();
12 |
13 | /// Gets the value of the dropdown item.
14 | /// The value for the item.
15 | object GetValue();
16 | }
17 | public struct ValueDropdownItem: IValueDropdownItem
18 | {
19 | /// The name of the item.
20 | public string Text;
21 | /// The value of the item.
22 | public object Value;
23 |
24 | ///
25 | /// Initializes a new instance of the class.
26 | ///
27 | /// The text to display for the dropdown item.
28 | /// The value for the dropdown item.
29 | public ValueDropdownItem(string text, object value)
30 | {
31 | this.Text = text;
32 | this.Value = value;
33 | }
34 |
35 | /// The name of this item.
36 | public override string ToString() => this.Text ?? this.Value?.ToString() ?? "";
37 |
38 | /// Gets the text.
39 | string IValueDropdownItem.GetText() => this.Text;
40 |
41 | /// Gets the value.
42 | object IValueDropdownItem.GetValue() => this.Value;
43 | }
44 | }
45 |
46 | #endif
--------------------------------------------------------------------------------
/ValueDropdownItem.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 39bb0b44b3774837b0f208c239946f0f
3 | timeCreated: 1737617720
--------------------------------------------------------------------------------
/VirtualPoint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace DaGenGraph
5 | {
6 | public class VirtualPoint
7 | {
8 | /// The Node this connection point belongs to
9 | public NodeBase node;
10 |
11 | /// The Port this connection point belongs top
12 | public Port port;
13 |
14 | /// The Point position in Node Space (not World Space)
15 | public Vector2 pointPosition;
16 |
17 | /// The Point position in Port Space (not Node or World Space). This is the value found in the Port.ConnectionPoints list
18 | public Vector2 localPointPosition;
19 |
20 | ///
21 | ///The Rect of this connection point in World Space.
22 | ///
23 | ///Note that CalculateRect() needs to be called before using this rect.
24 | ///
25 | ///CalculateRect() is done automatically when building the Database or when the Database is updated.
26 | ///
27 | ///The Database update is executed automatically when (Event.current.type == EventType.MouseDrag) is performed on the parent Node.
28 | ///
29 | public Rect rect;
30 |
31 | ///
32 | /// Remembers if this point is occupied or not.
33 | ///
34 | /// A point is deemed occupied when in the ConnectionsDatabase there is at least one VirtualConnection that uses this PointPosition (for the parent Port, for the parent Node)
35 | ///
36 | public bool isConnected;
37 |
38 |
39 | /// Construct a Virtual Point
40 | /// The node this virtual point belongs to
41 | ///
42 | /// The position - in node space - this point is located at
43 | /// The position - in socket space - this point is located at
44 | public VirtualPoint(NodeBase node, Port port, Vector2 pointPosition, Vector2 localPointPosition)
45 | {
46 | this.node = node;
47 | this.port = port;
48 | this.pointPosition = pointPosition;
49 | this.localPointPosition = localPointPosition;
50 | isConnected = false;
51 | CalculateRect(); //calculate the Rect by converting the position from NodeSpace to WorldSpace and setting up correct values
52 | }
53 |
54 | ///
55 | /// Calculate this virtual point's rect by converting it's point position node space position into a world position.
56 | ///
57 | /// It uses the default connector width and height (found in Settings.GUI) in order to create the rect.
58 | ///
59 | public void CalculateRect()
60 | {
61 | rect = new Rect();
62 | if (node == null)
63 | {
64 | Debug.Log("Cannot calculate the connection point Rect because the parent Node is null.");
65 | return;
66 | }
67 |
68 | if (port == null)
69 | {
70 | Debug.Log("Cannot calculate the connection point Rect because the parent Port is null.");
71 | return;
72 | }
73 |
74 | var worldRect = new Rect(node.GetX(),
75 | node.GetY() + port.GetY(),
76 | port.GetWidth(),
77 | port.GetHeight());
78 |
79 | rect = new Rect(worldRect.x + pointPosition.x + m_ConnectionPointWidth / 2,
80 | worldRect.y + pointPosition.y + m_ConnectionPointWidth / 2,
81 | m_ConnectionPointWidth,
82 | m_ConnectionPointHeight);
83 | }
84 |
85 | private float m_ConnectionPointWidth = 16f;
86 | private float m_ConnectionPointHeight = 16f;
87 | }
88 | }
--------------------------------------------------------------------------------
/VirtualPoint.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 481da3fe5c4240889229c5374b6d25d4
3 | MonoImporter:
4 | externalObjects: {}
5 | serializedVersion: 2
6 | defaultReferences: []
7 | executionOrder: 0
8 | icon: {instanceID: 0}
9 | userData:
10 | assetBundleName:
11 | assetBundleVariant:
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "com.lifang.dagen",
3 | "displayName": "DaGenGraph",
4 | "version": "1.1.0",
5 | "unity": "2020.4",
6 | "description": " used by lifang",
7 | "keywords": [
8 | "tools",
9 | "unity"
10 | ],
11 | "category": "LiFang",
12 | "dependencies": {
13 |
14 | },
15 | "type": "tool"
16 | }
17 |
--------------------------------------------------------------------------------
/package.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 779bfd226d94102479466849603a8d9d
3 | PackageManifestImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------