So I have a couple layers of inheritance first. It looks like this: BaseNode > DynamicNode > SequenceNode
In Dynamic node I'm creating ports on the fly with CustomPortBehavior and CustomPortInput. Everything works how you would expect except I'd prefer if the ports were reordered so I did by implementing the OverrideFieldOrder method. Essentially all I'm doing is reversing the original order. i.e. return base.OverrideFieldOrder(fields).Reverse();.
Also for some reason the property drawer for a float in DynamicNode is in the wrong place by default.
The order is reversed correctly but when creating a connection node in the menu it doesn't pickup up the correct type.
Before (Dragging&Dropping an edge):
After (Dragging&Dropping an edge):
The float itself does work before and after so I think it could be some kind of generic inheritance thing.
Code For DynamicNode:
DynamicNode Code
```c#
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 : BaseNode
{
[Input("Action Data")]
public Dictionary actionData = new Dictionary();
[Input("Float Val"), SerializeField] public float floatVal;
[SerializeField, ExpandableSO, ValueChangedCallback(nameof(OnDataChanged))] public T data;
protected override void Process()
{
UpdateActionWithCustomPortData();
}
protected virtual void UpdateActionWithCustomPortData()
{
// We clone due to reference issues
Dictionary actionDataClone = new Dictionary(actionData);
foreach (var field in GetInputFieldsOfType())
{
if (!actionDataClone.ContainsKey(field.fieldInfo.Name))
{
field.fieldInfo.SetValue(data, default);
}
else
{
field.fieldInfo.SetValue(data, actionDataClone[field.fieldInfo.Name]);
}
}
actionData.Clear();
}
protected virtual void OnDataChanged(UnityEditor.SerializedProperty serializedProperty)
{
UpdatePortsForFieldLocal(nameof(actionData));
}
#region Reflection Generation Of Ports
private List GetInputFieldsOfType()
{
List foundInputFields = new List();
Type dataType = actionData != 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)) continue;
foundInputFields.Add(new FieldPortInfo(field, attribute as InputAttribute));
break;
}
}
return foundInputFields;
}
[CustomPortInput(nameof(actionData), typeof(object))]
protected void PullInputs(List connectedEdges)
{
if (actionData == null) actionData = new Dictionary();
foreach (SerializableEdge t in connectedEdges)
{
actionData.Add(t.inputPortIdentifier, t.passThroughBuffer);
}
}
[CustomPortBehavior(nameof(actionData))]
protected IEnumerable ActionDataBehaviour(List edges)
{
foreach (var field in GetInputFieldsOfType())
{
yield return new PortData
{
displayName = field.inputAttribute.name,
displayType = field.fieldInfo.FieldType,
identifier = field.fieldInfo.Name,
acceptMultipleEdges = false,
};
}
}
public override IEnumerable OverrideFieldOrder(IEnumerable 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;
}
}
```
So I have a couple layers of inheritance first. It looks like this: BaseNode > DynamicNode > SequenceNode
In Dynamic node I'm creating ports on the fly with CustomPortBehavior and CustomPortInput. Everything works how you would expect except I'd prefer if the ports were reordered so I did by implementing the OverrideFieldOrder method. Essentially all I'm doing is reversing the original order. i.e.
return base.OverrideFieldOrder(fields).Reverse();
.Also for some reason the property drawer for a float in DynamicNode is in the wrong place by default.
The order is reversed correctly but when creating a connection node in the menu it doesn't pickup up the correct type. Before (Dragging&Dropping an edge): After (Dragging&Dropping an edge):
The float itself does work before and after so I think it could be some kind of generic inheritance thing.
Code For DynamicNode:
DynamicNode Code
```c# 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