UBlueprintCheatScript (C++)
The C++ surface of the cheat base class — properties, virtuals, and authoring patterns for pure-C++ vs hybrid BP+C++ cheats.
UBlueprintCheatScript is the base class every cheat inherits from.
This page covers the C++ surface — properties, virtuals, and the
recommended subclassing pattern.
- Header:
Source/BlueprintCheats/Public/BlueprintCheatScript.h - Module:
BlueprintCheats(Runtime)
UCLASS(Abstract, Blueprintable, BlueprintType)
class BLUEPRINTCHEATS_API UBlueprintCheatScript : public UObject;A script is a stateless template, not a singleton. The
UBlueprintCheatsSubsystem
creates one instance per enabled class on OnWorldMatchStarting and
reuses it for menu, console, and hotkey invocations within the level.
Authoring properties (protected)
UPROPERTY(Instanced, EditDefaultsOnly, BlueprintReadOnly)
TMap<FName, UBlueprintCheatArgument*> NamedExpectedArguments;
UPROPERTY(EditDefaultsOnly) FText ScriptDisplayName;
UPROPERTY(EditDefaultsOnly) FText HelpDescription;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) FString ConsoleCommand;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) TSubclassOf<UBlueprintCheatScriptMenuItemBase> WidgetClass;
UPROPERTY(EditDefaultsOnly) uint8 DisplayOrderPriority = 0;
UPROPERTY(EditDefaultsOnly) TObjectPtr<UInputAction> InputAction;
UPROPERTY(EditDefaultsOnly) bool bAddToMenu = true;
UPROPERTY(EditDefaultsOnly) bool bAddConsoleCommand = false;
UPROPERTY(EditDefaultsOnly) bool bContinueExecutingWithOngoingKeyPress = true;| Property | Purpose |
|---|---|
NamedExpectedArguments | The cheat's argument list, keyed by argument name. See CheatArguments. |
ScriptDisplayName | Override name shown in the menu. Falls back to the class name when empty. |
HelpDescription | Used as both the menu tooltip and the console-command help string. |
ConsoleCommand | The console command. Falls back to display name then class name. The project-wide prefix is prepended at registration time. |
WidgetClass | The UMG row used in the menu. Defaults to WBP_BlueprintsCheats_MenuItem. |
DisplayOrderPriority | Menu sort order. 0 is highest priority. |
InputAction | Optional Enhanced Input action that fires the cheat directly. |
bAddToMenu | If true, the cheat appears in the overlay menu. |
bAddConsoleCommand | If true, the cheat registers a console command. |
bContinueExecutingWithOngoingKeyPress | If true, hotkey re-fires Execute on ETriggerEvent::Ongoing while the key is held. |
The properties are protected, so a C++ subclass can read/write them
directly but external code cannot. The recommended pattern for setting
them is to author the cheat as a Blueprint subclass of your C++
base — the BP class can edit any EditDefaultsOnly property in the
Class Defaults panel. See Authoring patterns.
Public read-only API
FString GetConsoleCommand() const;
FText GetHelpDescription() const;
FText GetScriptDisplayName() const; // BlueprintNativeEvent
uint8 GetDisplayOrderPriority() const;
TMap<FName, UBlueprintCheatArgument*> GetExpectedArguments() const;
TObjectPtr<UInputAction> GetInputAction(); // virtual
bool ShouldAddToMenu() const;
bool ShouldAddConsoleCommand() const;
bool ContinueExecutingWithOngoingKeyPress() const;GetWorld() is overridden to follow the outer chain, with the
standard CDO guard.
Lifecycle and overrides
OnEnabled
UFUNCTION(BlueprintNativeEvent)
void OnEnabled();Called once when the subsystem enables the cheat (typically on world match start). Per-level setup tied to the cheat itself.
CanExecute
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
bool CanExecute(APlayerController* ExecutingPlayerController, FText& OutputMessage) const;Gates execution. Default returns true. Return false (and set
OutputMessage) to refuse — useful for cheats that require a pawn,
authority, or specific game state. Called from all three trigger
sources before Execute.
Execute (BP event)
UFUNCTION(BlueprintImplementableEvent)
bool Execute(APlayerController* ExecutingPlayerController,
const TMap<FName, UBlueprintCheatArgument*>& CheatArguments,
FText& OutcomeMessage) const;The cheat body. Implemented as a BlueprintImplementableEvent because
it needs the per-call argument map. To implement it from C++ you have
two options:
- Make the leaf cheat class a Blueprint subclass of your C++ base,
and implement
Executethere. - Override
Execute(APlayerController*, FText&) const(the parameterless C++ overload, see below) in C++ and ignore the BP event.
Execute (C++ overload)
virtual bool Execute(APlayerController* ExecutingPlayerController, FText& OutcomeMessage) const;Convenience overload. Default implementation calls the BP event with
NamedExpectedArguments. The subsystem invokes this overload from the
menu path. Override in C++ when you don't want a BP cheat body.
TryToParseStringArguments
UFUNCTION(BlueprintNativeEvent)
bool TryToParseStringArguments(const TArray<FString>& StringArguments,
TMap<FName, UBlueprintCheatArgument*>& CheatArgumentsOut,
FText& OutcomeMessage) const;Default implementation:
- Sorts
NamedExpectedArgumentsbyPosition. - Walks tokens left-to-right calling
ParseStringon each matched argument. - For missing tokens: tries
UseDefault(). If a default is configured, fills the argument and continues. Otherwise, if the argument isbOptional, parsing stops and returns success. Otherwise it fails. - On any
ParseStringfailure, populatesOutcomeMessageand returnsfalse.
Override only for non-positional parsing (e.g. --name value).
ExecuteRawArguments
UFUNCTION(BlueprintNativeEvent)
bool ExecuteRawArguments(APlayerController* ExecutingPlayerController,
const TArray<FString>& RawArguments,
FText& OutcomeMessage) const;Console / hotkey entry point. Default: parse via
TryToParseStringArguments then dispatch to the BP Execute event
with the parsed map. Override to skip parsing entirely (e.g. for
cheats that want raw tokens).
BuildWidget
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
UBlueprintCheatScriptMenuItemBase* BuildWidget(UBlueprintCheatsMenuWidgetBase* OwnerMenu) const;Default: NewObject of WidgetClass. Override when one cheat needs
special construction logic.
ResetState
UFUNCTION(BlueprintCallable)
virtual void ResetState() const;Called by the subsystem after a menu-driven execution. Walks
NamedExpectedArguments and clears each argument's value. Override
(and call Super::ResetState) if your cheat caches additional
transient state.
Editor data validation
#if WITH_EDITOR
virtual EDataValidationResult IsDataValid(class FDataValidationContext& Context) const override;
#endifCalled during editor data validation. The default implementation
validates the configured arguments — see BlueprintCheatScript.cpp.
Authoring patterns
1. Blueprint subclass of a C++ base (recommended)
// MyCheat_Base.h
UCLASS(Abstract)
class MYGAME_API UMyCheat_Base : public UBlueprintCheatScript
{
GENERATED_BODY()
public:
UMyCheat_Base();
protected:
virtual bool Execute(APlayerController* Controller, FText& OutcomeMessage) const override;
};// MyCheat_Base.cpp
UMyCheat_Base::UMyCheat_Base()
{
bAddConsoleCommand = true;
}
bool UMyCheat_Base::Execute(APlayerController* Controller, FText& OutcomeMessage) const
{
// your logic, reading from GetExpectedArguments()
return true;
}Then make BPCheat_* a Blueprint subclass of UMyCheat_Base. The
Blueprint asset edits ScriptDisplayName, ConsoleCommand,
HelpDescription, NamedExpectedArguments, etc. via the Class
Defaults panel — you keep BP authoring ergonomics for configuration
and use C++ for logic.
2. Pure C++ leaf class
If you want a fully code-only cheat, override the parameterless
Execute overload and configure properties from the constructor:
UCLASS()
class MYGAME_API UMyCheat_Pure : public UBlueprintCheatScript
{
GENERATED_BODY()
public:
UMyCheat_Pure()
{
ScriptDisplayName = INVTEXT("Pure C++ Cheat");
ConsoleCommand = TEXT("PureCheat");
bAddConsoleCommand = true;
}
protected:
virtual bool Execute(APlayerController* Controller, FText& OutcomeMessage) const override
{
OutcomeMessage = INVTEXT("Did the thing");
return true;
}
};Adding arguments from a pure C++ leaf is awkward because the argument
subclasses' configuration fields are protected. See
CheatArguments
for two ways to work around that.
Execution flow at a glance
Menu click ──► Subsystem::ExecuteScript
├── CanExecute → if false, log and stop
├── Execute(Controller, OutMsg) // C++ overload
│ └── Execute(Controller, NamedArgs, OutMsg) // BP event
└── ResetState
Console ──► Subsystem::ExecuteScriptFromConsole(rawArgs)
├── CanExecute
└── ExecuteRawArguments
├── TryToParseStringArguments
└── Execute(Controller, ParsedArgs, OutMsg)
Hotkey ──► same as console with empty rawArgs
(every argument must default or be optional)