Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CustomBehaviour Port drawers & Proxied Fields #204

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a511e4a
Update README.md
Greebling Oct 11, 2021
d94beb1
fixed typo in function name
Greebling Oct 12, 2021
43e5087
Implement conversion nodes
Greebling Jan 29, 2022
ad613d9
Fix typos and ordering of TypesAreConnectable call
Greebling Jan 29, 2022
0db21a3
Cleared up error message for wrong usage of custom io port functions
Greebling Jan 29, 2022
ed98f48
Add support for user created property fields that are not in a valid …
Greebling Jan 29, 2022
a525dd2
Add support for creating no ports from custom port behaviours
Greebling Jan 29, 2022
ae7e2ca
Small performance optimization
Greebling Jan 29, 2022
83c1dcb
Fixed node creation menu displaying interfaces
Greebling Jan 29, 2022
3747551
Fixed nullreference when opening and closing the graph window too fast
Greebling Jan 29, 2022
7812566
Add example conversion node
Greebling Jan 29, 2022
5323252
Revert "Update README.md"
Greebling Jan 29, 2022
8487de6
Fix typos
Greebling Jan 29, 2022
ecc4dc0
Relaxed filtering of inactive property fields
Greebling Jan 29, 2022
04332b6
Merge remote-tracking branch 'origin/NGP-Changes' into NGP-Changes
Greebling Jan 29, 2022
5f5c9a4
Add conversion adapter
Greebling Jan 31, 2022
e0a1dde
Add meta data
Greebling Jan 31, 2022
664e867
Made float rounding much more robust
Greebling Jan 31, 2022
e07e184
Replaced ShowAsDrawer with Input field
Feb 3, 2022
78cf45f
Removed debug
Feb 3, 2022
5eb25ae
Minor
Feb 3, 2022
d16504e
Added FieldInfo extensions for HasAttribute
Feb 3, 2022
eb09268
MovedFieldInfoExtensions into its own file
Feb 3, 2022
26dce96
Also use ShowAsDrawer attribute
Feb 3, 2022
e897ff5
Created Example
Feb 3, 2022
e91597b
Added IsProxied property to portdata
Feb 3, 2022
5a10792
Merge pull request #1 from dannymate/NGP-Changes
dannymate Feb 4, 2022
c43ab14
Merge branch 'master' into CustomBehaviour_PortDrawers
Feb 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions Assets/Examples/DefaultNodes/Nodes/DrawerFieldTestNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,49 @@
public class DrawerFieldTestNode : BaseNode
{

[Input(name = "Vector 4"), ShowAsDrawer]
public Vector4 vector4;
[Input(name = "Vector 4"), ShowAsDrawer]
public Vector4 vector4;

[Input(name = "Vector 3"), ShowAsDrawer]
public Vector3 vector3;
[Input(name = "Vector 3"), ShowAsDrawer]
public Vector3 vector3;

[Input(name = "Vector 2"), ShowAsDrawer]
public Vector2 vector2;
[Input(name = "Vector 2"), ShowAsDrawer]
public Vector2 vector2;

[Input(name = "Float"), ShowAsDrawer]
public float floatInput;
[Input(name = "Float"), ShowAsDrawer]
public float floatInput;

[Input(name = "Vector 3 Int"), ShowAsDrawer]
public Vector3Int vector3Int;
[Input(name = "Vector 3 Int"), ShowAsDrawer]
public Vector3Int vector3Int;

[Input(name = "Vector 2 Int"), ShowAsDrawer]
public Vector2Int vector2Int;
[Input(name = "Vector 2 Int"), ShowAsDrawer]
public Vector2Int vector2Int;

[Input(name = "Int"), ShowAsDrawer]
public int intInput;
[Input(name = "Int"), ShowAsDrawer]
public int intInput;

[Input(name = "Empty")]
public int intInput2;
[Input(name = "Empty")]
public int intInput2;

[Input(name = "String"), ShowAsDrawer]
public string stringInput;
[Input(name = "String"), ShowAsDrawer]
public string stringInput;

[Input(name = "Color"), ShowAsDrawer]
new public Color color;
[Input(name = "Color"), ShowAsDrawer]
new public Color color;

[Input(name = "Game Object"), ShowAsDrawer]
public GameObject gameObject;
[Input(name = "Game Object"), ShowAsDrawer]
public GameObject gameObject;

[Input(name = "Animation Curve"), ShowAsDrawer]
public AnimationCurve animationCurve;
[Input(name = "Animation Curve"), ShowAsDrawer]
public AnimationCurve animationCurve;

[Input(name = "Rigidbody"), ShowAsDrawer]
public Rigidbody rigidbody;
[Input(name = "Rigidbody"), ShowAsDrawer]
public Rigidbody rigidbody;

[Input("Layer Mask"), ShowAsDrawer]
public LayerMask layerMask;
[Input("Layer Mask"), ShowAsDrawer]
public LayerMask layerMask;

public override string name => "Drawer Field Test";
public override string name => "Drawer Field Test";

protected override void Process() {}
protected override void Process() { }
}
8 changes: 8 additions & 0 deletions Assets/Examples/DefaultNodes/Nodes/DynamicPortGeneration.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;
using System.Reflection;
using System;

[System.Serializable]
public abstract class DynamicNode<T> : BaseNode
{
[Input("Action Data", true)]
public Dictionary<string, List<object>> actionData = new Dictionary<string, List<object>>();

public T data;

public override bool needsInspector => true;

protected override void Process()
{
UpdateActionWithCustomPortData();
}

protected virtual void UpdateActionWithCustomPortData()
{
// We clone due to reference issues
Dictionary<string, List<object>> actionDataClone = new Dictionary<string, List<object>>(actionData);

foreach (var field in GetInputFieldsOfType())
{
if (!actionDataClone.ContainsKey(field.fieldInfo.Name))
{
if (field.inputAttribute.showAsDrawer)
continue;

field.fieldInfo.SetValue(data, default);
continue;
}

field.fieldInfo.SetValue(data, actionDataClone[field.fieldInfo.Name][0]);
}

actionData.Clear();
}

#region Reflection Generation Of Ports

private List<FieldPortInfo> GetInputFieldsOfType()
{
List<FieldPortInfo> foundInputFields = new List<FieldPortInfo>();

Type dataType = data != null ? data.GetType() : typeof(T);
foreach (var field in dataType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
foreach (var attribute in field.GetCustomAttributes(typeof(InputAttribute), true))
{
if (attribute.GetType() != typeof(InputAttribute) && !attribute.GetType().IsSubclassOf(typeof(InputAttribute))) continue;

foundInputFields.Add(new FieldPortInfo(field, attribute as InputAttribute));
break;
}
}

return foundInputFields;
}

private FieldPortInfo GetFieldPortInfo(string fieldName)
{
Type dataType = data != null ? data.GetType() : typeof(T);

FieldInfo fieldInfo = dataType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
InputAttribute inputAttribute = fieldInfo.GetCustomAttribute<InputAttribute>();

return new FieldPortInfo(fieldInfo, inputAttribute);
}

[CustomPortInput(nameof(actionData), typeof(object))]
protected void PullInputs(List<SerializableEdge> connectedEdges)
{
if (connectedEdges.Count == 0) return;

FieldPortInfo field = GetFieldPortInfo(connectedEdges.ElementAt(0).inputPortIdentifier);

if (actionData == null) actionData = new Dictionary<string, List<object>>();
foreach (var edge in connectedEdges)
{
if (!actionData.ContainsKey(field.fieldInfo.Name))
actionData.Add(field.fieldInfo.Name, new List<object>());

actionData[field.fieldInfo.Name].Add(edge.passThroughBuffer);
}
}

[CustomPortBehavior(nameof(actionData))]
protected IEnumerable<PortData> ActionDataBehaviour(List<SerializableEdge> edges) // Try changing edge here when ports update
{
foreach (var field in GetInputFieldsOfType())
{
Type displayType = field.fieldInfo.FieldType;

yield return new PortData
{
displayName = field.inputAttribute.name,
displayType = displayType,
identifier = field.fieldInfo.Name,
showAsDrawer = field.inputAttribute.showAsDrawer,
vertical = false,
proxiedFieldPath = nameof(data) + '.' + field.fieldInfo.Name,
acceptMultipleEdges = field.inputAttribute.allowMultiple,
};
}

// Debug.Log(this.GetCustomName() + " BEHAVE: " + this.inputPorts.Count);
}

// public override IEnumerable<FieldInfo> OverrideFieldOrder(IEnumerable<FieldInfo> fields)
// {
// return base.OverrideFieldOrder(fields).Reverse();

// // static long GetFieldInheritanceLevel(FieldInfo f)
// // {
// // int level = 0;
// // var t = f.DeclaringType;
// // while (t != null)
// // {
// // t = t.BaseType;
// // level++;
// // }

// // return level;
// // }

// // // Order by MetadataToken and inheritance level to sync the order with the port order (make sure FieldDrawers are next to the correct port)
// // return fields.OrderByDescending(f => (GetFieldInheritanceLevel(f) << 32) | (long)f.MetadataToken);

// }

#endregion
}

public struct FieldPortInfo
{
public FieldInfo fieldInfo;
public InputAttribute inputAttribute;

public FieldPortInfo(FieldInfo fieldInfo, InputAttribute inputAttribute)
{
this.fieldInfo = fieldInfo;
this.inputAttribute = inputAttribute;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;

[System.Serializable]
public abstract class DynamicNodeWithOutput<T> : DynamicNode<T>
{
[Output(name = "Out")]
public T dataOutput;

public override string name => "DynamicNodeWithOutput";

protected override void Process()
{
base.Process();
dataOutput = data;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions Assets/Examples/DefaultNodes/Nodes/DynamicPortGeneration/Namer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GraphProcessor;
using UnityEngine;

[Serializable]
public class Namer
{
[SerializeField, Input("Name"), ShowAsDrawer] string name;
[SerializeField, Input("Bool")] bool value;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GraphProcessor;
using System.Linq;

[System.Serializable, NodeMenuItem("Custom/ProxiedInputsNode")]
public class NamerNode : DynamicNodeWithOutput<Namer>
{
public override string name => "ConditionalNameNode";
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions Assets/Examples/DefaultNodes/Nodes/FloatToStringNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Globalization;
using GraphProcessor;
using UnityEngine;

[Serializable, NodeMenuItem("Convert/Float to String"), ConverterNode(typeof(float), typeof(string))]
public class FloatToStringsNode : BaseNode, IConversionNode
{
[Input("In")]
public float input;

public int decimalPlaces = 2;

[Output("Out")]
public string output;

public override string name => "To String";

public string GetConversionInput()
{
return nameof(input);
}

public string GetConversionOutput()
{
return nameof(output);
}

protected override void Process()
{
output = input.ToString("F" + decimalPlace, CultureInfo.InvariantCulture);
output = val.ToString(CultureInfo.InvariantCulture);
}
}
3 changes: 3 additions & 0 deletions Assets/Examples/DefaultNodes/Nodes/FloatToStringNode.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Assets/Examples/Editor/GraphAssetCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public class GraphAssetCallbacks
{
[MenuItem("Assets/Create/GraphProcessor", false, 10)]
public static void CreateGraphPorcessor()
public static void CreateGraphProcessor()
{
var graph = ScriptableObject.CreateInstance< BaseGraph >();
ProjectWindowUtil.CreateAsset(graph, "GraphProcessor.asset");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public virtual void OnDrop(GraphView graphView, Edge edge)
try
{
this.graphView.RegisterCompleteObjectUndo("Connected " + edgeView.input.node.name + " and " + edgeView.output.node.name);
if (!this.graphView.Connect(edge as EdgeView, autoDisconnectInputs: !wasOnTheSamePort))
if (!this.graphView.ConnectConvertable(edge as EdgeView, !wasOnTheSamePort))
this.graphView.Disconnect(edge as EdgeView);
} catch (System.Exception)
{
Expand Down
Loading