mirror of
https://github.com/Siccity/xNode.git
synced 2025-12-21 01:36:03 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
08582d9536
@ -2,34 +2,58 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNodeEditor {
|
namespace XNodeEditor {
|
||||||
public class NodeEditorAssetModProcessor : UnityEditor.AssetModificationProcessor {
|
/// <summary> Deals with modified assets </summary>
|
||||||
public static AssetDeleteResult OnWillDeleteAsset(string path, RemoveAssetOptions options) {
|
class NodeEditorAssetModProcessor : UnityEditor.AssetModificationProcessor {
|
||||||
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
|
|
||||||
|
|
||||||
|
/// <summary> Automatically delete Node sub-assets before deleting their script.
|
||||||
|
/// <para/> This is important to do, because you can't delete null sub assets. </summary>
|
||||||
|
private static AssetDeleteResult OnWillDeleteAsset (string path, RemoveAssetOptions options) {
|
||||||
|
// Get the object that is requested for deletion
|
||||||
|
UnityEngine.Object obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object> (path);
|
||||||
|
|
||||||
|
// If we aren't deleting a script, return
|
||||||
if (!(obj is UnityEditor.MonoScript)) return AssetDeleteResult.DidNotDelete;
|
if (!(obj is UnityEditor.MonoScript)) return AssetDeleteResult.DidNotDelete;
|
||||||
|
|
||||||
|
// Check script type. Return if deleting a non-node script
|
||||||
UnityEditor.MonoScript script = obj as UnityEditor.MonoScript;
|
UnityEditor.MonoScript script = obj as UnityEditor.MonoScript;
|
||||||
System.Type scriptType = script.GetClass();
|
System.Type scriptType = script.GetClass ();
|
||||||
|
if (scriptType != typeof (XNode.Node) && !scriptType.IsSubclassOf (typeof (XNode.Node))) return AssetDeleteResult.DidNotDelete;
|
||||||
|
|
||||||
if (scriptType != typeof(XNode.Node) && !scriptType.IsSubclassOf(typeof(XNode.Node))) return AssetDeleteResult.DidNotDelete;
|
// Find all ScriptableObjects using this script
|
||||||
|
string[] guids = AssetDatabase.FindAssets ("t:" + scriptType);
|
||||||
//Find ScriptableObjects using this script
|
|
||||||
string[] guids = AssetDatabase.FindAssets("t:" + scriptType);
|
|
||||||
for (int i = 0; i < guids.Length; i++) {
|
for (int i = 0; i < guids.Length; i++) {
|
||||||
string assetpath = AssetDatabase.GUIDToAssetPath(guids[i]);
|
string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]);
|
||||||
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetpath);
|
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath);
|
||||||
for (int k = 0; k < objs.Length; k++) {
|
for (int k = 0; k < objs.Length; k++) {
|
||||||
XNode.Node node = objs[k] as XNode.Node;
|
XNode.Node node = objs[k] as XNode.Node;
|
||||||
if (node.GetType() == scriptType) {
|
if (node.GetType () == scriptType) {
|
||||||
if (node != null && node.graph != null) {
|
if (node != null && node.graph != null) {
|
||||||
Debug.LogWarning(node.name + " of " + node.graph + " depended on deleted script and has been removed automatically.", node.graph);
|
// Delete the node and notify the user
|
||||||
node.graph.RemoveNode(node);
|
Debug.LogWarning (node.name + " of " + node.graph + " depended on deleted script and has been removed automatically.", node.graph);
|
||||||
|
node.graph.RemoveNode (node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// We didn't actually delete the script. Tell the internal system to carry on with normal deletion procedure
|
||||||
return AssetDeleteResult.DidNotDelete;
|
return AssetDeleteResult.DidNotDelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Automatically re-add loose node assets to the Graph node list </summary>
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
private static void OnReloadEditor () {
|
||||||
|
// Find all NodeGraph assets
|
||||||
|
string[] guids = AssetDatabase.FindAssets ("t:" + typeof (XNode.NodeGraph));
|
||||||
|
for (int i = 0; i < guids.Length; i++) {
|
||||||
|
string assetpath = AssetDatabase.GUIDToAssetPath (guids[i]);
|
||||||
|
XNode.NodeGraph graph = AssetDatabase.LoadAssetAtPath (assetpath, typeof (XNode.NodeGraph)) as XNode.NodeGraph;
|
||||||
|
graph.nodes.RemoveAll(x => x == null); //Remove null items
|
||||||
|
Object[] objs = AssetDatabase.LoadAllAssetRepresentationsAtPath (assetpath);
|
||||||
|
// Ensure that all sub node assets are present in the graph node list
|
||||||
|
for (int u = 0; u < objs.Length; u++) {
|
||||||
|
if (!graph.nodes.Contains (objs[u] as XNode.Node)) graph.nodes.Add(objs[u] as XNode.Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +193,8 @@ namespace XNodeEditor {
|
|||||||
//Save guiColor so we can revert it
|
//Save guiColor so we can revert it
|
||||||
Color guiColor = GUI.color;
|
Color guiColor = GUI.color;
|
||||||
for (int n = 0; n < graph.nodes.Count; n++) {
|
for (int n = 0; n < graph.nodes.Count; n++) {
|
||||||
while (graph.nodes[n] == null) graph.nodes.RemoveAt(n);
|
// Skip null nodes. The user could be in the process of renaming scripts, so removing them at this point is not advisable.
|
||||||
|
if (graph.nodes[n] == null) continue;
|
||||||
if (n >= graph.nodes.Count) return;
|
if (n >= graph.nodes.Count) return;
|
||||||
XNode.Node node = graph.nodes[n];
|
XNode.Node node = graph.nodes[n];
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,28 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace XNode {
|
namespace XNode {
|
||||||
/// <summary> Base class for all nodes </summary>
|
/// <summary>
|
||||||
|
/// Base class for all nodes
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// Classes extending this class will be considered as valid nodes by xNode.
|
||||||
|
/// <code>
|
||||||
|
/// [System.Serializable]
|
||||||
|
/// public class Adder : Node {
|
||||||
|
/// [Input] public float a;
|
||||||
|
/// [Input] public float b;
|
||||||
|
/// [Output] public float result;
|
||||||
|
///
|
||||||
|
/// // GetValue should be overridden to return a value for any specified output port
|
||||||
|
/// public override object GetValue(NodePort port) {
|
||||||
|
/// return a + b;
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public abstract class Node : ScriptableObject {
|
public abstract class Node : ScriptableObject {
|
||||||
|
/// <summary> Used by <see cref="InputAttribute"/> and <see cref="OutputAttribute"/> to determine when to display the field value associated with a <see cref="NodePort"/> </summary>
|
||||||
public enum ShowBackingValue {
|
public enum ShowBackingValue {
|
||||||
/// <summary> Never show the backing value </summary>
|
/// <summary> Never show the backing value </summary>
|
||||||
Never,
|
Never,
|
||||||
@ -55,16 +74,26 @@ namespace XNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Instance Ports
|
#region Instance Ports
|
||||||
/// <summary> Returns input port at index </summary>
|
/// <summary> Convenience function.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="AddInstancePort"/>
|
||||||
|
/// <seealso cref="AddInstanceOutput"/>
|
||||||
public NodePort AddInstanceInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
public NodePort AddInstanceInput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
return AddInstancePort(type, NodePort.IO.Input, connectionType, fieldName);
|
return AddInstancePort(type, NodePort.IO.Input, connectionType, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns input port at index </summary>
|
/// <summary> Convenience function.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="AddInstancePort"/>
|
||||||
|
/// <seealso cref="AddInstanceInput"/>
|
||||||
public NodePort AddInstanceOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
public NodePort AddInstanceOutput(Type type, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
return AddInstancePort(type, NodePort.IO.Output, connectionType, fieldName);
|
return AddInstancePort(type, NodePort.IO.Output, connectionType, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Add a dynamic, serialized port to this node.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="AddInstanceInput"/>
|
||||||
|
/// <seealso cref="AddInstanceOutput"/>
|
||||||
private NodePort AddInstancePort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
private NodePort AddInstancePort(Type type, NodePort.IO direction, Node.ConnectionType connectionType = Node.ConnectionType.Multiple, string fieldName = null) {
|
||||||
if (fieldName == null) {
|
if (fieldName == null) {
|
||||||
fieldName = "instanceInput_0";
|
fieldName = "instanceInput_0";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user