Unreal ImGui_WS plugin provides the ability to display debugging information from the unreal engine on remote web pages and also supports packaged games. (e.g. standalone DS processes can use this debugger to preview in-game data visually)
- ImGui webpage drawing
- Local Slate panel rendering
- UMG support
- ImGui blueprint nodes (automatic scope management)
- Unreal world debugger
- Top view of the unreal world
- Details panel
- World outline view
- Logging and console features
- Panel layout system
- ImPlot data visualization library
- C++ RAII API
Select ImGui_WS on the ImGui webpage and check ImGuiDemo to open the Demo panel For code viewing ImGuiDemo.cpp, refer to the widget drawing method required for copying the Demo panel imgui_manual demo web version
imgui_manual demo web version
Click the ImGui button in the lower right corner to open the corresponding webpage, or enter ImGui.WS.LaunchWeb in the console to open the webpage
ImGui_WS drawing is only enabled by default under the editor and the packaged DS or client adds ExecCmds="ImGui.WS.Enable 1" in the startup parameters to enable drawing
The previewed world can be selected through the world context option under the ImGui_WS menu
You can set the port number through Config or the command line
-
Port number can be configured in ProjectSettings - Plugins - ImGui_WS
-
File configured in ImGui_WS.ini
[/Script/ImGui_WS.ImGui_WS_Settings]
GamePort=8890
ServerPort=8891
EditorPort=8892 -
Startup parameter configuration -ExecCmds="ImGui.WS.Port 8890"
- Gets ImGuiContext by calling UImGui_WS_Manager::GetImGuiContext
- Function OnDraw draws the invoked event for the ImGui_WS drawing
- Bind this event to call ImGui to draw a specific panel
- UnrealImGui::FImGuiTextureHandle create texture handle
- Call UnrealImGui::UpdateTextureData update texture data
- Call ImGui::Image draw the texture
static UnrealImGui::FImGuiTextureHandle TextureHandle = []
{
UTexture2D* Texture2D = LoadObject<UTexture2D>(nullptr, TEXT("/Engine/EditorResources/S_Actor"));
// step 1
const UnrealImGui::FImGuiTextureHandle Handle{ Texture2D };
// step 2
UnrealImGui::UpdateTextureData(Handle, UnrealImGui::ETextureFormat::RGB8, Texture2D);
return Handle;
}();
// step 3
ImGui::Image(TextureHandle, ImVec2{ 256.f, 256.f });
Console variable ImGui.WS.LocalPanelMode <ELocalPanelMode>
sets the local panel mode
- 0: Draw on the current game viewport
- 1: Open a separate window for rendering (desktop platforms only)
- 2: Open a mergeable window for rendering (editor only)
Console commands
ImGui.WS.OpenPanel
opens the local panelImGui.WS.ClosePanel
closes the local panel
Added ImGuiPanel
widget, expose the widget as a variable (Is Variable) and bind the OnImGuiTick
drawing event
Encapsulates most ImGui drawing functions for use in blueprints, and nodes automatically manage scope, no need to manually control Begin and End call pairing
World Debugger is the default runtime unreal world debugger provided by this plugin, which provides the function of previewing and setting Actor properties in the game world
You can configure the console variable ImGui.DebugGameWorld to control whether the debug panel is enabled. If you need to turn off this function when enabled by default, you can set ImGuiWorldDebuggerBootstrap:: bLaunchImGuiWorldDebugger = false in the game module StartupModule.
To avoid displaying too many unrelated Actors, the default preview will only display Actors drawn that inherit the UImGuiWorldDebuggerDrawerBase declaration.
After entering type:ClassPath in the FilterActor search box, only the Actor of the current type will be displayed in the map
Create a type that inherits from UImGuiWorldDebuggerDrawerBase
- Add constructor
UShootWeaponBulletDrawer::UShootWeaponBulletDrawer()
{
// Declare the Actor types supported by the Drawer
DrawActor = AShootWeaponBullet::StaticClass();
// Drawn solid radius
Radius = 10.f;
// Painted color
Color = FLinearColor::Red;
}
- Rewrite functions such as DrawImGuiDebuggerExtendInfo to add extra debugging information drawing
void UShootWeaponBulletDrawer::DrawImGuiDebuggerExtendInfo(const AActor* Actor, const FImGuiWorldViewportContext& DebuggerContext) const
{
const AShootWeaponBullet* Bullet = CastChecked<AShootWeaponBullet>(Actor);
const FVector EndLocation = Bullet->GetActorLocation();
const FVector StartLocation = EndLocation - Actor->GetVelocity() * DebuggerContext.DeltaSeconds;
DebuggerContext.DrawLine(FVector2D{ StartLocation }, FVector2D{ EndLocation }, Color);
}
Inherit UImGuiWorldDebuggerViewportPanel and rewrite the following virtual functions
- DrawDebugInfoUnderActors draws extra debugging information on the lower layer of Actors
- DrawDebugInfoUpperActors draws extra debugging information on the upper layer of Actors
It is recommended to add a switch to debug information for each world to avoid displaying too many elements in the debugging world at the same time
// declare switch
UPROPERTY(Config)
uint8 bExampleToggle : 1;
// Add the menu option of whether to enable the switch in the implementation
if (ImGui::BeginMenu("Example Menu"))
{
{
bool Value = bExampleToggle;
if (ImGui::Checkbox("Example Toggle", &Value))
{
bShowGlobalLifeTime = Value;
DebuggerContext.MarkConfigDirty();
}
}
ImGui::EndMenu();
}
// The switch is judged in the logic, and the debug information is drawn when it is turned on.
All properties of the incoming UObject instance can be drawn, and multi-select editing is supported
For usage, please refer to UImGuiWorldDebuggerDetailsPanel::Draw
See how FStructCustomizerScoped is used
- Inherit UImGuiWorldDebuggerPanelBase to add a new panel to ImGuiWorldDebugger
- Inherit UImGuiWorldDebuggerLayoutBase to add layout description to ImGuiWorldDebugger
UUnrealImGuiPanelBuilder is used to build the layout of its window, and the following parameters need to be configured
property | describe |
---|---|
DockSpaceName | the name of the layout system |
After configuring the description information of the layout system, call the following methods to draw the panel
method | describe |
---|---|
Register | Register the layout system and call it when it is created |
Unregister | Unregister the layout system and call it when it is destroyed |
DrawPanels | Draw the panels under the layout system |
LoadDefaultLayout | Reload the activated layout |
Inherit the layout base class types supported under UUnrealImGuiPanelBuilder. For example, ImGuiWorldDebugger extended layout inherits UImGuiWorldDebuggerLayoutBase
- Configure LayoutName. Unnamed layouts will not be displayed
- implement LoadDefaultLayout to declare the default layout structure
- implement ShouldCreateLayout to declare support owner
The default layout divides the viewport into four areas
UCLASS()
class UImGuiWorldDebuggerDefaultLayout : public UImGuiWorldDebuggerLayoutBase
{
GENERATED_BODY()
public:
// Declare the DockId as the configuration when the panel registers the Dock
enum EDockId
{
Viewport,
Outliner,
Details,
Utils,
};
UImGuiWorldDebuggerDefaultLayout();
void LoadDefaultLayout(UObject* Owner, const UUnrealImGuiPanelBuilder& LayoutBuilder) override;
};
UImGuiWorldDebuggerDefaultLayout::UImGuiWorldDebuggerDefaultLayout()
{
// Set layout name
LayoutName = TEXT("Default");
}
void UImGuiWorldDebuggerDefaultLayout::LoadDefaultLayout(UObject* Owner, const UUnrealImGuiPanelBuilder& LayoutBuilder)
{
const ImGuiID DockId = ImGui::DockBuilderAddNode(DockSpaceId, ImGuiDockNodeFlags_None);
// Call DockBuilderSplitNode to divide the layout
ImGuiID RemainAreaId;
ImGuiID ViewportId = ImGui::DockBuilderSplitNode(DockSpaceId, ImGuiDir_Left, 0.7f, nullptr, &RemainAreaId);
const ImGuiID UtilsId = ImGui::DockBuilderSplitNode(ViewportId, ImGuiDir_Down, 0.3f, nullptr, &ViewportId);
const ImGuiID OutlinerId = ImGui::DockBuilderSplitNode(RemainAreaId, ImGuiDir_Up, 0.3f, nullptr, &RemainAreaId);
const ImGuiID DetailsId = ImGui::DockBuilderSplitNode(RemainAreaId, ImGuiDir_Down, 0.7f, nullptr, &RemainAreaId);
// Add a mapping relationship between the declared DockId and the actual ID of ImGui
const TMap<int32, ImGuiID> DockIdMap
{
{ Viewport, ViewportId },
{ Outliner, OutlinerId },
{ Details, DetailsId },
{ Utils, UtilsId },
};
// Subpanel application layout information
ApplyPanelDockSettings(LayoutBuilder, DockIdMap, EDockId::Utils);
ImGui::DockBuilderFinish(DockId);
}
Inherit the panel base class types supported under UUnrealImGuiPanelBuilder. For example, the ImGuiWorldDebugger extended panel inherits UImGuiWorldDebuggerPanelBase
- Configure Title. Unnamed panels will not be registered
- Configure DefaultDockSpace to add the position of the panel in the layout
- Implement Draw to realize panel drawing
- Implement ShouldCreatePanel to declare support owner (Optional)
UImGuiWorldDebuggerViewportPanel::UImGuiWorldDebuggerViewportPanel()
{
// Declares that the menu bar needs to be displayed
ImGuiWindowFlags = ImGuiWindowFlags_MenuBar;
// Set panel name
Title = TEXT("Viewport");
// The default position in the ImGuiWorldDebuggerDefaultLayout layout is Viewport
DefaultDockSpace =
{
{ UImGuiWorldDebuggerDefaultLayout::StaticClass()->GetFName(), UImGuiWorldDebuggerDefaultLayout::EDockId::Viewport }
};
}
Blueprint created panel need add in
Project Settings - ImGui WS - Blueprint Panels
- Inherit UUnrealImGuiViewportBase to declare viewport panel
- Inherit UUnrealImGuiViewportExtentBase to declare viewport extent draw
- Implement DrawViewportMenu draw menu
- Implement DrawViewportContent draw viewport content element
- Implement ShouldCreateExtent to declare support viewport type (optional)
Menu Tools - ImGui Panels
can open single ImGui Panel
Call ImGui::InsertNotification to use the global bubbling message prompt
Start recording:
- Menu->ImGui_WS->Start Record
- Console input ImGui.WS.StartRecord
To end recording:
- Menu->ImGui_WS->Stop Record
- Console input ImGui.WS.StopRecord
Menu->ImGui_WS->Load Record, select the recorded file for review
Encapsulates ImGui API to support automatic scope management, include ImGuiEx.h header file to use the scope interface
// RAII style, no need for developers to worry about ImGui::End call
if (ImGui::FWindow Window{ "WindowName" })
{
ImGui::Text("Content");
}
// Equivalent ImGui default API, need to manage ImGui::End call
if (ImGui::Begin("WindowName"))
{
ImGui::Text("Content");
}
// Cannot be omitted, otherwise rendering will be incorrect
ImGui::End();