During development, console commands can be very helpful by allowing a developer or tester to easily bypass content, or disable the mechanics not relevant to the current test being run. The most common way to implement this is via console commands, which can invoke functions during runtime. The console can be accessed using the tilde key (~
) or the equivalent in the upper-left area of the alphanumeric zone of your keyboard.
If you haven't already followed the Creating a new editor module recipe, do so, as this recipe will need a place to initialize and register the console command.
IConsoleCommand* DisplayTestCommand; IConsoleCommand* DisplayUserSpecifiedWindow;
StartupModule
:DisplayTestCommand = IConsoleManager::Get().RegisterConsoleCommand(TEXT("DisplayTestCommandWindow"), TEXT("test"), FConsoleCommandDelegate::CreateRaw(this, &FUE4CookbookEditorModule::DisplayWindow, FString(TEXT("Test Command Window"))), ECVF_Default); DisplayUserSpecifiedWindow= IConsoleManager::Get().RegisterConsoleCommand(TEXT("DisplayWindow"), TEXT("test"), FConsoleCommandWithArgsDelegate::CreateLambda( [&](const TArray< FString >& Args) { FString WindowTitle; for (FString Arg : Args) { WindowTitle +=Arg; WindowTitle.AppendChar(' '); } this->DisplayWindow(WindowTitle); } ), ECVF_Default);
ShutdownModule
, add this:If (DisplayTestCommand) { IConsoleManager::Get().UnregisterConsoleObject(DisplayTestCommand); DisplayTestCommand = nullptr; } If (DisplayUserSpecifiedWindow) { IConsoleManager::Get().UnregisterConsoleObject(DisplayTestCommand); DisplayTestCommand = nullptr; }
void DisplayWindow(FString WindowTitle) { TSharedRef<SWindow> CookbookWindow = SNew(SWindow) .Title(FText::FromString(WindowTitle)) .ClientSize(FVector2D(800, 400)) .SupportsMaximize(false) .SupportsMinimize(false); IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame")); if (MainFrameModule.GetParentWindow().IsValid()) { FSlateApplication::Get().AddWindowAsNativeChild(CookbookWindow, MainFrameModule.GetParentWindow().ToSharedRef()); } else { FSlateApplication::Get().AddWindow(CookbookWindow); } }
DisplayTestCommandWindow,
and hit Enter.StartupModule
method.IConsoleManager
is the module that contains the console functionality for the engine.IConsoleManager
that is being used by the engine. To do so, we invoke the static Get
function, which returns a reference to the module in a similar way to a singleton.RegisterConsoleCommand
is the function that we can use to add a new console command, and make it available in the console:virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandDelegate& Command, uint32 Flags);
Name
: The actual console command that will be typed by users. It should not include spaces.Help:
The tooltip that appears when users are looking at the command in the console. If your console command takes arguments, this is a good place to display usage information to users.Command:
This is the actual function delegate that will be executed when the user types the command.Flags:
These flags control visibility of the command in a shipping build, and are also used for console variables. ECVF_Default
specifies the default behavior wherein the command is visible, and has no restrictions on availability in a release build.CreateRaw
static function on the FConsoleCommand
delegate type. This lets us bind a raw C++ function to the delegate. The extra argument that is supplied after the function reference, the FString
"Test Command Window"
, is a compile-time defined parameter that is passed to the delegate so that the end user doesn't have to specify the window name.DisplayUserSpecifiedWindow
, is one that demonstrates the use of arguments with console commands.FConsoleCommandWithArgsDelegate
and the CreateLambda
function on it in particular.FConsoleCommandWithArgsDelegate
specifies that the function should take a const TArray
of FStrings. Our DisplayWindow
function takes a single FString
to specify the window title, so we need to somehow concatenate all the arguments of the console command into a single FString
to use as our window title.FString
onto the actual DisplayWindow
function.[&](const TArray<FString>& Args)
, specifies that this lambda or anonymous function wants to capture the context of the declaring function by reference by including the ampersand in the capture options [&]
.const Tarray
containing FStrings as a parameter called Args
.FString,
and concatenate the strings that make up our arguments together, adding a space between them to separate them so that we don't get a title without spaces.for
loop for brevity to loop over them all and perform the concatenation.this
pointer (captured by the &
operator mentioned earlier) to invoke DisplayWindow
with our new title.IConsoleCommand*
, called DisplayTestCommand
. When we execute the RegisterConsoleCommand
function, it returns a pointer to the console command object that we can use as a handle later.ShutdownModule
, we check to see if DisplayTestCommand
refers to a valid console command object. If it does, we get a reference to the IConsoleManager
object, and call UnregisterConsoleCommand
passing in the pointer that we stored earlier in our call to RegisterConsoleCommand
.UnregisterConsoleCommand
deletes the IConsoleCommand
instance via the passed-in pointer, so we don't need to deallocate
the memory ourselves, just reset DisplayTestCommand
to nullptr
so we can be sure the old pointer doesn't dangle.DisplayWindow
function takes in the window title as an FString
parameter. This allows us to either use a console command that takes arguments to specify the title, or a console command that uses payload parameters to hard-code the title for other commands.SNew()
to allocate and create an SWindow
object.SWindow
is a Slate Window, a top-level window using the Slate UI framework.Builder
design pattern to allow for easy configuration of the new window.Title
, ClientSize
, SupportsMaximize
, and SupportsMinimize
functions used here, are all member functions of SWindow
, and they return a reference to an SWindow
(usually, the same object that the method was invoked on, but sometimes, a new object constructed with the new configuration).DisplayWindow
create a new top-level Window that has a title based on the function parameter. It is 800x400 pixels wide, and cannot be maximized or minimized. AddWindowAsNativeChild
to insert our window in the hierarchy.AddWindow,
and pass in our new window instance.3.145.64.126