Workflow: Reading and Writing Facts
With your UFactsComponent
set up on an Actor, you can now interact with its data from any Blueprint. This is done primarily through two type-safe nodes: Get Fact by Tag and Update Fact by Tag.
The Key to Type Safety: The Details Panel
Before we use the nodes, it's essential to understand what makes them powerful. The "Value" pin on these nodes dynamically changes its type based on the Fact you select in the Details panel.
- Place a Get Fact by Tag or Update Fact by Tag node in your graph.
- Select the node.
- In the Details panel, you will see "Fact Node Configuration".
- First, set the Schema For Type Resolution.
- Then, set the Fact To Access.
As soon as you select a Fact, the Value pin on the node will automatically update to the correct data type (e.g., a integer pin, a float pin, a struct pin). This prevents type-mismatch errors and eliminates the need for manual casting.
Reading a Fact's Value
The Get Fact by Tag node is a pure node (no execution pins) used to retrieve the current value of a Fact.
Let's create a simple health display for our player character.
- Open your player character Blueprint.
- In the Event Graph, find a recurring event like
Event Tick
. - Add a Get Fact by Tag node.
- In its Details panel, set:
- Schema For Type Resolution:
Schema.Player
- Fact To Access:
Fact.Player.Stat.Health
- Schema For Type Resolution:
- Get a reference to your
FactsComponent
and from it, get its Context ID. Connect this to theContext ID
input pin on the node. - The
Value
output pin should now be aFloat
. You can connect this to aPrint String
node to display the health on screen.
The node also provides an Operation Result
struct. You can break this struct to check the bSuccess
boolean. This is useful for gracefully handling cases where a Fact might not exist in a given Context.
Writing a Fact's Value
The Update Fact by Tag node is a latent node (with execution pins) used to change the value of a Fact.
Let's create a simple function to apply damage.
- In your player character Blueprint, create a new function called
ApplyDamage
. Give it aFloat
input namedDamageAmount
. - Inside the function, first use a Get Fact by Tag node to read the current
Fact.Player.Stat.Health
. - Subtract the
DamageAmount
from the current health. - Add an Update Fact by Tag node.
- In its Details panel, set:
- Schema For Type Resolution:
Schema.Player
- Fact To Access:
Fact.Player.Stat.Health
- Schema For Type Resolution:
- Connect the execution pins.
- Connect the character's Context ID to the
Context ID
input pin. - Connect the result of your subtraction to the
Value
input pin.
The Update Fact by Tag operation will only succeed if it's executed on a machine that has network authority over the Actor (i.e., the server for a replicated Actor). The Operation Result
will indicate failure if a client attempts to update a replicated fact directly. Always perform updates on the server and let the new value replicate down to clients.
Listening for Changes
While you can check a Fact's value every frame on Tick
, a much more efficient and powerful pattern is to react to changes as they happen. This is done with the Listen For Fact Changes node.
This node is asynchronous. It activates once and then its "On Fact Changed" execution pin will fire every time the specified Fact's value changes, until the listener is explicitly cancelled or the owning object is destroyed.
- In your player character's
Begin Play
event, add a Listen For Fact Changes node. - Configuration:
- In the Details panel, select the
Fact To Access
asFact.Player.Stat.Health
. - Connect the
Context ID
pin.
- In the Details panel, select the
- From the
On Fact Changed
pin, you can trigger UI updates, sound effects, or any other logic that needs to happen when health changes. - The
New Value
output pin provides the updated health value directly.
This event-driven approach is far more performant than polling on Tick
and is the recommended way to build reactive gameplay systems.
Next Up: Creating and Using Queries