Select the variable in the node class variables list.
In the details panel, locate the State Machine Variable section.
Set the Direction field to one of the following:
Input
Output
Both
Use the meta specifier LD_PropertyDirection. This can accept:
Input
Output
Both
UPROPERTY(BlueprintReadWrite,Category="Input",meta=(LD_PropertyDirection="Input"))FStringInputStr;UPROPERTY(BlueprintReadWrite,Category="Output",meta=(LD_PropertyDirection="Output"))FStringOutputStr;// Accepts "Input,Output" or "Both"UPROPERTY(BlueprintReadWrite,Category="InputOutput",meta=(LD_PropertyDirection="Input,Output"))FStringInputOutputStr;
Once you place a state node that has at least one variable configured for output, the state machine graph will begin showing connector pins over a node when hovered.
Output Variables Required for Connector Pins
When no output variables are present the graph will not display any connector pins. This is an optimization and UX choice to reduce clutter, since the pins are only needed for output connections.
The connectors will be "compact" versions (just the pin) until you select the property. When you select the property, the connectors will expand to the "full version", where you have more control over the connection.
You can change or clear values, manage multiple outputs, or browse to linked state properties.
Select a pin and drag to an opposite pin. This will look similar to a normal drag and drop operation. When dragging, compatible pins on other states are displayed indicating where you can complete a connection. Drop over a pin to make a connection.
You can click on a property or connector pin (without dragging) to open the full connector display. This will show every available connection, since outputs can connect to more than one variable.
From here you can navigate your state machine, looking for properties to connect to. You can also search for properties.
You can also wire from an input to output, using either drag and drop or manually. You may need to press the add button first if you plan on connecting manually.
Note that this method only works for connecting to state outputs, not back to owning BP variables. You should be using the normal drag and drop routine for connecting owning BP variables to input.
How does outputting to a state property work?
When you output to another state property, this works by creating a proxy variable at runtime, which is effectively a copy of the variable, stored in the owning state machine instance. Then, when a future state reads this variable, it will read the proxy value. This allows you to safely modify the output variable of the state after writing its output, without impacting the value read by other states.
This also keeps behavior consistent with how input properties have always worked, in that they are a copy of the input provided to the state, evaluated once on state begin.
Select a blueprint variable just like you were going to make a connection to an input property, but instead of dropping it directly on the property, select the output connector pin.
Where to Drop Variables
You can also drop these variables on input connector pins as well, and it create a normal blueprint getter to the input property.
You can click on a property or connector pin (without dragging) to open the full connector display, similar to when creating a state connection. Owning blueprint variables are present in the list, along with state input variables.
How does outputting to an owning blueprint property work?
When you output to the owning blueprint, you're writing to that variable at the time of the write. Unlike state to state variables, owning blueprint connections do not use proxies. It wouldn't be practical to do so, as they effectively are a proxy variable already. The proxies state to state use are to help match this behavior.
The local property graph is available for advanced configuration of the property input and all outputs. This is what is represented by the connectors in the owning graph node.
You can access the property graph by double clicking on the property directly, or by right clicking it, and selecting Go to Property Graph.
First, let's explain the graph:
On the left, you have Get State Property Output. This is the state output variable we are reading from.
On the right, we have Set State Property Output. This is what the state is writing to. This special node allows us to select either state variable inputs, or owning state machine variables.
In this example, we are already writing to an owning blueprint variable, String Var.
Notice there are two string wires coming from the output pin. One to the Proxy Variable, and one to the Owning Blueprint Variable.
Now, add a connection to another state variable.
Notice that there is no additional string connection here. That is because this is a state property, and it is using the Proxy Variable input to determine its value.
Add another owning blueprint variable of a different type this time. For this example we will use an integer.
Now there is a third string connection, but this time it is auto casted to an integer type.
This distinction exists because when writing to an owning blueprint variable, the value is immediately applied, so any necessary transformations, such as casting, must be performed at the time of the write.
In contrast, when writing to a state-level output, the value is stored as-is and any modifications (e.g., casting) are deferred until the value is read later.
Why is writing to state variables different from owning BP variables?
Owning blueprint variables already exist outside of the state. When a state starts, it might read the value of the owning blueprint variable, but won't modify it. On exit, it can now write back to that same property. Outside of those separate events, the property value won't change unless you are manually adjusting it.
To achieve the same functionality with state to state variables, we have to create a copy (proxy) of the variable at the state machine level, since it doesn't exist already. We could allow value modification for each proxy at the time of output, but then we would have to create a proxy for each different value or casted type. That is a lot of unecessary overhead, both in memory and processing time, when we can just let the reader perform modifications on property retrieval.