Hi everybody, I would like to customize how a field of a specific type is drawn inside a unit, in the flow diagram, using something like PropertyDrawers, as I do for Inspector fields. Is this possible?
I’m not sure how much “customization” you are looking for.
Currently you can use the attribute:
[UnitHeaderInspectable]
This will display the a type field in the upper portion of the unit/node within the graph. If you need further customization from that, you may want to look into the attribute within the unity visual scripting package to determine how to adjust it further. I would assume that any changes at that level may quickly run into compatibility conflicts in future updates.
The preview of 1.8 with high performance interpreter has been pulled from public access. Unity seem to have refocused on the next iteration of Visual Scripting for Unity 2023. And at that point, it’ll have a completely different runtime API for the high performance interpreter and completely different API for the GUI as well since they’re migrating from current IMGUI to Graph Tools Foundation which is UI Toolkit based. So anything in production with UVS 1.7.x will likely remain 1.7 based until the end of the product’s life cycle.
Thank you for the suggestion but that’s not what I’m looking for. I would like, for example, to be able to put a custom button next to a ValueInput.
[Widget(typeof(ValueInput))]
public class CustomValueInput : ValueInputWidget
{
public CustomValueInput(FlowCanvas canvas, ValueInput port) : base(canvas, port)
{
}
public override void DrawForeground()
{
if(port.type == typeof(LocalizationKey))
{
base.DrawForeground();
Rect localizationButton = new Rect(position.position + new Vector2(position.width, 0.0f), new Vector2(position.height, position.height));
if(GUI.Button(localizationButton, "L"))
{
}
}
else
{
base.DrawForeground();
}
}
}
It’s not possible to inherit from ValueInput so I can’t use a derived type in the Widget attribute.
The Rect of the entire row is available through the position property. There are other positions like iconPosition, handlePosition, inspectorPosition… for each part of the row.
You can also replace whatever you need by overriding DrawForeground:
[Widget(typeof(SaySequenceNode))]
public class CustomNodeWidget : UnitWidget<SaySequenceNode>
{
public CustomNodeWidget(FlowCanvas canvas, SaySequenceNode unit) : base(canvas, unit)
{
}
public override void DrawForeground()
{
// Extracted from assembly
this.BeginDim();
base.DrawForeground();
this.DrawIcon();
if (this.showSurtitle)
this.DrawSurtitle();
if (this.showTitle)
this.DrawTitle();
if (this.showSubtitle)
this.DrawSubtitle();
if (this.showIcons)
this.DrawIcons();
//if (this.showSettings) Commented out because it is private in the base class
// this.DrawSettings();
if (this.showHeaderAddon)
this.DrawHeaderAddon();
if (this.showPorts)
this.DrawPortsBackground();
this.EndDim();
}
}
The only thing that comes to my mind is using the DrawHeaderAddon method and draw an empty label that has a fixed width and zero height, at the position of the icon. That will make the entire unit wider.
In this example, there are spawner objects in the scene that spawn “entities” (other scene objects). The node subscribes to the EntitySpawned event of the spawner and triggers the event in the flow graph when it happens, returning the just spawned entity.
I found this by digging into the disassembled code of Bolt and I think everything I have overridden is necessary.
BTW the spawner object is passed to the graph via Variables in the object that contains the FlowMachine component.
This must appear in the Definition method (if it has a control input and control output), otherwise the nodes that are connected to the output will look grayed in the graph window.