Make a Button Run Blueprint
Receive a selected contract action directly, without name comparisons.
This example connects MainMenu.Exit in package Gameplay to Quit Game.
CalmUI only delivers the request. You decide what the game does with it.
Prepare the button in Studio
- Open Store → Action Contracts. Create group
MainMenu, actionExit, with no payload fields, or use the existing action. - In the button's opening tag, type
/, choose Click → Action Contract, and selectMainMenu.Exit. - Save. Wait for the connected Unreal package to be up to date.
The actual button contains @click="$action('MainMenu.Exit')". A component's
local $emit('click') alone does not send a contract action.
Open the View and listen
In your Level Blueprint, use Get Player Controller, Player Index 0.
Connect Event BeginPlay → Open CalmUI Screen. Select package Gameplay and
Screen MainMenu, and pass the same Player Controller. Connect Failed to
Print String, using Error Message.
From Completed, add Listen for CalmUI Action:
| Input | Value |
|---|---|
| Player Controller | The same controller that opened the View |
| Package | Gameplay Package Asset |
| Action | Select MainMenu.Exit from the list |
| Listener Owner (advanced) | Leave Self; this Blueprint owns the listener's lifetime |
The package must already be loaded. The immediate execution output of Open does not mean loading completed. Listen reports invalid inputs through Failed and Error; connect those to Print String too.
Choose Package directly on the node to populate the Action list. With a connected package variable, connect an Action name variable as well; the editor cannot predict a runtime package's available names.

Connect the response
Connect On Action directly to Quit Game, passing the same Player Controller
as Specific Player. No Equal or Branch is needed: this node receives only
MainMenu.Exit for its selected Local Player.
Create a separate listener for each other action, for example
MainMenu.OpenSettings. Wire its On Action to your settings logic. Register
once, not on every frame or every menu opening, unless you stop the old listener.
Compile and run the level. Clicking Exit should reach Quit Game. Studio Preview
cannot execute the game Blueprint. If nothing happens, print the listener's
Failed/Error first, then check the saved $action binding and package version.
Payload and stopping
The Payload output is an event struct. Split it to read Payload Json, Name,
Action Id, Local Player Id, View Id and Component Instance Id. Payload fields are
validated against the contract. For example, a Continue action with required
string saveId can send:
<button @click="$action('MainMenu.Continue', { saveId: 'slot-1' })">Continue</button>CalmUI does not generate typed pins such as SaveId; read payload fields with the typed Read CalmUI Action * nodes instead.

For a top-level string field, connect Payload to Event on Read CalmUI Action
String and set Field to saveId. Branch on the returned boolean before using
Value. Missing, null, non-string or malformed data returns false and clears Value;
the helper does not convert numbers to text or authorize the requested operation.
The notification example
uses this route for entry and action IDs.
For an integer contract field such as quantity, use Read CalmUI Action Integer
with Field set to quantity. Branch on its boolean output before using Value.
It accepts integral JSON numbers in the shared script-safe range
-9007199254740991 through 9007199254740991. Fractional numbers, numeric strings,
null, missing fields, out-of-range values and malformed JSON return false and
set Value to zero. The output is an Integer64 pin; this is not support for the
entire Integer64 range. Validate positive quantities and game-specific limits
in your own handler. Use Read CalmUI Action Boolean for flags and Read CalmUI
Action Float for finite decimal numbers. All readers address an exact top-level
field, not a nested path.

Save the Listener output if you want to call Stop Listening early. Here, the custom event StopMenuListener feeds a separate Stop Listening node with the saved Listener from MainMenu.OpenSettings. Stopping twice is safe and affects only this listener. Create a new node invocation to listen again. Owner Actor EndPlay (also for an Actor Component owner) and Local Player teardown stop it automatically. Other UObject owners are held weakly; invalid owners, unloaded packages and removed/changed action identities are detected on the next runtime tick or before delivery. Hiding a View alone does not stop the listener.
Compatible reloads keep listening. Changes to the payload contract do not create typed pins automatically; update your payload handling to match the contract.
The advanced Subscribe To CalmUI Action and shared detailed events still work. Do not keep both routes wired to the same response, or it will run twice.