Skip to content

UI Widgets Without Event Graphs

The current UI rule is:

Widget Blueprint = layout
C++ widget class = behavior and data flow

The goal is not to avoid Blueprints entirely. The goal is to avoid maintained gameplay logic living in Widget Event Graphs.

The important widget classes are:

UAndromedaInteractPromptWidget
UAndromedaScannerScreenWidget
UAndromedaSuitScanRecallWidget

BindWidgetOptional

Widget C++ classes use properties such as:

UPROPERTY(BlueprintReadOnly, meta=(BindWidgetOptional), Category="Andromeda|UI")
TObjectPtr<UTextBlock> ItemNameText;

BindWidgetOptional means:

If the Widget Blueprint has a Designer widget named ItemNameText
and it has a compatible type,
bind it to this C++ property.

If it does not exist,
do not fail construction.

This is useful during early UI iteration. The code can tolerate missing fields while the layout evolves.

The tradeoff is that a typo silently gives nullptr, so important widgets should be verified during testing.

Interact Prompt Widget

The prompt widget owns:

focused object reference
current prompt text
prompt visibility
text block update

The character calls:

InteractPromptWidget->SetPrompt(PromptText);

or:

InteractPromptWidget->ClearPrompt();

The Widget Blueprint only needs the layout and correctly named widgets.

Scanner Screen Widget

The scanner screen widget is informational only.

It owns:

idle / item ready / error state
FAndromedaScanResult
text population

It does not own:

final sale/quarantine actions
package assignment
cargo/consequence processing
interaction intent

Those are outside the current placement foundation. The scanner screen presents scan data; workstation gameplay and later cargo/consequence flow belong elsewhere.

Expected Designer bindings include:

StatusText
ItemNameText
ManifestText
LegalRequirementText
RadiationText
MassText
SerialText
HazardText
PackageRequirementText
NotesText

When ShowScanResult is called, the widget stores the struct and refreshes all text fields. ShowIdle, ShowItemReady, and ShowError update the status text without changing global input mode.

The physical workstation ScreenComponent is the traceable screen-operation surface, but it is not the UMG widget. It forwards screen-use calls to the owning workstation actor; the Widget Blueprint remains presentation-only. Item placement is handled by freeform placement, and pickup is routed by the character/carry path through the salvage item's pickup capability.

Suit Scan Recall Widget

The suit scan recall widget is a non-modal helmet overlay.

It owns:

visibility
current station scan record list
empty/unavailable state text
text population

It does not own:

station access detection
station databank storage
scan creation
input mode changes
mouse cursor state

Expected Designer bindings include:

RecallRoot
StatusText
RecordsText

AAndromedaHUD creates the widget from HUD defaults, toggles it when the character broadcasts OnScanRecallRequested, and queries the currently connected station databank. The widget is passive and should not need Event Graph logic.

Why No Event Graphs

There is nothing wrong with Blueprints for presentation and configuration. The current project preference is that maintained rules live in C++ so the logic is reviewable, searchable, diffable, and easier to refactor.

Blueprints still matter:

BP_PlayerCharacter assigns input action references.
HUD defaults assign suit HUD widget class references.
BP_ScannerWorkstation assigns mesh assets, placement volume transforms, and inherited ScreenComponent widget/screen-interaction settings.
BP_Station tunes the inherited station databank and StationAccess sphere components.
WBP_ScannerScreen defines layout.
WBP_SuitScanRecall defines layout.
Data Assets define item content.

The split is not "C++ good, Blueprint bad." The split is:

C++ owns rules.
Blueprints own authored configuration and presentation.