Giter Site home page Giter Site logo

alelievr / nodegraphprocessor Goto Github PK

View Code? Open in Web Editor NEW
2.2K 57.0 356.0 1.83 MB

Node graph editor framework focused on data processing using Unity UIElements and C# 4.6

Home Page: https://github.com/alelievr/NodeGraphProcessor/projects/2

License: MIT License

C# 100.00%
unity unity-editor graph node-based

nodegraphprocessor's Introduction

NodeGraphProcessor

Node graph editor framework focused on data processing using Unity UIElements, GraphView and C# 4.7

Discord Codacy Badge openupm

This node based solution provides a great C# API allowing you to implement conditional graphs, dependencies graphs, processing graphs and more.
image

Based on Unity's GraphView technology, NodeGraphProcessor is also very fast and works well with large graphs.
Performance

Simple and powerful C# node API to create new nodes and custom views.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;

[System.Serializable, NodeMenuItem("Operations/Sub")] // Add the node in the node creation context menu
public class SubNode : BaseNode
{
    [Input(name = "A")]
    public float                inputA;
    [Input(name = "B")]
    public float                inputB;

    [Output(name = "Out")]
    public float				output;

    public override string		name => "Sub";

    // Called when the graph is process, process inputs and assign the result in output.
    protected override void Process()
    {
        output = inputA - inputB;
    }
}

Unity Compatible versions

This project requires at least Unity 2020.2 with a scripting runtime version of 4.x in player settings.
The current Unity version used for the project is 2020.2.0f1, if you want to install NodeGraphProcessor in an older unity project, you can install it via Open UPM (minimum version: Unity 2019.3).

Installation

Instructions

Install Manually

There are two ways to install this asset: you can use the Unity package manager or move the entire repo inside your Assets folder. To install using the package manager:

  • download this repo
  • inside the package manager click the '+' button at the bottom to add a package from disk
  • then select the package.json file located in Assets/NodeGraphProcessor
  • package is installed :)

Install via OpenUPM

The package is available on the openupm registry. It's recommended to install it via openupm-cli.

openupm add com.alelievr.node-graph-processor

Install via Git

Alternatively, you can use the git address feature in the package manager on the branch #upm, it only contains the package but it may be out of sync compared to master.

Note that you'll not have access to the examples provided in this repo because the package only include the core of NodeGraphProcessor.

Community

Join the NodeGraphProcessor Discord server!

Features

  • Node and Graph property serialization (as json)
  • Scriptable Object to store graph as a Unity asset.
  • Highly customizable and simple node and links API
  • Support multi-input into a container (multiple float into a list of float for example)
  • Graph processor which execute node's logic with a dependency order
  • Documented C# API to add new nodes / graphs
  • Exposed parameters that can be set per-asset to customize the graph processing from scripts or the inspector
  • Parameter set mode, you can now output data from thegraph using exposed parameters. Their values will be updated when the graph is processed
  • Search window to create new nodes
  • Colored groups
  • Node messages (small message with it's icon beside the node)
  • Stack Nodes
  • Relay nodes
  • Display additional settings in the inspector
  • Node creation menu on edge drop
  • Simplified edge connection compared to default GraphView (ShaderGraph and VFX Graph)
  • Multiple graph window workflow (copy/paste)
  • Vertical Ports
  • Sticky notes (requires Unity 2020.1)
  • Renamable nodes

More details are available in the Changelog

Documentation

API doc is available here: alelievr.github.io/NodeGraphProcessor

The user manual is hosted using Github Wiki.

Remaining to do

  • Investigate for ECS/Jobs integration
  • API to create the graph in C#
  • Subgraphs

For more details consult our Github Project page.

Projects made with NodeGraphProcessor

image

Want to be in the made with list? Send a message to the issue #14

Gallery

Minimap

Relay nodes

Node connection menu

Node creation menu

Graph Parameters

Groups

Node Settings

Node Messages

Conditional Processing (in Example)

Stacks

Relay Node Packing

Node Inspector

Improved Edge Connection

Multi-Window support

Field Drawers (Thanks @TeorikDeli!)

Sticky Notes (2020.1 or more required)

image

Vertical Ports

image

Drag And Drop Objects

CreateNodeFromObject

Renamable nodes

Just add this bit of code in your Node script to make it renamable in the UI.

        public override bool	isRenamable => true;

RenamableNode

nodegraphprocessor's People

Contributors

alelievr avatar bezarius avatar cbaggers avatar dsmiller95 avatar favoyang avatar freshlybrewedcode avatar gelonsoft avatar githappens avatar hdmmy avatar hybridherbst avatar merpheus-dev avatar teorikdeli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nodegraphprocessor's Issues

How to get this working

Hi,

I've tried to get this project running in Unity 2019.2 and 2020.1 but I get loads of errors

I copied the project to my Unity project Assets folder and it imported. Then I get about 200 errors

Things like

The type or namespace name 'GraphProcessor' could not be found (are you missing a using directive or an assembly reference?) D:\Unity\Test2\Assets\NodeGraphProcessor-master\Assets\Examples\DefaultNodes\Nodes\TextNode.cs 4 Active

Generally a lot of missing stuff. Where is all this extra stuff?

Thanks

Node edges persist after removal

I'm trying to traverse trough nodes via functions like:
outputPorts.FirstOrDefault(n => n.fieldName == "outNodes").GetEdges().Select(e => e.inputNode as BaseNode) to later conduct operations/process nodes on demand in my implementation.

When i disconnect nodes from graphs in graph editor, they do not disappear from outputPorts. So they are still returned via outputPorts.FirstOrDefault I mentioned.

Example: when I connect output to node A and B - and then remove link to node B and add C: ABC will be returned (instead of AC).
Example 2: adding node and removing it will sill return a node, even if output has no edges.

After code recompilation (after any changes to class files), everything updates to correct state and removed nodes disappear from outputPorts.

Something I may be doing wrong, bug... or something I need to do?
I use manual, node traversal as I use implementation that depends on user input. Maybe this approach is causing issue and I need to use processor?

Undo Performance

Undo performance dramatically degrades right after open Graph and don't restore after the closing of Graph Window.
So maybe implement some Undo listeners cleaning process after the window closing? Or add a possibility of disabling Undo for Graph? Degraded undo performance makes undo totally useless, so if there is no way to fix it disable it will be a better option.

Parameters Cannot Be Deleted (2019.2 & 2019.3, MacOS)

Hi!

It seems, deleting a parameter doesn't work. I tried to edit ExposedParameterFieldView for a possible fix, but I am not too familiar with the UIElements & GraphView yet and I couldn't find a way 🤷🏻‍♂️

Anyway; if I add a parameter and then delete it, it visually deletes from the list but doesn't actually removes from the list. If I add a new parameter, the deleted parameter is shown again or If I save, close and reopen the graph, the deleted parameter is shown again too.

It may be a Unity bug, but there is no problem in ShaderGraph.

Renaming is works by the way.

Name collision with Doozy assets

Hi,
I just pulled this repo into my project and noticed that some of the example scripts share the same name as other included libraries:
Assets/Plugins/Doozy/Engine/Nody/Models/Graph.cs(261,28): error CS0039: Cannot convert type 'Doozy.Engine.Nody.Models.Node' to 'StartNode' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
This can be quickly solved by moving the example scripts into a different namespace.

Potential Issue: Graph is serialized constantly whilst the inspector is active

This one surprised me whilst I was looking into the Unity undo issue.

If you click on a graph in the project treeview (so that it is selected and the GraphInspector is showing in the inspector) BaseGraph.OnBeforeSerialize() will be called constantly.

This is easiest to see if you add a debug.log to BaseGraph.OnBeforeSerialize().

This will probably be an issue when graph sizes are large enough that serializing them every frame would be noticable

How do you use it at runtime?

Hello.
I'd like to use this feature to do some processing at runtime, but I don't know how to do it.
But I've looked at various parts of it, including "read.me", but I don't know how to do it.
I'd appreciate it if you could tell me how to do it.
It's a translation from Japanese, so the text may not be correct. Sorry...

Hello World Example and Contributions?

Hi there, I am evaluating different open source node graph projects for Unity as the basis for other tools I'm writing, both internal and also open source. I like this one because the appearance matches the newer native Unity graph tools and that its available as a package (easy dependency management). I have a couple of questions for you when you have a chance:

  • Do you have a hello world example available somewhere that would demonstrate how to setup a basic graph? I see you have several screenshots on the readme demonstrating the nodes/graphs, but other than the WIP project linked here I'm not sure where to get started. I have followed some of the wiki instructions for creating nodes, graph views, but am not sure where to go from there.
  • If I ended up using this I'd like to help contribute bug fixes/features as I can; how do you want contributions to be made, do you have any particular style guide for code, and is Trello the main backlog source for this project?

Thanks!

InvalidCastException: Specified cast is not valid when having a multiple input

 [Input(name = "Multi float", allowMultiple = true)]
 public IEnumerable<float> inputsFloat;

image

Processing the graph causes this exception :

InvalidCastException: Specified cast is not valid.
(wrapper dynamic-method) System.Object.lambda_method(System.Runtime.CompilerServices.Closure)
GraphProcessor.NodePort.PushData () (at Assets/NodeGraphProcessorRuntime/Core/Elements/NodePort.cs:101)
GraphProcessor.NodeOutputPortContainer+<>c.<PushDatas>b__1_0 (GraphProcessor.NodePort p) (at Assets/NodeGraphProcessorRuntime/Core/Elements/NodePort.cs:159)
System.Collections.Generic.List`1[T].ForEach (System.Action`1[T] action) (at <ac823e2bb42b41bda67924a45a0173c3>:0)
GraphProcessor.NodeOutputPortContainer.PushDatas () (at Assets/NodeGraphProcessorRuntime/Core/Elements/NodePort.cs:159)
GraphProcessor.BaseNode.OnProcess () (at Assets/NodeGraphProcessorRuntime/Core/Elements/BaseNode.cs:159)

Apparently the lambda is not used to dealing with IEnumerable in inputs

Custom Multiple Output ports are not working

Hey there, I've been trying to make a branching structure like a dialogue system. So, I've been trying to convert CustomPortsNode from multiple inputs to mulitple outputs. But whenever I do that, I can connect a single port to another node, though if I try to connect a second one, it throws a NullRefException as follows:

NullReferenceException: Object reference not set to an instance of an object
GraphProcessor.SerializableEdge.CreateNewEdge (GraphProcessor.BaseGraph graph, GraphProcessor.NodePort inputPort, GraphProcessor.NodePort outputPort) (at Assets/com.alelievr.NodeGraphProcessor/Utils/SerializableEdge.cs:53)

And in line 53, we have this:
image

I've tried to debug, in second port connection attempt, outputPort and owner is null.

Behaviour Example: (Doesn't connect 2nd one and throws the exception at above)

image

This is the node that I've used, basically it is the same node as CustomPortDataNode, I just flipped input and outputs.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;

[System.Serializable, NodeMenuItem("Custom/MultiPorts")]
public class CustomPortsNode : BaseNode
{
    [Input]
	public List< float >       	inputs;

	[Output]
	public List< float >		outputs; // TODO: custom function for this one

	List< object >				values;

	public override string		name => "CustomPorts";

    public override string      layoutStyle => "TestType";

    // We keep the max port count so it doesn't cause binding issues
    [SerializeField, HideInInspector]
	int							portCount = 1;

	protected override void Process()
	{
		// do things with values
	}

	[CustomPortBehavior(nameof(outputs))]
	IEnumerable< PortData > ListPortBehavior(List< SerializableEdge > edges)
	{
		portCount = Mathf.Max(portCount, edges.Count + 1);

		for (int i = 0; i < portCount; i++)
		{
			yield return new PortData {
				displayName = "In " + i,
				displayType = typeof(float),
				identifier = i.ToString(), // Must be unique
			};
		}
	}

	[CustomPortOutput(nameof(outputs), typeof(float))]
	void PullInputs(List< SerializableEdge > inputEdges)
	{
		//values = inputEdges.Select(e => e.passThroughBuffer).ToList();
	}

	[CustomPortInput(nameof(inputs), typeof(float))]
	void PushOutputs(List< SerializableEdge > connectedEdges)
	{
		// Values length is supposed to match connected edges length
		//for (int i = 0; i < connectedEdges.Count; i++)
		//	connectedEdges[i].passThroughBuffer = values[i];
	}
}

Negative Compute Order

The computing order becomes negative on a large graph.
UPD: Replacing int to long on the "compute order" field solved the problem, but I don't think that for a long time.
Maybe implement another order computing algorithm?

Proof1
Proof2

Documentation

Hey! I consider using this framework for some of my projects (like self-created Dialogue system). I already used xNode, but NodeGraphProcessor uses new APIs and I see fresh potential.

I'm not sure about some parts of documentation that are unclear for me:

  1. "Remaining to do: Runtime processing without the editor" what does it mean in practice? What it affects? Is solution ready for implementation and optimized enough?

  2. Licence: Would be nice to know for safety what licence project bases upon.

  3. Node coloring: How I may tint nodes for readability? For now, examples are most important learning material - maybe I would find it out in some time. Would be perfect with some direct wiki clarifications related to features.

Thank you for developing this project! :)

Both an input node and an editable field

I figured out that adding both Node and SerializeField attributes to a field give you an editable field plus a node input:

[Input("Amount"), SerializeField]

However this has a few issues.

  1. The editable field is not located next to the input creating a confusing UI
  2. VisibleIf only affects the editable field, not the node input.

I'd be happy to help out with this if you agree it's worth improving on.

Black window

I imported the package, and added the example folder in my assets to test.
When I open an asset like "Basic example", it works great.
But when I go in the window menu and click on 01_DefaultGraph or any other graphs, it just open a black editor window.
I opened the UIElements Debugger and there is only the graphRootView with no children visualElements.

ScriptableObject reference on node possible? (null in build)

Is it's possible to serialize scriptableObject reference? Everything is working in editor but in a build the variable "AiAction" is null when the node is evaluated.

[System.Serializable, NodeMenuItem("Obsolete/AiAction")]
public class AIActionNode : LeafNode
{
    [SerializeField] private AIAction action = null;

    [Input(name = "AIMaster", allowMultiple = false)]
    public AIMaster aiMaster;

    protected override NodeState OnEvaluate()
    {
        return aiMaster.DoAction(action);
    }
}

image

class CustomConvertions -> InvalidCastException: Specified cast is not valid.

Hi,

i try to add code to the class. for example i wanna convert int32 to string. i write the code in CustomConvertions class.

Ekran Resmi 2019-11-15 14 00 50

Seems to be working.

graph

But when i try to run, show this error : InvalidCastException: Specified cast is not valid.

I don't understand. It's same convert vector4 to float. But my code doesn't work.

Please help us!
Thank you =D

Can't add GameObject parameters

Cloned the project and opened in 2019.3.15.

If click on the ExposedGetProperties example, I can see the exposed gameobject property, however, if I try to add more parameters, they don't appear in the inspector.

Tried restarting the editor, but it doesn't help.

Other types of parameters seem to work.

Undo stops working

Represent:
Open some graph.
Change some node position.
Ctrl+z. Working well.
Close graph.
Open another graph.
Change some node position.
Ctrl+z. Not working.

Console error:

ArgumentNullException: Value cannot be null.
Parameter name: identifier
UnityEditor.Undo.RegisterCompleteObjectUndo (UnityEngine.Object objectToUndo, System.String name) (at :0)
GraphProcessor.BaseNodeView.SetPosition (UnityEngine.Rect newPos) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:567)
GraphProcessor.BaseNodeView.InitializeView () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:123)
GraphProcessor.BaseNodeView.Initialize (GraphProcessor.BaseGraphView owner, GraphProcessor.BaseNode node) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:80)
GraphProcessor.BaseGraphView.AddNodeView (GraphProcessor.BaseNode node) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:615)
GraphProcessor.BaseGraphView.InitializeNodeViews () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:532)
GraphProcessor.BaseGraphView.ReloadView () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:473)
UnityEditor.Undo.Internal_CallUndoRedoPerformed () (at :0)
UnityEditor.EditorApplication:Internal_CallGlobalEventHandler()

Process/Traverse the graph

First of all, super excited about this project, i already made some simple nodes in just a few mins.

Not a bug but an example request.

Could you show us how to process the made graph, load it, run it, jump into some non-starter nodes.
A very simple example would be just great

Mike

Support arrays

Hey! Сould you add support for arrays(primitives and unity objects)?

[Question] How difficult would it be to have dynamic location of the connection sockets on the node body?

Hey there,
I have been considering implementing a node graph into my project as it feels like it might make things a bit easier for me. I have just started looking at what's available but so far I like the feature set I am seeing with this one, especially the smaller connection relocation/relay node. The one thing I really need to make sure I can do is be able to implement dynamic placement of the actual connector sockets on the node body itself. In all the images I see so far from this framework, as well as the examples, they are only ever on the left and right sides of the node body. Are they able to be placed on the top and bottom of the node as well?

The only example I have to display what I mean is from an image of another older node framework:

While the main features this framework are great, the actual connection socket being able to move position around the node body is the one thing that would end up making it worth using a node framework at all. If this sounds like something that could be fairly easily implemented then I will definitely give this framework a go.

I appreciate your time,
Thanks,
-MH

NodeGraphs not working when compiling using IL2CPP.

Exception log:

NullReferenceException: Object reference not set to an instance of an object.
  at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate (System.Runtime.CompilerServices.IStrongBox[] closure) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate () [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Expression`1[TDelegate].Compile (System.Boolean preferInterpretation) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Linq.Expressions.Expression`1[TDelegate].Compile () [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.CustomPortIO.LoadCustomPortMethods () [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.CustomPortIO..cctor () [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.NodePort..ctor (GraphProcessor.BaseNode owner, System.Object fieldOwner, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.NodePort..ctor (GraphProcessor.BaseNode owner, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseNode.AddPort (System.Boolean input, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseNode.Initialize (GraphProcessor.BaseGraph graph) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.AddNode (GraphProcessor.BaseNode node) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.Deserialize () [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.OnEnable () [0x00000] in <00000000000000000000000000000000>:0 
Rethrow as TypeInitializationException: The type initializer for 'GraphProcessor.CustomPortIO' threw an exception.
  at GraphProcessor.NodePort..ctor (GraphProcessor.BaseNode owner, System.Object fieldOwner, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.NodePort..ctor (GraphProcessor.BaseNode owner, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseNode.AddPort (System.Boolean input, System.String fieldName, GraphProcessor.PortData portData) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseNode.Initialize (GraphProcessor.BaseGraph graph) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.AddNode (GraphProcessor.BaseNode node) [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.Deserialize () [0x00000] in <00000000000000000000000000000000>:0 
  at GraphProcessor.BaseGraph.OnEnable () [0x00000] in <00000000000000000000000000000000>:0 
 
(Filename: currently not available on il2cpp Line: -1)

NodePort as Proxy

Hello there.
I'm trying to use your graph as View for my own graph data structure.
And i'm stuck on NodePort API usage.
For the reason that i have my own memory Object, i need option specify Owner and FieldInfo as External source of NodePort

public NodePort(BaseNode owner, string fieldName, PortData portData)
		{
			this.fieldName = fieldName;
			this.owner = owner;
			this.portData = portData;

			fieldInfo = owner.GetType().GetField(fieldName, BindingFlags.Public |                                                      BindingFlags.NonPublic | BindingFlags.Instance);

If it possible Port Source data should be wrap as your PortData for use it like abstraction

Have OutputAttribute allowMultiple = false

In the context of a flow graph I would like to prevent an output from being plugged into multiple inputs by using the OutputAttribute with a new parameter "allowMultiple" set to false (much like the InputAttribute).

I'd love to work on this feature if you point me in the right direction for it.

Thanks in advance

ToolbarView AddButton doesn't seem to be adding any buttons

Hey again,
I was beginning to experiment with things, so I create a new Window/View/Toolbar, following the Custom Toolbar example, but then I noticed that even in the example, I don't see any sort of custom toolbar?
I am assuming it should be up there near Center, Show Processor, etc, etc?

I went to try and add a new one as follows:

    public class WaypointNodeManagerToolbar : ToolbarView
    {
        public WaypointNodeManagerToolbar(BaseGraphView graphView) : base(graphView)
        {
        }

        protected override void AddButtons()
        {
            // Add the hello world button on the left of the toolbar
            AddButton("Hello !", () => Debug.Log("Hello World"), false);
            AddButton("Create new Waypoint", () => Debug.Log("Creating new waypoint"));

            // add the default buttons (center, show processor and show in project)
            base.AddButtons();
        }
    }

This is what I end up with:

I feel like I might be missing something silly? Perhaps it's related to 2020.1.0b15. I will try the example in a lesser version to compare.

Thanks,
-MH

Open Script By Type

I'm notice the following source code

public void OpenNodeScript()
{
	var scriptPath = NodeProvider.GetNodeScript(nodeTarget.GetType());

#pragma warning disable CS0618 // Deprecated function but no alternative :(
	if (scriptPath != null)
		InternalEditorUtility.OpenFileAtLineExternal(scriptPath, 0);
#pragma warning restore CS0618
}

But you can do it by this way

 public static bool OpenScript(Type type,params string[] folders)
        {
            var typeName  = type.Name;
            var filter    = $"t:script {typeName}";
            
            var assets = AssetDatabase.FindAssets(filter, folders);
            var assetGuid = assets.FirstOrDefault(
                    x => string.Equals(typeName,
                        Path.GetFileNameWithoutExtension(x.AssetGuidToPath()),
                        StringComparison.OrdinalIgnoreCase));
            
            if (string.IsNullOrEmpty(assetGuid))
                return false;
            
            var asset = AssetDatabase.LoadAssetAtPath<Object>(assetGuid.AssetGuidToPath());
            if (asset == null)
                return false;
            return AssetDatabase.OpenAsset(asset.GetInstanceID(), 0, 0);
        }

Potential bug in when CustomPortsNode updates it's input ports

If I have understood the point of this node correctly it should always have one more port than the max number of input edges is has had previously. However when I add an input edge it doesn't update the port UI until some other action forces it (for example adding a new output edge).

This clip shows the issue:

multiNodeUpdateBug

In my code I worked around this by adding a custom view as follows:

[NodeCustomEditor(typeof(SomeNode))]
public class SomeNodeView : RealtimeNodeView
{
    public override void Enable()
    {
	nodeTarget.onAfterEdgeConnected += OnStructuralChange;
	nodeTarget.onAfterEdgeDisconnected += OnStructuralChange;
    }

    void OnStructuralChange(SerializableEdge _) => ForceUpdatePorts();
}

Is this intended behavior? Apologies if I missed something obvious.

ListView on the node

Hello, thanks for the conditional example, it was very helpful.
Can you show me some examples of how can I add some list or array to the node?

Thanks for the support, Mikhail.

Subgraphs /nested graphs

I'm still playing and getting to grips with how things work but I suspect eventually I will need subgraphs in some form. I wondered if you'd given the matter much thought or got any rough ideas what the most natural way to approach this would be?

Building the project

Hey there, when I try to build my projects with NodeGraphProcessor, I get lots of compile errors because some scripts are missing.

Is there a solution for this ?

I get errors like this:
The type or namespace name 'UIElements' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)

undo very slow in unity 2019.3.5f1

when i open any graph and move node position, press ctrl+z.
it's need wait over 1 min then the node recover to origin position.

unity version : 2019.3.5f1

(Runtime graph) Need to execute 2 time for parameter to get set?

image

Im messing around and familiarizing myself with the api (Nice job to the author by the way). I'm trying to execute the following graph in runtime using the base processor for some reason i always get a null reference of the parameters on the first go but after that everything working has it should.

here is the runtime code,
`public class Testing : SerializedMonoBehaviour
{
[SerializeField] private TreeBehaviorGraph graph = null;
[SerializeField] private ProcessGraphProcessor processor;

[BoxGroup("Entities")]
public RPGEntity player;
[BoxGroup("Entities")]
public RPGEntity AI;

private void Start()
{
    graph = ScriptableObject.Instantiate(graph);

    if (graph != null)
        processor = new ProcessGraphProcessor(graph);
}

[Button("Init")]
public void Init()
{
    graph.SetParameterValue("ThisEntity", player);
    graph.SetParameterValue("Target", AI);
}

[Button("Execute")]
public void Execute()
{
    if (graph != null)
    {
        Init();
        processor.Run();
    }
}

}`

CustomPortBehavior Multiple Port Node

Hello Again ;)

by your good advice i use [CustomPortBehavior] attribute for my purpose.
It look's like:

    [Serializable]
    public class UniBaseNode : BaseNode

And SetUp Custom Port Behaviour:

        
        [CustomPortBehavior(nameof(inputs))]
        public IEnumerable< PortData > GetPortsForInputs(List< SerializableEdge > edges)
        {
            return GetPorts(PortIO.Input);
        }
        
        [CustomPortBehavior(nameof(outputs))]
        public IEnumerable< PortData > GetPortsForOutputs(List< SerializableEdge > edges)
        {
            return GetPorts(PortIO.Output);
        }

It look correct from Editor Window

But when i try to break connection between any node that error occurs:

MissingMethodException: Default constructor not found for type System.Collections.Generic.IEnumerable`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Activator.CreateInstance (System.Type type) (at <437ba245d8404784b9fbab9b439ac908>:0)
GraphProcessor.NodePort.ResetToDefault () (at Assets/NodeGraphProcessor/Assets/com.alelievr.NodeGraphProcessor/Runtime/Elements/NodePort.cs:236)
GraphProcessor.BaseNode.OnEdgeDisconnected (GraphProcessor.SerializableEdge edge) (at Assets/NodeGraphProcessor/Assets/com.alelievr.NodeGraphProcessor/Runtime/Elements/BaseNode.cs:341)
GraphProcessor.BaseGraph+<>c__DisplayClass36_0.<Disconnect>b__0 (GraphProcessor.SerializableEdge r) (at Assets/NodeGraphProcessor/Assets/com.alelievr.NodeGraphProcessor/Runtime/Graph/BaseGraph.cs:270)


Edge drag and drop behaviour

Just jotting down some thoughts as I see you're working on the relay node and this might have some relationship with that task.

Currently playing with Mixture and I find myself frequently creating relay nodes by accident:

  1. When I miss dropping an edge on an input node by a few pixels (the target is very small
  2. When I don't notice the input type doesn't match and the input is disabled (I've got better at not doing this but newbies will do it all the time)

In general - the small target size of input nodes makes it much slower to create graphs quickly (Fitt's Law)

It's not uncommon for there to be a on obvious "main" input for a node. I wonder if it might improve UX for the entire node should be a valid drop target and for the node to make a sensible guess as to what the correct input to connect is.

It could be as simple as "pick the first unconnected valid input" and then the source code order can be used to determine which nodes are good defaults (I think you'd naturally do this in any case - you tend to put the most important nodes first)

In any case - dropping an edge on a node shouldn't create a relay. Only dropping on empty space should do that.

I've got some other thoughts around drag+drop - dropping nodes on edges should insert etc but they probably should be separate issues.

Wiki's default graph window example is outdated

I found this example from the wiki while playing around, and it gave an error saying "DefaultGraphWindow does not implement inherited abstract member 'BaseGraphWindow.InitializeWindow(BaseGraph)".

Apparantly Initialize() has been renamed to InitializeWindow(). I think that should be updated in the wiki page too. I would also remove the unnecessary using directives which are System.Collections and System.Collections.Generic, so that the example can be as clutter-free as possible.

ComputeOrderType.DepthFirst performance dramatically degradation.

The performance of add and remove node actions begins to degrade significantly on the high count of nodes.
The root of the issue is a DFS algorithm.
BFS works without any performance issues at all.

Here green is an ok performance point and red is a point where issues start.
изображение

All graph
изображение

Recursive Serialization is not supported. You can't dereference a PPtr while loading (occasional crash)

First off, fantastic project. I'm thoroughly impressed with where is going.

Unity version is 2019.3.15f1

Either Unity crashes while loading or, if it does load, I have this error in the console.

Recursive Serialization is not supported. You can't dereference a PPtr while loading. (Constructors of C# classes may not load objects either. See stacktrace.)
UnityEngine.JsonUtility:FromJsonOverwrite(String, Object)
GraphProcessor.SerializableObject:OnAfterDeserialize() (at Assets/com.alelievr.NodeGraphProcessor/Runtime/Utils/SerrializableObject.cs:54)

I checked the Editor.log and found this that looked relevant:

Assertion failed on expression: 'CurrentThread::IsMainThread()'
UnityEngine.JsonUtility:FromJsonInternal(String, Object, Type)
UnityEngine.JsonUtility:FromJsonOverwrite(String, Object)
GraphProcessor.SerializableObject:OnAfterDeserialize() (at Assets\com.alelievr.NodeGraphProcessor\Runtime\Utils\SerrializableObject.cs:54)

[C:\buildslave\unity\build\Runtime/BaseClasses/BaseObject.cpp line 288] 
(Filename: Assets/com.alelievr.NodeGraphProcessor/Runtime/Utils/SerrializableObject.cs Line: 54)

Stacktrace:

  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) UnityEngine.JsonUtility.FromJsonInternal (string,object,System.Type) [0x00009] in <1386288601af43018501cce2912f52f4>:0
  at UnityEngine.JsonUtility.FromJsonOverwrite (string,object) [0x00059] in <1386288601af43018501cce2912f52f4>:0
  at GraphProcessor.SerializableObject.OnAfterDeserialize () [0x00090] in C:\home\Code\NodeGraphProcessor\Assets\com.alelievr.NodeGraphProcessor\Runtime\Utils\SerrializableObject.cs:54
  at (wrapper runtime-invoke) object.runtime_invoke_void__this__ (object,intptr,intptr,intptr) [0x00020] in <437ba245d8404784b9fbab9b439ac908>:0

line 54 can be seen here

            else if (typeof(UnityEngine.Object).IsAssignableFrom(type))
            {
                ObjectWrapper obj = new ObjectWrapper();
                JsonUtility.FromJsonOverwrite(serializedValue, obj); // <<<<<<<< LINE 54
                value = obj.value;
            }

which is odd as the documentation for FromJsonOverwrite makes it look like this this should be safe from threads other than main.

I'll post more if I find it.

Loop Node

Hello!

Node Graph Processor is a wonderful framework, but I don't know how to make a loop node.
Can you help me?
Something like a ForLoop node from the UE4.

Exposed parameters of gameobject type is not serialized causing nullref exception during runtime.

When setting exposed parameter of gameobject type from code using exposedParameters[0].serializedValue.value , there is no data in exposedParameters[0].serializedValue.serializedValue which causes this error:

System.NullReferenceException
  at (wrapper managed-to-native) UnityEngine.GameObject.get_transform(UnityEngine.GameObject)
  at GetPositionNode.Process () [0x00001] in F:\Projects\FatalSet\Assets\_FS\Script\NodeSystem\Nodes\GameObjectNodes.cs:30 
  at GraphProcessor.BaseNode.<OnProcess>b__49_0 () [0x00000] in F:\Projects\FatalSet\Library\PackageCache\com.alelievr.node-graph-processor@92ac41e0ce\Runtime\Elements\BaseNode.cs:351 
  at GraphProcessor.ExceptionToLog.Call (System.Action a) [0x00002] in F:\Projects\FatalSet\Library\PackageCache\com.alelievr.node-graph-processor@92ac41e0ce\Runtime\Utils\ExceptionToLog.cs:14 
UnityEngine.Debug:LogError(Object)
GraphProcessor.ExceptionToLog:Call(Action) (at Library/PackageCache/com.alelievr.node-graph-processor@92ac41e0ce/Runtime/Utils/ExceptionToLog.cs:19)
GraphProcessor.BaseNode:OnProcess() (at Library/PackageCache/com.alelievr.node-graph-processor@92ac41e0ce/Runtime/Elements/BaseNode.cs:351)
NodeGraphProcessor.Assets.Examples.ConditionalGraph.<RunConditionalGraph>d__13:MoveNext() (at Assets/Samples/Node Graph Processor/0.6.0/Examples/ConditionalGraph/ConditionalProcessor.cs:154)
NodeGraphProcessor.Assets.Examples.ConditionalGraph.ConditionalProcessor:Run() (at Assets/Samples/Node Graph Processor/0.6.0/Examples/ConditionalGraph/ConditionalProcessor.cs:51)
AIController:Update() (at Assets/_FS/Script/AIController.cs:149)

I think ConditionalProcessor needs to use serializedValue.value when serializedValue.serializedValue returns empty string or use only serializedValue.value during runtime execution.

Add Compatibility section to README.md

Great project and amazing work. Just took me a while to figure out I needed the latest Unity3D beta version 2018.3.x
I feel it should improve the adoption of the project.
Thanks!

Accessing to connected nodes

I am trying to access to connected nodes in order to only process them but when I do something such as nodes.GetOutputNodes() it always return 0 elements. So I am unable to trace connections. Is there a way of doing it ?

An issue with dragging in assets. Probably a bug in unity's shader graph that we'll need to handle

When dragging an asset over the graph view Unity spams Undo.undoRedoPerformed. A real pain when you try to use nodes with ObjectFields.

It manifests in two different ways depending on if it's a temp graph or not.

Here is the case where the graph is loaded from an asset.

graphUndoRedoIssue0

And here is one of the stack traces (they all seem to be the same).

ArgumentNullException: Value cannot be null.
Parameter name: identifier
UnityEditor.Undo.RegisterCompleteObjectUndo (UnityEngine.Object objectToUndo, System.String name) (at <a20a50bbfaff4193bf6ba6b262f9a71f>:0)
GraphProcessor.BaseGraphView.RegisterCompleteObjectUndo (System.String name) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:968)
GraphProcessor.BaseNodeView.SetPosition (UnityEngine.Rect newPos) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:646)
GraphProcessor.BaseNodeView.InitializeView () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:153)
GraphProcessor.BaseNodeView.Initialize (GraphProcessor.BaseGraphView owner, GraphProcessor.BaseNode node) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseNodeView.cs:81)
GraphProcessor.BaseGraphView.AddNodeView (GraphProcessor.BaseNode node) (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:736)
GraphProcessor.BaseGraphView.InitializeNodeViews () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:635)
GraphProcessor.BaseGraphView.ReloadView () (at Assets/com.alelievr.NodeGraphProcessor/Editor/Views/BaseGraphView.cs:567)
UnityEditor.Undo.Internal_CallUndoRedoPerformed () (at <a20a50bbfaff4193bf6ba6b262f9a71f>:0)

The case for temporary graphs is a little different. This is the one that is causing me the most issues as I use temp graphs.
The second case is a little different.

Note: I needed to restart the editor after getting the first kind of error before this one showed up.

graphUndoRedoIssue1

Here we do actually get an undo before it start spamming the callback. In the first part of the video I move a node twice (it's hard to see but I do briefly let go of it when it's on the left). In the second part of the video I spawn a node to show that the spurious undo removes the node.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.