mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-21 01:36:03 +08:00
Merge branch 'master' of https://github.com/Siccity/xNode into examples
This commit is contained in:
commit
becd710fe0
23
CONTRIBUTING.md
Normal file
23
CONTRIBUTING.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Contributing to xNode
|
||||||
|
💙Thank you for taking the time to contribute💙
|
||||||
|
|
||||||
|
If you haven't already, join our [Discord channel](https://discord.gg/qgPrHv4)!
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
Try to keep your pull requests relevant, neat, and manageable. If you are adding multiple features, try splitting them into separate commits.
|
||||||
|
* Avoid including irellevant whitespace or formatting changes.
|
||||||
|
* Comment your code.
|
||||||
|
* Spell check your code / comments
|
||||||
|
|
||||||
|
## New features
|
||||||
|
xNode aims to be simple and extendible, not trying to fix all of Unity's shortcomings.
|
||||||
|
|
||||||
|
If your feature aims to cover something not related to editing nodes, it generally won't be accepted. If in doubt, ask on the Discord channel.
|
||||||
|
|
||||||
|
## Coding conventions
|
||||||
|
Skim through the code and you'll get the hang of it quickly.
|
||||||
|
* Methods, Types and properties PascalCase
|
||||||
|
* Variables camelCase
|
||||||
|
* Public methods XML commented
|
||||||
|
* Open braces on same line as condition
|
||||||
|
* 4 spaces for indentation.
|
||||||
@ -3,7 +3,7 @@
|
|||||||
[](https://raw.githubusercontent.com/Siccity/xNode/master/LICENSE.md)
|
[](https://raw.githubusercontent.com/Siccity/xNode/master/LICENSE.md)
|
||||||
[](https://github.com/Siccity/xNode/wiki)
|
[](https://github.com/Siccity/xNode/wiki)
|
||||||
|
|
||||||
[Go to Downloads](https://github.com/Siccity/xNode/releases) / [Go to Asset Store](http://u3d.as/108S)
|
[Downloads](https://github.com/Siccity/xNode/releases) / [Asset Store](http://u3d.as/108S) / [Documentation](https://github.com/Siccity/xNode/wiki)
|
||||||
|
|
||||||
### xNode
|
### xNode
|
||||||
Thinking of developing a node-based plugin? Then this is for you. You can download it as an archive and unpack to a new unity project, or connect it as git submodule.
|
Thinking of developing a node-based plugin? Then this is for you. You can download it as an archive and unpack to a new unity project, or connect it as git submodule.
|
||||||
@ -20,7 +20,6 @@ With a minimal footprint, it is ideal as a base for custom state machines, dialo
|
|||||||
* No runtime reflection (unless you need to edit/build node graphs at runtime. In this case, all reflection is cached.)
|
* No runtime reflection (unless you need to edit/build node graphs at runtime. In this case, all reflection is cached.)
|
||||||
* Does not rely on any 3rd party plugins
|
* Does not rely on any 3rd party plugins
|
||||||
* Custom node inspector code is very similar to regular custom inspector code
|
* Custom node inspector code is very similar to regular custom inspector code
|
||||||
* For a full list of features, see [this page](https://github.com/Siccity/xNode/wiki/Full-features-list)
|
|
||||||
|
|
||||||
### Node example:
|
### Node example:
|
||||||
```csharp
|
```csharp
|
||||||
|
|||||||
@ -140,8 +140,12 @@ namespace XNodeEditor {
|
|||||||
} else if (!IsHoveringNode) {
|
} else if (!IsHoveringNode) {
|
||||||
// If click outside node, release field focus
|
// If click outside node, release field focus
|
||||||
if (!isPanning) {
|
if (!isPanning) {
|
||||||
|
// I've got no idea which of these do what, so we'll just reset all of it.
|
||||||
GUIUtility.hotControl = 0;
|
GUIUtility.hotControl = 0;
|
||||||
GUIUtility.keyboardControl = 0;
|
GUIUtility.keyboardControl = 0;
|
||||||
|
EditorGUIUtility.editingTextField = false;
|
||||||
|
EditorGUIUtility.keyboardControl = 0;
|
||||||
|
EditorGUIUtility.hotControl = 0;
|
||||||
}
|
}
|
||||||
AssetDatabase.SaveAssets();
|
AssetDatabase.SaveAssets();
|
||||||
}
|
}
|
||||||
@ -166,8 +170,12 @@ namespace XNodeEditor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventType.KeyDown:
|
case EventType.KeyDown:
|
||||||
if (e.keyCode == KeyCode.Delete) RemoveSelectedNodes();
|
if (EditorGUIUtility.editingTextField) break;
|
||||||
else if (e.keyCode == KeyCode.D && e.control) DublicateSelectedNodes();
|
else if (e.keyCode == KeyCode.F) Home();
|
||||||
|
break;
|
||||||
|
case EventType.ValidateCommand:
|
||||||
|
if (e.commandName == "SoftDelete") RemoveSelectedNodes();
|
||||||
|
else if (e.commandName == "Duplicate") DublicateSelectedNodes();
|
||||||
Repaint();
|
Repaint();
|
||||||
break;
|
break;
|
||||||
case EventType.Ignore:
|
case EventType.Ignore:
|
||||||
|
|||||||
@ -10,7 +10,6 @@ namespace XNodeEditor.Internal {
|
|||||||
public class NodeEditorBase<T, A, K> where A : Attribute, NodeEditorBase<T, A, K>.INodeEditorAttrib where T : NodeEditorBase<T,A,K> where K : ScriptableObject {
|
public class NodeEditorBase<T, A, K> where A : Attribute, NodeEditorBase<T, A, K>.INodeEditorAttrib where T : NodeEditorBase<T,A,K> where K : ScriptableObject {
|
||||||
/// <summary> Custom editors defined with [CustomNodeEditor] </summary>
|
/// <summary> Custom editors defined with [CustomNodeEditor] </summary>
|
||||||
private static Dictionary<Type, T> editors;
|
private static Dictionary<Type, T> editors;
|
||||||
private static Dictionary<ScriptableObject, SerializedObject> serializeds;
|
|
||||||
public K target;
|
public K target;
|
||||||
public SerializedObject serializedObject;
|
public SerializedObject serializedObject;
|
||||||
|
|
||||||
@ -19,17 +18,10 @@ namespace XNodeEditor.Internal {
|
|||||||
Type type = target.GetType();
|
Type type = target.GetType();
|
||||||
T editor = GetEditor(type);
|
T editor = GetEditor(type);
|
||||||
editor.target = target;
|
editor.target = target;
|
||||||
editor.serializedObject = GetSerialized(target);
|
editor.serializedObject = new SerializedObject(target);
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SerializedObject GetSerialized(K target) {
|
|
||||||
if (target == null) return null;
|
|
||||||
if (serializeds == null) serializeds = new Dictionary<ScriptableObject, SerializedObject>();
|
|
||||||
if (!serializeds.ContainsKey(target)) serializeds.Add(target, new SerializedObject(target));
|
|
||||||
return serializeds[target];
|
|
||||||
}
|
|
||||||
|
|
||||||
private static T GetEditor(Type type) {
|
private static T GetEditor(Type type) {
|
||||||
if (type == null) return null;
|
if (type == null) return null;
|
||||||
if (editors == null) CacheCustomEditors();
|
if (editors == null) CacheCustomEditors();
|
||||||
|
|||||||
@ -364,8 +364,8 @@ namespace XNodeEditor {
|
|||||||
GUIContent content = new GUIContent();
|
GUIContent content = new GUIContent();
|
||||||
content.text = type.PrettyName();
|
content.text = type.PrettyName();
|
||||||
if (hoveredPort.IsStatic && hoveredPort.IsOutput) {
|
if (hoveredPort.IsStatic && hoveredPort.IsOutput) {
|
||||||
object obj = ObjectFromFieldName(hoveredPort.node, hoveredPort.fieldName);
|
object obj = hoveredPort.node.GetValue(hoveredPort);
|
||||||
if (obj != null) content.text += " = " + obj.ToString();
|
content.text += " = " + (obj != null ? obj.ToString() : "null");
|
||||||
}
|
}
|
||||||
Vector2 size = NodeEditorResources.styles.tooltip.CalcSize(content);
|
Vector2 size = NodeEditorResources.styles.tooltip.CalcSize(content);
|
||||||
Rect rect = new Rect(Event.current.mousePosition - (size), size);
|
Rect rect = new Rect(Event.current.mousePosition - (size), size);
|
||||||
|
|||||||
@ -70,13 +70,13 @@ namespace XNodeEditor {
|
|||||||
switch (showBacking) {
|
switch (showBacking) {
|
||||||
case XNode.Node.ShowBackingValue.Unconnected:
|
case XNode.Node.ShowBackingValue.Unconnected:
|
||||||
// Display a label if port is connected
|
// Display a label if port is connected
|
||||||
if (port.IsConnected) EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30));
|
if (port.IsConnected) EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30));
|
||||||
// Display an editable property field if port is not connected
|
// Display an editable property field if port is not connected
|
||||||
else EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
|
else EditorGUILayout.PropertyField(property, label, includeChildren, GUILayout.MinWidth(30));
|
||||||
break;
|
break;
|
||||||
case XNode.Node.ShowBackingValue.Never:
|
case XNode.Node.ShowBackingValue.Never:
|
||||||
// Display a label
|
// Display a label
|
||||||
EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.styles.outputPort, GUILayout.MinWidth(30));
|
EditorGUILayout.LabelField(label != null ? label : new GUIContent(property.displayName), NodeEditorResources.OutputPort, GUILayout.MinWidth(30));
|
||||||
break;
|
break;
|
||||||
case XNode.Node.ShowBackingValue.Always:
|
case XNode.Node.ShowBackingValue.Always:
|
||||||
// Display an editable property field
|
// Display an editable property field
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using UnityEngine;
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNodeEditor {
|
namespace XNodeEditor {
|
||||||
public static class NodeEditorResources {
|
public static class NodeEditorResources {
|
||||||
@ -15,9 +16,9 @@ namespace XNodeEditor {
|
|||||||
// Styles
|
// Styles
|
||||||
public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } }
|
public static Styles styles { get { return _styles != null ? _styles : _styles = new Styles(); } }
|
||||||
public static Styles _styles = null;
|
public static Styles _styles = null;
|
||||||
|
public static GUIStyle OutputPort { get { return new GUIStyle(EditorStyles.label) { alignment = TextAnchor.UpperRight }; } }
|
||||||
public class Styles {
|
public class Styles {
|
||||||
public GUIStyle inputPort, outputPort, nodeHeader, nodeBody, tooltip, nodeHighlight;
|
public GUIStyle inputPort, nodeHeader, nodeBody, tooltip, nodeHighlight;
|
||||||
|
|
||||||
public Styles() {
|
public Styles() {
|
||||||
GUIStyle baseStyle = new GUIStyle("Label");
|
GUIStyle baseStyle = new GUIStyle("Label");
|
||||||
@ -27,10 +28,6 @@ namespace XNodeEditor {
|
|||||||
inputPort.alignment = TextAnchor.UpperLeft;
|
inputPort.alignment = TextAnchor.UpperLeft;
|
||||||
inputPort.padding.left = 10;
|
inputPort.padding.left = 10;
|
||||||
|
|
||||||
outputPort = new GUIStyle(baseStyle);
|
|
||||||
outputPort.alignment = TextAnchor.UpperRight;
|
|
||||||
outputPort.padding.right = 10;
|
|
||||||
|
|
||||||
nodeHeader = new GUIStyle();
|
nodeHeader = new GUIStyle();
|
||||||
nodeHeader.alignment = TextAnchor.MiddleCenter;
|
nodeHeader.alignment = TextAnchor.MiddleCenter;
|
||||||
nodeHeader.fontStyle = FontStyle.Bold;
|
nodeHeader.fontStyle = FontStyle.Bold;
|
||||||
|
|||||||
@ -1,12 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace XNodeEditor {
|
namespace XNodeEditor {
|
||||||
/// <summary> A set of editor-only utilities and extensions for UnityNodeEditorBase </summary>
|
/// <summary> A set of editor-only utilities and extensions for UnityNodeEditorBase </summary>
|
||||||
public static class NodeEditorUtilities {
|
public static class NodeEditorUtilities {
|
||||||
|
|
||||||
|
/// <summary>C#'s Script Icon [The one MonoBhevaiour Scripts have].</summary>
|
||||||
|
private static Texture2D scriptIcon = (EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D);
|
||||||
|
|
||||||
public static bool GetAttrib<T>(Type classType, out T attribOut) where T : Attribute {
|
public static bool GetAttrib<T>(Type classType, out T attribOut) where T : Attribute {
|
||||||
object[] attribs = classType.GetCustomAttributes(typeof(T), false);
|
object[] attribs = classType.GetCustomAttributes(typeof(T), false);
|
||||||
return GetAttrib(attribs, out attribOut);
|
return GetAttrib(attribs, out attribOut);
|
||||||
@ -85,5 +93,86 @@ namespace XNodeEditor {
|
|||||||
}
|
}
|
||||||
} else return type.ToString();
|
} else return type.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Creates a new C# Class.</summary>
|
||||||
|
[MenuItem("Assets/Create/xNode/Node C# Script", false, 89)]
|
||||||
|
private static void CreateNode() {
|
||||||
|
string[] guids = AssetDatabase.FindAssets("xNode_NodeTemplate.cs");
|
||||||
|
if (guids.Length == 0) {
|
||||||
|
Debug.LogWarning("xNode_NodeTemplate.cs.txt not found in asset database");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||||
|
CreateFromTemplate(
|
||||||
|
"NewNode.cs",
|
||||||
|
path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Creates a new C# Class.</summary>
|
||||||
|
[MenuItem("Assets/Create/xNode/NodeGraph C# Script", false, 89)]
|
||||||
|
private static void CreateGraph() {
|
||||||
|
string[] guids = AssetDatabase.FindAssets("xNode_NodeGraphTemplate.cs");
|
||||||
|
if (guids.Length == 0) {
|
||||||
|
Debug.LogWarning("xNode_NodeGraphTemplate.cs.txt not found in asset database");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||||
|
CreateFromTemplate(
|
||||||
|
"NewNodeGraph.cs",
|
||||||
|
path
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateFromTemplate(string initialName, string templatePath) {
|
||||||
|
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(
|
||||||
|
0,
|
||||||
|
ScriptableObject.CreateInstance<DoCreateCodeFile>(),
|
||||||
|
initialName,
|
||||||
|
scriptIcon,
|
||||||
|
templatePath
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inherits from EndNameAction, must override EndNameAction.Action
|
||||||
|
public class DoCreateCodeFile : UnityEditor.ProjectWindowCallback.EndNameEditAction {
|
||||||
|
public override void Action(int instanceId, string pathName, string resourceFile) {
|
||||||
|
Object o = CreateScript(pathName, resourceFile);
|
||||||
|
ProjectWindowUtil.ShowCreatedAsset(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Creates Script from Template's path.</summary>
|
||||||
|
internal static UnityEngine.Object CreateScript(string pathName, string templatePath) {
|
||||||
|
string className = Path.GetFileNameWithoutExtension(pathName).Replace(" ", string.Empty);
|
||||||
|
string templateText = string.Empty;
|
||||||
|
|
||||||
|
UTF8Encoding encoding = new UTF8Encoding(true, false);
|
||||||
|
|
||||||
|
if (File.Exists(templatePath)) {
|
||||||
|
/// Read procedures.
|
||||||
|
StreamReader reader = new StreamReader(templatePath);
|
||||||
|
templateText = reader.ReadToEnd();
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
|
templateText = templateText.Replace("#SCRIPTNAME#", className);
|
||||||
|
templateText = templateText.Replace("#NOTRIM#", string.Empty);
|
||||||
|
/// You can replace as many tags you make on your templates, just repeat Replace function
|
||||||
|
/// e.g.:
|
||||||
|
/// templateText = templateText.Replace("#NEWTAG#", "MyText");
|
||||||
|
|
||||||
|
/// Write procedures.
|
||||||
|
|
||||||
|
StreamWriter writer = new StreamWriter(Path.GetFullPath(pathName), false, encoding);
|
||||||
|
writer.Write(templateText);
|
||||||
|
writer.Close();
|
||||||
|
|
||||||
|
AssetDatabase.ImportAsset(pathName);
|
||||||
|
return AssetDatabase.LoadAssetAtPath(pathName, typeof(Object));
|
||||||
|
} else {
|
||||||
|
Debug.LogError(string.Format("The template file was not found: {0}", templatePath));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
10
Scripts/Editor/Resources/ScriptTemplates.meta
Normal file
10
Scripts/Editor/Resources/ScriptTemplates.meta
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 86b677955452bb5449f9f4dd47b6ddfe
|
||||||
|
folderAsset: yes
|
||||||
|
timeCreated: 1519049391
|
||||||
|
licenseType: Free
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using XNode;
|
||||||
|
|
||||||
|
[CreateAssetMenu]
|
||||||
|
public class #SCRIPTNAME# : NodeGraph {
|
||||||
|
#NOTRIM#
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8165767f64da7d94e925f61a38da668c
|
||||||
|
timeCreated: 1519049802
|
||||||
|
licenseType: Free
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using XNode;
|
||||||
|
|
||||||
|
public class #SCRIPTNAME# : Node {
|
||||||
|
|
||||||
|
// Use this for initialization
|
||||||
|
protected override void Init() {
|
||||||
|
base.Init();
|
||||||
|
#NOTRIM#
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the correct value of an output port when requested
|
||||||
|
public override object GetValue(NodePort port) {
|
||||||
|
return null; // Replace this
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 85f6f570600a1a44d8e734cb111a8b89
|
||||||
|
timeCreated: 1519049802
|
||||||
|
licenseType: Free
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -202,6 +202,10 @@ namespace XNode {
|
|||||||
foreach (NodePort port in Ports) port.ClearConnections();
|
foreach (NodePort port in Ports) port.ClearConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return JsonUtility.ToJson(this).GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Mark a serializable field as an input port. You can access this through <see cref="GetInputPort(string)"/> </summary>
|
/// <summary> Mark a serializable field as an input port. You can access this through <see cref="GetInputPort(string)"/> </summary>
|
||||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
|
||||||
public class InputAttribute : Attribute {
|
public class InputAttribute : Attribute {
|
||||||
|
|||||||
@ -9,8 +9,15 @@ namespace XNode {
|
|||||||
public enum IO { Input, Output }
|
public enum IO { Input, Output }
|
||||||
|
|
||||||
public int ConnectionCount { get { return connections.Count; } }
|
public int ConnectionCount { get { return connections.Count; } }
|
||||||
/// <summary> Return the first connection </summary>
|
/// <summary> Return the first non-null connection </summary>
|
||||||
public NodePort Connection { get { return connections.Count > 0 ? connections[0].Port : null; } }
|
public NodePort Connection {
|
||||||
|
get {
|
||||||
|
for (int i = 0; i < connections.Count; i++) {
|
||||||
|
if (connections[i] != null) return connections[i].Port;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public IO direction { get { return _direction; } }
|
public IO direction { get { return _direction; } }
|
||||||
public Node.ConnectionType connectionType { get { return _connectionType; } }
|
public Node.ConnectionType connectionType { get { return _connectionType; } }
|
||||||
@ -54,8 +61,7 @@ namespace XNode {
|
|||||||
if (attribs[i] is Node.InputAttribute) {
|
if (attribs[i] is Node.InputAttribute) {
|
||||||
_direction = IO.Input;
|
_direction = IO.Input;
|
||||||
_connectionType = (attribs[i] as Node.InputAttribute).connectionType;
|
_connectionType = (attribs[i] as Node.InputAttribute).connectionType;
|
||||||
}
|
} else if (attribs[i] is Node.OutputAttribute) {
|
||||||
else if (attribs[i] is Node.OutputAttribute) {
|
|
||||||
_direction = IO.Output;
|
_direction = IO.Output;
|
||||||
_connectionType = (attribs[i] as Node.OutputAttribute).connectionType;
|
_connectionType = (attribs[i] as Node.OutputAttribute).connectionType;
|
||||||
}
|
}
|
||||||
@ -225,15 +231,17 @@ namespace XNode {
|
|||||||
connections.RemoveAt(i);
|
connections.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (port != null) {
|
||||||
// Remove the other ports connection to this port
|
// Remove the other ports connection to this port
|
||||||
for (int i = 0; i < port.connections.Count; i++) {
|
for (int i = 0; i < port.connections.Count; i++) {
|
||||||
if (port.connections[i].Port == this) {
|
if (port.connections[i].Port == this) {
|
||||||
port.connections.RemoveAt(i);
|
port.connections.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Trigger OnRemoveConnection
|
// Trigger OnRemoveConnection
|
||||||
node.OnRemoveConnection(this);
|
node.OnRemoveConnection(this);
|
||||||
port.node.OnRemoveConnection(port);
|
if (port != null) port.node.OnRemoveConnection(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearConnections() {
|
public void ClearConnections() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user