Blueprints overview¶
Blueprint is Unreal's visual scripting layer. From a C++ engineer's seat, the rule is simple: you write the foundation in C++ so designers can extend it in Blueprint without you.
For how Rephrased splits work between C++ and Blueprint, see Blueprints in Rephrased.
What Blueprint actually is¶
A Blueprint asset is a UClass derived from a C++ UCLASS. It can:
- Override
BlueprintNativeEventandBlueprintImplementableEventfunctions. - Read/write
UPROPERTYs markedBlueprintReadWrite. - Call
UFUNCTIONs markedBlueprintCallable. - Add new
UPROPERTYs and event graphs of its own.
A Blueprint cannot add private data the C++ side doesn't know about. Anything Blueprint references in C++ must be reflected.
Exposing a class to Blueprint¶
Marker on the UCLASS:
Blueprintable— Blueprints can subclass this.BlueprintType— Blueprints can use this as a variable type or function parameter.
Most actor base classes get both. Classes that exist only as data carriers can use BlueprintType alone.
BlueprintNativeEvent vs BlueprintImplementableEvent¶
Both let Blueprint override C++. They differ in whether C++ provides a default.
// Native: C++ has a default, Blueprint can replace it
UFUNCTION(BlueprintNativeEvent, Category = "Interaction")
void OnInteract(AActor* Player);
virtual void OnInteract_Implementation(AActor* Player);
// Implementable: C++ declares only, Blueprint must implement
UFUNCTION(BlueprintImplementableEvent, Category = "Behavior")
void OnBegin(const FRuneRuleEvent& RuleEvent);
Use Native for behavior that has a sensible default; use Implementable for hooks intended for designers (no C++ side at all).
The C++ caller still calls the wrapper:
That dispatches to the Blueprint override if the BP has one, otherwise _Implementation. Do not call _Implementation directly from outside — you bypass the Blueprint.
Calling C++ from Blueprint¶
Mark the function BlueprintCallable (with side effects) or BlueprintPure (no side effects, used as a getter):
UFUNCTION(BlueprintCallable, Category = "Rune")
void SetStatus(const FGameplayTagContainer& NewStatus);
UFUNCTION(BlueprintPure, Category = "Rune")
bool HasStatus(FGameplayTag Tag) const;
BlueprintPure shows up as a value node with no exec pin — wire it as input to other nodes.
Reading C++ data from Blueprint¶
UPROPERTY specifiers control this:
BlueprintReadWrite— Blueprint can read and assign.BlueprintReadOnly— Blueprint can read only.- (no specifier) — invisible to Blueprint.
Pair with EditAnywhere / EditDefaultsOnly / etc. for the editor-side visibility. They are independent: a property can be EditAnywhere, BlueprintReadOnly (designer can configure it, BP graph can only read it).
Delegates Blueprint can bind to¶
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FRunePendingChanged, URuneDataAsset*, Rune, UObject*, Source);
UPROPERTY(BlueprintAssignable, Category = "Rune|Events")
FRunePendingChanged OnPendingChanged;
DYNAMIC and BlueprintAssignable together make a Blueprint-bindable event. Designers see "On Pending Changed" in the event list and can drop nodes onto it.
What Blueprints should not do¶
- Hold the only reference to a tick-critical loop. C++ should drive things that run every frame.
- Reach into private state. If a designer needs something, expose it with the right specifier.
Change history¶
- 2026-09-29 — Gabriel Li — Native and implementable event examples use current interaction and puzzle behavior hooks (CORE-009).
- 2026-09-17 — Gabriel Li — Blueprint exposure examples now use verb effects, runeable-object status, puzzle actor hooks, and coordinator events.
- 2026-05-23 — Gabriel Li — Split generic Blueprint material from Rephrased project track.
- 2026-05-08 — Gabriel Li — Added baseline change history section for weekly wiki maintenance.