Merge remote-tracking branch 'arnaud-jamin/main'

# Conflicts:
#	.gitignore
#	Plugins/Cog/Source/CogEngine/Public/CogEngineCollisionTester.h
#	Plugins/Cog/Source/ThirdParty/ImGui/imgui_widgets.cpp
This commit is contained in:
ed
2025-05-16 19:24:15 -04:00
238 changed files with 20469 additions and 5755 deletions
+1 -1
View File
@@ -22,7 +22,7 @@
"LoadingPhase": "Default"
},
{
"Name": "CogWindow",
"Name": "Cog",
"Type": "Runtime",
"LoadingPhase": "Default"
},
+2
View File
@@ -1,2 +1,4 @@
[CoreRedirects]
+StructRedirects=(OldName="/Script/CogDebug.CogLogCategory",NewName="/Script/CogCommon.CogLogCategory")
+PropertyRedirects=(OldName="/Script/CogEngine.CogEngineCheatCategory.PersistentEffects",NewName="/Script/CogEngine.CogEngineCheatCategory.PersistentCheats")
+PropertyRedirects=(OldName="/Script/CogEngine.CogEngineCheatCategory.InstantEffects",NewName="/Script/CogEngine.CogEngineCheatCategory.InstantCheats")
@@ -1,8 +1,8 @@
using UnrealBuildTool;
public class CogWindow : ModuleRules
public class Cog : ModuleRules
{
public CogWindow(ReadOnlyTargetRules Target) : base(Target)
public Cog(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
@@ -1,11 +1,11 @@
#include "CogWindowConsoleCommandManager.h"
#include "CogConsoleCommandManager.h"
#include "Engine/World.h"
TMap<FString, FCogCommandInfo> FCogWindowConsoleCommandManager::CommandMap;
TMap<FString, FCogCommandInfo> FCogConsoleCommandManager::CommandMap;
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(const TCHAR* InName, const TCHAR* InHelp, UWorld* InWorld, const FCogWindowConsoleCommandDelegate& InDelegate)
void FCogConsoleCommandManager::RegisterWorldConsoleCommand(const TCHAR* InName, const TCHAR* InHelp, UWorld* InWorld, const FCogWindowConsoleCommandDelegate& InDelegate)
{
FCogCommandInfo& commandInfo = CommandMap.FindOrAdd(InName);
@@ -20,13 +20,15 @@ void FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(const TCHAR* I
{
FCogCommandInfo* commandInfo = CommandMap.Find(InName);
if (commandInfo == nullptr)
{
return;
}
{ return; }
FWorldContext* WorldContext = GEngine->GetWorldContextFromWorld(InCommandWorld);
if (WorldContext == nullptr)
{ return; }
for (auto& receiver : commandInfo->Receivers)
{
if (receiver.World == InCommandWorld)
if (receiver.PIEInstance == WorldContext->PIEInstance)
{
receiver.Delegate.ExecuteIfBound(Args, InCommandWorld);
break;
@@ -37,21 +39,28 @@ void FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(const TCHAR* I
);
}
FCogCommandReceiver& receiver = commandInfo.Receivers.AddDefaulted_GetRef();
receiver.World = InWorld;
receiver.Delegate = InDelegate;
if (const FWorldContext* WorldContext = GEngine->GetWorldContextFromWorld(InWorld))
{
FCogCommandReceiver& receiver = commandInfo.Receivers.AddDefaulted_GetRef();
receiver.PIEInstance = WorldContext->PIEInstance;
receiver.Delegate = InDelegate;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowConsoleCommandManager::UnregisterAllWorldConsoleCommands(const UWorld* InWorld)
void FCogConsoleCommandManager::UnregisterAllWorldConsoleCommands(const UWorld* InWorld)
{
FWorldContext* WorldContext = GEngine->GetWorldContextFromWorld(InWorld);
if (WorldContext == nullptr)
{ return; }
for (auto& kv : CommandMap)
{
FCogCommandInfo& commandInfo = kv.Value;
for (int32 i = commandInfo.Receivers.Num() - 1; i >= 0; --i)
{
if (commandInfo.Receivers[i].World == InWorld)
if (commandInfo.Receivers[i].PIEInstance == WorldContext->PIEInstance)
{
commandInfo.Receivers.RemoveAt(i);
}
@@ -63,4 +72,4 @@ void FCogWindowConsoleCommandManager::UnregisterAllWorldConsoleCommands(const UW
commandInfo.ConsoleObject = nullptr;
}
}
}
}
@@ -1,4 +1,4 @@
#include "CogWindowHelper.h"
#include "CogHelper.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
@@ -7,7 +7,7 @@
#include "imgui.h"
//----------------------------------------------------------------------------------------------------------------------
const UObject* FCogWindowHelper::GetFirstAssetByClass(const TSubclassOf<UObject> AssetClass)
const UObject* FCogHelper::GetFirstAssetByClass(const TSubclassOf<UObject>& AssetClass)
{
const IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")).Get();
@@ -23,7 +23,7 @@ const UObject* FCogWindowHelper::GetFirstAssetByClass(const TSubclassOf<UObject>
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogWindowHelper::GetActorName(const AActor* Actor)
FString FCogHelper::GetActorName(const AActor* Actor)
{
if (Actor == nullptr)
{
@@ -34,7 +34,7 @@ FString FCogWindowHelper::GetActorName(const AActor* Actor)
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogWindowHelper::GetActorName(const AActor& Actor)
FString FCogHelper::GetActorName(const AActor& Actor)
{
#if WITH_EDITOR
@@ -50,7 +50,7 @@ FString FCogWindowHelper::GetActorName(const AActor& Actor)
//-----------------------------------------------------------------------------------------
bool FCogWindowHelper::ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max)
bool FCogHelper::ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max)
{
FVector Corners[8];
Corners[0].Set(-Extent.X, -Extent.Y, -Extent.Z); // - - -
@@ -89,4 +89,12 @@ bool FCogWindowHelper::ComputeBoundingBoxScreenPosition(const APlayerController*
Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y);
return true;
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogHelper::IsTraceChannelHidden(const UCollisionProfile& InCollisionProfile, const ECollisionChannel InCollisionChannel)
{
return false;
}
@@ -1,17 +1,17 @@
#include "CogWindowModule.h"
#include "CogModule.h"
#define LOCTEXT_NAMESPACE "FCogWindowModule"
#define LOCTEXT_NAMESPACE "FCogModule"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowModule::StartupModule()
void FCogModule::StartupModule()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowModule::ShutdownModule()
void FCogModule::ShutdownModule()
{
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCogWindowModule, CogWindow)
IMPLEMENT_MODULE(FCogModule, Cog)
File diff suppressed because it is too large Load Diff
@@ -2,13 +2,27 @@
#include "CogDebug.h"
#include "CogWindow_Settings.h"
#include "CogWindowManager.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "Engine/World.h"
#include "imgui_internal.h"
#include "GameFramework/Pawn.h"
#include "GameFramework/PlayerController.h"
#include "Engine/LocalPlayer.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::Initialize()
{
ensure(bIsInitialized == false);
bIsInitialized = true;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::Shutdown()
{
bIsInitialized = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::SetFullName(const FString& InFullName)
{
@@ -52,59 +66,64 @@ bool FCogWindow::CheckEditorVisibility()
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::RenderMainMenuWidget()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::RenderContextMenu()
{
RenderSettings();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::RenderSettings()
{
if (bHasMenu)
{
ImGui::Checkbox("Show Menu", &bShowMenu);
}
if (ImGui::Button("Reset Settings", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
{
ResetConfig();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::Render(float DeltaTime)
{
ImGuiWindowFlags WindowFlags = 0;
PreRender(WindowFlags);
const FString WindowTitle = GetTitle() + "##" + Name;
if (bHasMenu && bShowMenu)
{
WindowFlags |= ImGuiWindowFlags_MenuBar;
}
if (bNoPadding)
PreBegin(WindowFlags);
const FString WindowTitle = GetTitle() + "##" + Name;
const bool IsOpen = ImGui::Begin(StringCast<ANSICHAR>(*WindowTitle).Get(), &bIsVisible, WindowFlags);
PostBegin();
if (IsOpen)
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
}
if (ImGui::Begin(TCHAR_TO_ANSI(*WindowTitle), &bIsVisible, WindowFlags))
{
if (bNoPadding)
{
ImGui::PopStyleVar(1);
}
if (ImGui::BeginPopupContextWindow())
{
if (bHasMenu)
{
ImGui::Checkbox("Show Menu", &bShowMenu);
}
if (ImGui::Button("Reset Settings"))
{
ResetConfig();
}
ImGui::EndPopup();
}
RenderContent();
}
else
{
if (bNoPadding)
if (bUseCustomContextMenu == false)
{
ImGui::PopStyleVar(1);
if (ImGui::BeginPopupContextWindow())
{
RenderContextMenu();
ImGui::EndPopup();
}
}
}
ImGui::End();
PostRender();
PostEnd();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -127,19 +146,19 @@ void FCogWindow::GameTick(float DeltaTime)
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::SetSelection(AActor* NewSelection)
{
if (CurrentSelection == NewSelection)
{
return;
}
AActor* OldActor = GetSelection();
FCogDebug::SetSelection(NewSelection);
AActor* OldActor = CurrentSelection.Get();
CurrentSelection = NewSelection;
OnSelectionChanged(OldActor, NewSelection);
}
//--------------------------------------------------------------------------------------------------------------------------
AActor* FCogWindow::GetSelection() const
{
return FCogDebug::GetSelection();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::SetIsVisible(const bool Value)
{
if (bIsVisible == Value)
@@ -189,13 +208,32 @@ ULocalPlayer* FCogWindow::GetLocalPlayer() const
}
//--------------------------------------------------------------------------------------------------------------------------
UCogCommonConfig* FCogWindow::GetConfig(const TSubclassOf<UCogCommonConfig> ConfigClass) const
UCogCommonConfig* FCogWindow::GetConfig(const TSubclassOf<UCogCommonConfig>& InConfigClass, bool InResetConfigOnRequest) const
{
return GetOwner()->GetConfig(ConfigClass);
UCogCommonConfig* Config = GetOwner()->GetConfig(InConfigClass);
if (Config != nullptr && InResetConfigOnRequest)
{
ConfigsToResetOnRequest.AddUnique(Config);
}
return Config;
}
//--------------------------------------------------------------------------------------------------------------------------
const UObject* FCogWindow::GetAsset(const TSubclassOf<UObject> AssetClass) const
void FCogWindow::ResetConfig()
{
for (auto& Config : ConfigsToResetOnRequest)
{
if (Config != nullptr)
{
Config->Reset();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
const UObject* FCogWindow::GetAsset(const TSubclassOf<UObject>& AssetClass) const
{
return GetOwner()->GetAsset(AssetClass);
}
@@ -205,3 +243,25 @@ UWorld* FCogWindow::GetWorld() const
{
return Owner->GetWorld();
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindow::IsWindowRenderedInMainMenu()
{
return Owner->IsRenderingMainMenu();
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogWindow::GetDpiScale() const
{
return GetOwner()->GetContext().GetDpiScale();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow::RenderConfigShortcuts(UCogCommonConfig& InConfig) const
{
FProperty* InModifiedProperty = nullptr;
if (FCogWidgets::AllInputChordsOfConfig(InConfig, &InModifiedProperty))
{
GetOwner()->RebindShortcut(InConfig, *InModifiedProperty);
}
}
@@ -0,0 +1,66 @@
#include "CogWindow_Layouts.h"
#include "CogImguiInputHelper.h"
#include "CogSubsystem.h"
#include "CogWindow_Settings.h"
#include "InputCoreTypes.h"
//--------------------------------------------------------------------------------------------------------------------------
FCogWindow_Layouts::FCogWindow_Layouts()
{
bShowInMainMenu = false;
bHasMenu = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Layouts::RenderContent()
{
const UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld());
if (PlayerInput == nullptr)
{
return;
}
if (ImGui::MenuItem("Reset Window Layout"))
{
GetOwner()->ResetLayout();
}
ImGui::Separator();
UCogWindowConfig_Settings* Settings = GetOwner()->GetSettings();
RenderLoadLayoutMenuItem(1, Settings->Shortcut_LoadLayout1);
RenderLoadLayoutMenuItem(2, Settings->Shortcut_LoadLayout2);
RenderLoadLayoutMenuItem(3, Settings->Shortcut_LoadLayout3);
RenderLoadLayoutMenuItem(4, Settings->Shortcut_LoadLayout4);
ImGui::Separator();
RenderSaveLayoutMenuItem(1, Settings->Shortcut_SaveLayout1);
RenderSaveLayoutMenuItem(2, Settings->Shortcut_SaveLayout2);
RenderSaveLayoutMenuItem(3, Settings->Shortcut_SaveLayout3);
RenderSaveLayoutMenuItem(4, Settings->Shortcut_SaveLayout4);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Layouts::RenderLoadLayoutMenuItem(int InLayoutIndex, const FInputChord& InInputChord)
{
const auto Shortcut = StringCast<ANSICHAR>(*FCogImguiInputHelper::InputChordToString(InInputChord));
const auto Text = StringCast<ANSICHAR>(*FString::Printf(TEXT("Load Layout %d"), InLayoutIndex));
if (ImGui::MenuItem(Text.Get(), Shortcut.Get()))
{
GetOwner()->LoadLayout(InLayoutIndex + 1);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Layouts::RenderSaveLayoutMenuItem(int InLayoutIndex, const FInputChord& InInputChord)
{
const auto Shortcut = StringCast<ANSICHAR>(*FCogImguiInputHelper::InputChordToString(InInputChord));
const auto Text = StringCast<ANSICHAR>(*FString::Printf(TEXT("Save Layout %d"), InLayoutIndex));
if (ImGui::MenuItem(Text.Get(), Shortcut.Get()))
{
GetOwner()->SaveLayout(InLayoutIndex + 1);
}
}
@@ -2,18 +2,24 @@
#include "CogImguiHelper.h"
#include "CogImguiInputHelper.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "imgui.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "InputCoreTypes.h"
//--------------------------------------------------------------------------------------------------------------------------
FCogWindow_Settings::FCogWindow_Settings()
{
bShowInMainMenu = false;
bHasMenu = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Settings::Initialize()
{
Super::Initialize();
bHasMenu = false;
Config = GetConfig<UCogWindowConfig_Settings>();
@@ -38,6 +44,10 @@ void FCogWindow_Settings::PreSaveConfig()
Super::PreSaveConfig();
ImGuiIO& IO = ImGui::GetIO();
if (Config == nullptr)
{ return; }
Config->bNavEnableKeyboard = IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard;
//Config->bNavEnableGamepad = IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad;
//Config->bNavNoCaptureInput = IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard;
@@ -49,14 +59,6 @@ void FCogWindow_Settings::PreSaveConfig()
Config->bShareMouseWithGameplay = Context.GetShareMouseWithGameplay();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Settings::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Settings::RenderContent()
{
@@ -77,8 +79,8 @@ void FCogWindow_Settings::RenderContent()
{
Context.SetEnableInput(bEnableInput);
}
ImGui::SetItemTooltip("Enable ImGui inputs. When enabled the ImGui menu is shown and inputs are forwarded to ImGui.");
FCogWindowWidgets::MenuItemShortcut("EnableInputShortcut", FCogImguiInputHelper::CommandToString(PlayerInput, UCogWindowManager::ToggleInputCommand));
FCogWidgets::ItemTooltipWrappedText("Enable ImGui inputs. When enabled the ImGui menu is shown and inputs are forwarded to ImGui.");
FCogWidgets::MenuItemShortcut("EnableInputShortcut", FCogImguiInputHelper::InputChordToString(Config->Shortcut_ToggleImguiInput));
//-------------------------------------------------------------------------------------------
bool bShareKeyboard = Context.GetShareKeyboard();
@@ -86,7 +88,7 @@ void FCogWindow_Settings::RenderContent()
{
Context.SetShareKeyboard(bShareKeyboard);
}
ImGui::SetItemTooltip("Forward the keyboard inputs to the game when ImGui does not need them.");
FCogWidgets::ItemTooltipWrappedText("Forward the keyboard inputs to the game when ImGui does not need them.");
//-------------------------------------------------------------------------------------------
bool bShareMouse = Context.GetShareMouse();
@@ -94,7 +96,7 @@ void FCogWindow_Settings::RenderContent()
{
Context.SetShareMouse(bShareMouse);
}
ImGui::SetItemTooltip("Forward mouse inputs to the game when ImGui does not need them.");
FCogWidgets::ItemTooltipWrappedText("Forward mouse inputs to the game when ImGui does not need them.");
//-------------------------------------------------------------------------------------------
if (bShareMouse == false)
@@ -107,7 +109,7 @@ void FCogWindow_Settings::RenderContent()
{
Context.SetShareMouseWithGameplay(bShareMouseWithGameplay);
}
ImGui::SetItemTooltip("When disabled, mouse inputs are only forwarded to game menus. "
FCogWidgets::ItemTooltipWrappedText("When disabled, mouse inputs are only forwarded to game menus. "
"When enabled, mouse inputs are also forwarded to the gameplay. Note that this mode: \n"
" - Force the cursor to be visible.\n"
" - Prevent the interaction of Cog's transform gizmos.\n"
@@ -120,13 +122,23 @@ void FCogWindow_Settings::RenderContent()
//-------------------------------------------------------------------------------------------
ImGui::CheckboxFlags("Keyboard Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::SetItemTooltip("Use the keyboard to navigate in ImGui windows with the following keys : Tab, Directional Arrows, Space, Enter.");
FCogWidgets::ItemTooltipWrappedText("Use the keyboard to navigate in ImGui windows with the following keys : Tab, Directional Arrows, Space, Enter.");
//-------------------------------------------------------------------------------------------
//ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
//FCogWidgets::ItemTooltipWrappedText("Use the gamepad to navigate in ImGui windows.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Disable Conflicting Commands", &Config->bDisableConflictingCommands);
FCogWidgets::ItemTooltipWrappedText("Disable the existing Unreal command shortcuts mapped to same shortcuts Cog is using. Typically, if the F1 shortcut is used to toggle Inputs, the Unreal wireframe command will get disabled.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Disable shortcuts when ImGui want text input", &Config->bDisableShortcutsWhenImGuiWantTextInput);
FCogWidgets::ItemTooltipWrappedText("Disable Cog's shortcuts (ToggleInput, ToggleSelectionMode, LoadLayout, ...) when ImGui want text input."
" This can be required if the shortcuts are mapped by keys generating a text input (letters, or Backspace for example)."
" This is not required if the shortcuts are set to keys such as F1 or F2.");
}
//-------------------------------------------------------------------------------------------
//ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
//ImGui::SetItemTooltip("Use the gamepad to navigate in ImGui windows.");
//-------------------------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Window", ImGuiTreeNodeFlags_DefaultOpen))
{
@@ -134,22 +146,26 @@ void FCogWindow_Settings::RenderContent()
{
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_ViewportsEnable, Config->bEnableViewports);
}
ImGui::SetItemTooltip("Enable moving ImGui windows outside of the main viewport.");
FCogWidgets::ItemTooltipWrappedText("Enable moving ImGui windows outside of the main viewport.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Compact Mode", &Config->bCompactMode);
ImGui::SetItemTooltip("Enable compact mode.");
FCogWidgets::ItemTooltipWrappedText("Enable compact mode.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Transparent Mode", &Config->bTransparentMode);
FCogWidgets::ItemTooltipWrappedText("Enable transparent mode.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Show Windows In Main Menu", &Config->bShowWindowsInMainMenu);
ImGui::SetItemTooltip("Show the content of the windows when hovering the window menu item.");
FCogWidgets::ItemTooltipWrappedText("Show the content of the windows when hovering the window menu item.");
//-------------------------------------------------------------------------------------------
ImGui::Checkbox("Show Help", &Config->bShowHelp);
ImGui::SetItemTooltip("Show windows help on the window menu items.");
FCogWidgets::ItemTooltipWrappedText("Show windows help on the window menu items.");
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("DPI Scale", &Config->DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
{
@@ -164,12 +180,108 @@ void FCogWindow_Settings::RenderContent()
}
//-------------------------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Config"))
if (ImGui::CollapsingHeader("Widgets (?)", ImGuiTreeNodeFlags_DefaultOpen))
{
if (ImGui::Button("Reset All Windows Config", ImVec2(-1.0f, 0.0f)))
FCogWidgets::ItemTooltipWrappedText("Widgets appear in the main menu bar.");
ImGui::Checkbox("Show Widget Borders", &Config->ShowWidgetBorders);
FCogWidgets::ItemTooltipWrappedText("Should a border be visible between widgets.");
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Widgets Alignment", Config->WidgetAlignment);
FCogWidgets::ItemTooltipWrappedText("How the widgets should be aligned in the main menu bar.");
if (ImGui::BeginChild("Widgets", ImVec2(0, ImGui::GetFontSize() * 10), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY, ImGuiWindowFlags_MenuBar))
{
if (ImGui::BeginMenuBar())
{
ImGui::TextUnformatted("Widgets visibility and ordering");
ImGui::SameLine();
FCogWidgets::HelpMarker("Drag and drop the widget names to reorder them.");
ImGui::EndMenuBar();
}
TArray<FCogWindow*>& Widgets = GetOwner()->Widgets;
for (int32 i = 0; i < Widgets.Num(); ++i)
{
FCogWindow* Window = Widgets[i];
ImGui::PushID(i);
bool Visible = Window->GetIsWidgetVisible();
if (ImGui::Checkbox("##Visibility", &Visible))
{
Window->SetIsWidgetVisible(Visible);
}
ImGui::SameLine();
ImGui::Selectable(TCHAR_TO_ANSI(*Window->GetName()), false, ImGuiSelectableFlags_SpanAvailWidth);
{
Window->SetIsWidgetVisible(Visible);
}
if (ImGui::IsItemHovered())
{
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
}
if (ImGui::IsItemActive() && ImGui::IsItemHovered() == false)
{
const int iNext = i + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1);
if (iNext >= 0 && iNext < Widgets.Num())
{
Widgets[i] = Widgets[iNext];
Widgets[iNext] = Window;
ImGui::ResetMouseDragDelta();
}
}
ImGui::PopID();
}
}
ImGui::EndChild();
}
//-------------------------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Shortcuts", ImGuiTreeNodeFlags_DefaultOpen))
{
for (TObjectPtr SomeConfig : GetOwner()->GetConfigs())
{
if (SomeConfig == nullptr)
{ continue; }
if (FCogWidgets::IsConfigContainingInputChords(*SomeConfig))
{
auto ConfigName = StringCast<ANSICHAR>(*FCogWidgets::FormatConfigName(SomeConfig->GetClass()->GetName()));
ImGui::SeparatorText(ConfigName.Get());
FProperty* InModifiedProperty = nullptr;
if (FCogWidgets::AllInputChordsOfConfig(*SomeConfig, &InModifiedProperty))
{
GetOwner()->RebindShortcut(*SomeConfig, *InModifiedProperty);
}
}
}
}
//-------------------------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Settings", ImGuiTreeNodeFlags_DefaultOpen))
{
if (ImGui::Button("Save All Settings", ImVec2(ImGui::GetContentRegionAvail().x, 0.0f)))
{
GetOwner()->SaveAllSettings();
}
// if (ImGui::Button("Reload All Settings", ImVec2(ImGui::GetContentRegionAvail().x, 0.0f)))
// {
// GetOwner()->ReloadAllSettings();
// }
FCogWidgets::PushButtonBackColor(ImVec4(1.0f, 0.0f, 0.0f, 1));
if (ImGui::Button("Reset All Settings", ImVec2(ImGui::GetContentRegionAvail().x, 0.0f)))
{
GetOwner()->ResetAllWindowsConfig();
}
FCogWidgets::PopButtonBackColor();
}
}
@@ -1,13 +1,19 @@
#include "CogWindow_Spacing.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Spacing::PreRender(ImGuiWindowFlags& WindowFlags)
FCogWindow_Spacing::FCogWindow_Spacing()
{
bShowInMainMenu = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Spacing::PreBegin(ImGuiWindowFlags& WindowFlags)
{
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Spacing::PostRender()
void FCogWindow_Spacing::PostBegin()
{
ImGui::PopStyleColor(1);
}
@@ -2,7 +2,6 @@
#include "CoreMinimal.h"
#include "HAL/IConsoleManager.h"
#include "Templates/Function.h"
class UWorld;
@@ -11,7 +10,7 @@ DECLARE_DELEGATE_TwoParams(FCogWindowConsoleCommandDelegate, const TArray<FStrin
//--------------------------------------------------------------------------------------------------------------------------
struct FCogCommandReceiver
{
UWorld* World = nullptr;
int32 PIEInstance = INDEX_NONE;
FCogWindowConsoleCommandDelegate Delegate;
};
@@ -25,10 +24,8 @@ struct FCogCommandInfo
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGWINDOW_API FCogWindowConsoleCommandManager
struct COG_API FCogConsoleCommandManager
{
public:
static void RegisterWorldConsoleCommand(const TCHAR* InName, const TCHAR* InHelp, UWorld* InWorld, const FCogWindowConsoleCommandDelegate& InDelegate);
static void UnregisterAllWorldConsoleCommands(const UWorld* InWorld);
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include "AssetRegistry/AssetData.h"
#include "CoreMinimal.h"
#include "Templates/SubclassOf.h"
class UCollisionProfile;
class COG_API FCogHelper
{
public:
static FString GetActorName(const AActor* Actor);
static FString GetActorName(const AActor& Actor);
static bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max);
template<typename T>
static const T* GetFirstAssetByClass();
static const UObject* GetFirstAssetByClass(const TSubclassOf<UObject>& AssetClass);
template<typename TCLass, typename TMember>
static FProperty* FindProperty(TCLass* Instance, TMember TCLass::*PointerToMember);
static bool IsTraceChannelHidden(const UCollisionProfile& InCollisionProfile, ECollisionChannel InCollisionChannel);
};
//----------------------------------------------------------------------------------------------------------------------
template<typename T>
const T* FCogHelper::GetFirstAssetByClass()
{
return Cast<T>(GetFirstAssetByClass(T::StaticClass()));
}
//----------------------------------------------------------------------------------------------------------------------
template<typename TCLass, typename TMember>
FProperty* FCogHelper::FindProperty(TCLass* Instance, TMember TCLass::*PointerToMember)
{
for (TFieldIterator<FProperty> It(Instance->GetClass()); It; ++It)
{
FProperty* Property = *It;
if (Property == nullptr)
{ continue; }
const void* MemberAddress = &(Instance->*PointerToMember);
const void* PropertyAddress = Property->ContainerPtrToValuePtr<void>(Instance);
if (MemberAddress == PropertyAddress)
{ return Property; }
}
return nullptr;
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class COG_API FCogModule : public IModuleInterface
{
public:
static inline FCogModule& Get() { return FModuleManager::LoadModuleChecked<FCogModule>("Cog"); }
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
@@ -0,0 +1,15 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "CogPluginSubsystem.generated.h"
UCLASS(Abstract)
class COG_API UCogPluginSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
virtual void OnPlayerControllerSet(APlayerController* InController) {}
};
@@ -1,9 +1,13 @@
#pragma once
#include "CoreMinimal.h"
#include "CogHelper.h"
#include "CogImguiContext.h"
#include "CogWindow_Settings.h"
#include "imgui.h"
#include "CogWindowManager.generated.h"
#include "Subsystems/WorldSubsystem.h"
#include "CogSubsystem.generated.h"
class UCogCommonConfig;
class FCogWindow;
@@ -17,31 +21,30 @@ struct ImGuiSettingsHandler;
struct ImGuiTextBuffer;
struct FKey;
UCLASS(Config = Cog)
class COGWINDOW_API UCogWindowManager : public UObject
//--------------------------------------------------------------------------------------------------------------------------
UCLASS()
class COG_API UCogSubsystem : public UTickableWorldSubsystem
{
GENERATED_BODY()
public:
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
UCogWindowManager();
virtual TStatId GetStatId() const override;
virtual void PostInitProperties() override;
virtual void PostInitialize() override;
virtual void Shutdown();
virtual void Deinitialize() override;
virtual void SortMainMenu();
virtual void Tick(float DeltaTime) override;
virtual void Render(float DeltaTime);
virtual void Tick(float DeltaTime);
virtual void AddWindow(FCogWindow* Window, const FString& Name, bool AddToMainMenu = true);
virtual void AddWindow(FCogWindow* Window, const FString& Name);
template<class T>
T* AddWindow(const FString& Name, bool AddToMainMenu = true);
T* AddWindow(const FString& Name);
virtual void SortMainMenu();
virtual FCogWindow* FindWindowByID(ImGuiID ID);
virtual void CloseAllWindows();
@@ -52,34 +55,43 @@ public:
virtual void SaveLayout(int32 LayoutIndex);
virtual bool GetHideAllWindows() const { return bIsSelectionModeActive; }
virtual void SetActivateSelectionMode(bool Value);
virtual bool GetActivateSelectionMode() const;
virtual void ResetAllWindowsConfig();
virtual bool RegisterDefaultCommandBindings();
const FCogWindow_Settings* GetSettingsWindow() const { return SettingsWindow; }
UCogWindowConfig_Settings* GetSettings() const { return Settings.Get(); }
UCogCommonConfig* GetConfig(const TSubclassOf<UCogCommonConfig> ConfigClass);
UCogCommonConfig* GetConfig(const TSubclassOf<UCogCommonConfig>& ConfigClass);
template<class T>
T* GetConfig();
const UObject* GetAsset(const TSubclassOf<UObject> AssetClass) const;
const UObject* GetAsset(const TSubclassOf<UObject>& AssetClass) const;
template<typename T>
T* GetAsset();
FInputActionHandlerSignature& AddShortcut(const UObject& InInstance, const FProperty& InProperty);
template<typename TCLass, typename TMember>
FInputActionHandlerSignature& AddShortcut(TCLass* InInstance, TMember TCLass::*InPointerToMember);
void RebindShortcut(const UCogCommonConfig& InConfig, const FProperty& InProperty);
const FCogImguiContext& GetContext() const { return Context; }
FCogImguiContext& GetContext() { return Context; }
bool IsRenderingMainMenu() const { return bIsRenderingInMainMenu; }
static void AddCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key);
static void SortCommands(UPlayerInput* PlayerInput);
TArray<TObjectPtr<UCogCommonConfig>>& GetConfigs() const { return Configs; };
protected:
friend class FCogWindow_Layouts;
@@ -92,10 +104,29 @@ protected:
TArray<FMenu> SubMenus;
};
virtual void InitializeInternal();
struct FCogShortcut
{
FName PropertyName;
TWeakObjectPtr<const UObject> Config;
FInputActionHandlerSignature Delegate;
FInputChord InputChord;
};
virtual void Render(float DeltaTime);
virtual void TryInitialize(UWorld& World);
virtual void UpdatePlayerControllers(UWorld& World);
virtual void InitializeWindow(FCogWindow* Window);
virtual void Shutdown();
virtual void RenderMainMenu();
virtual FMenu* AddMenu(const FString& Name);
virtual void RenderOptionMenu(FMenu& Menu);
@@ -104,10 +135,24 @@ protected:
virtual void RenderMenuItemHelp(FCogWindow& Window);
void SetLocalPlayerController(APlayerController& PlayerController);
virtual void ToggleInputMode();
virtual void DisableInputMode();
virtual void TryDisableCommandsConflictingWithShortcuts(UPlayerInput* PlayerInput);
virtual void RequestDisableCommandsConflictingWithShortcuts();
virtual bool BindShortcut(FCogShortcut& InShortcut) const;
virtual void RenderWidgets();
virtual void SaveAllSettings();
virtual void ReloadAllSettings();
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
static void SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
@@ -118,6 +163,8 @@ protected:
static void SettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf);
static FString EnableCommand;
static FString ToggleInputCommand;
static FString DisableInputCommand;
@@ -129,13 +176,19 @@ protected:
static FString ResetLayoutCommand;
UPROPERTY()
mutable TArray<UCogCommonConfig*> Configs;
TWeakObjectPtr<UWorld> CurrentWorld;
UPROPERTY()
mutable TArray<TObjectPtr<UCogCommonConfig>> Configs;
UPROPERTY()
mutable TArray<const UObject*> Assets;
mutable TArray<TObjectPtr<const UObject>> Assets;
UPROPERTY(Config)
bool bRegisterDefaultCommands = true;
TArray<TWeakObjectPtr<APlayerController>> ServerPlayerControllers;
TWeakObjectPtr<APlayerController> LocalPlayerController;
TWeakObjectPtr<UInputComponent> InputComponent;
FCogImguiContext Context;
@@ -143,11 +196,15 @@ protected:
TArray<FCogWindow*> Widgets;
TArray<FCogShortcut> Shortcuts;
int32 WidgetsOrderIndex = 0;
TArray<FCogWindow*> SpaceWindows;
FCogWindow_Settings* SettingsWindow = nullptr;
TWeakObjectPtr<UCogWindowConfig_Settings> Settings;
FCogWindow_Layouts* LayoutsWindow = nullptr;
@@ -156,32 +213,56 @@ protected:
int32 LayoutToLoad = -1;
int32 SelectionModeActiveCounter = 0;
bool bIsInputEnabledBeforeEnteringSelectionMode = false;
bool bIsSelectionModeActive = false;
bool IsInitialized = false;
bool bIsInitialized = false;
bool bIsRenderingInMainMenu = false;
int32 NumExecBindingsChecked = 0;
FInputActionHandlerSignature InvalidShortcutDelegate;
};
//--------------------------------------------------------------------------------------------------------------------------
template<class T>
T* UCogWindowManager::AddWindow(const FString& Name, bool AddToMainMenu)
T* UCogSubsystem::AddWindow(const FString& Name)
{
T* Window = new T();
AddWindow(Window, Name, AddToMainMenu);
AddWindow(Window, Name);
return Window;
}
//--------------------------------------------------------------------------------------------------------------------------
template<class T>
T* UCogWindowManager::GetConfig()
T* UCogSubsystem::GetConfig()
{
static_assert(TPointerIsConvertibleFromTo<T, const UCogCommonConfig>::Value);
return Cast<T>(&GetConfig(T::StaticClass()));
return Cast<T>(GetConfig(T::StaticClass()));
}
//--------------------------------------------------------------------------------------------------------------------------
template<typename T>
T* UCogWindowManager::GetAsset()
T* UCogSubsystem::GetAsset()
{
return Cast<T>(GetAsset(T::StaticClass()));
}
}
//--------------------------------------------------------------------------------------------------------------------------
template <typename TCLass, typename TMember>
FInputActionHandlerSignature& UCogSubsystem::AddShortcut(TCLass* InInstance, TMember TCLass::* InPointerToMember)
{
if (InInstance == nullptr)
{ return InvalidShortcutDelegate; }
const FProperty* Property = FCogHelper::FindProperty(InInstance, InPointerToMember);
if (Property == nullptr)
{ return InvalidShortcutDelegate; }
return AddShortcut(*InInstance, *Property);
}
+286
View File
@@ -0,0 +1,286 @@
#pragma once
#include "CoreMinimal.h"
#include "imgui.h"
#include "UObject/ReflectedTypeAccessors.h"
#include <Templates/SubclassOf.h>
#include "CogHelper.h"
class AActor;
class APawn;
class FEnumProperty;
class UCollisionProfile;
class UEnum;
class UObject;
enum class ECheckBoxState : uint8;
enum ECollisionChannel : int;
struct FKeyBind;
using FCogWindowActorContextMenuFunction = TFunction<void(AActor& Actor)>;
//--------------------------------------------------------------------------------------------------------------------------
class COG_API FCogWidgets
{
public:
static bool BeginTableTooltip();
static void EndTableTooltip();
static bool ItemTooltipWrappedText(const char* InText);
static bool BeginItemTooltipWrappedText();
static void EndItemTooltipWrappedText();
static bool BeginItemTableTooltip();
static void EndItemTableTooltip();
static void ThinSeparatorText(const char* Label);
static bool DarkCollapsingHeader(const char* InLabel, ImGuiTreeNodeFlags InFlags);
static void ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay);
static bool ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor);
static bool ToggleButton(bool* Value, const char* Text, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static bool ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static bool MultiChoiceButton(const char* Label, bool IsSelected, const ImVec2& Size = ImVec2(0, 0));
static bool MultiChoiceButtonsInt(TArray<int32>& Values, int32& Value, const ImVec2& Size = ImVec2(0, 0), bool InInline = true);
static bool MultiChoiceButtonsFloat(TArray<float>& InValues, float& InValue, const ImVec2& InSize = ImVec2(0, 0), bool InInline = true, float InTolerance = UE_SMALL_NUMBER);
static void SliderWithReset(const char* Name, float* Value, float Min, float Max, const float& ResetValue, const char* Format);
static void HelpMarker(const char* Text);
static void PushStyleCompact();
static void PopStyleCompact();
static void AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd = nullptr);
static bool SearchBar(const char* InLabel, ImGuiTextFilter& InFilter, float InWidth = -1.0f);
static void PushButtonBackColor(const ImVec4& Color);
static void PopButtonBackColor();
static void PushFrameBackColor(const ImVec4& Color);
static void PushSliderBackColor(const ImVec4& Color);
static void PushBackColor(const ImVec4& Color);
static void PopSliderBackColor();
static void PopFrameBackColor();
static void PopBackColor();
static float GetShortWidth();
static void SetNextItemToShortWidth();
static float GetFontWidth();
template<typename EnumType>
static bool ComboboxEnum(const char* Label, const EnumType CurrentValue, EnumType& NewValue);
template<typename EnumType>
static bool ComboboxEnum(const char* Label, EnumType& Value);
static bool ComboboxEnum(const char* Label, const UEnum* Enum, int64 CurrentValue, int64& NewValue);
static bool ComboboxEnum(const char* Label, const UObject* Object, const char* FieldName, uint8* PointerToEnumValue);
static bool ComboboxEnum(const char* Label, const FEnumProperty* EnumProperty, uint8* PointerToEnumValue);
static bool CheckBoxState(const char* Label, ECheckBoxState& State, bool ShowTooltip = true);
static bool InputChord(const char* Label, FInputChord& InInputChord);
static bool InputChord(FInputChord& InInputChord);
static bool Key(FKey& InKey);
static bool KeyBind(FKeyBind& InKeyBind);
static bool ButtonWithTooltip(const char* Text, const char* Tooltip);
static bool DeleteArrayItemButton();
static bool ComboTraceChannel(const char* Label, ECollisionChannel& Channel);
static bool CollisionProfileChannels(int32& OutChannels);
static bool CollisionTraceChannels(int32& OutChannels);
static bool CollisionObjectTypeChannels(int32& OutChannels);
static bool CollisionProfileChannel(const UCollisionProfile& InCollisionProfile, int32 InChannelIndex, FColor& InChannelColor, int32& InChannels);
static bool MenuActorsCombo(const char* StrID, AActor*& NewSelection, const UWorld& World, const TSubclassOf<AActor>& ActorClass, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool MenuActorsCombo(const char* StrID, AActor*& NewSelection, const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool ActorsListWithFilters(AActor*& NewSelection, const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool ActorsList(AActor*& NewSelection, const UWorld& World, const TSubclassOf<AActor>& ActorClass, const ImGuiTextFilter* Filter = nullptr, const APawn* LocalPlayerPawn = nullptr, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static void ActorContextMenu(AActor& Selection, const FCogWindowActorContextMenuFunction& ContextMenuFunction);
static void ActorFrame(const AActor& Actor);
static void SmallButton(const char* Text, const ImVec4& Color);
static bool InputText(const char* Text, FString& Value, ImGuiInputTextFlags InFlags = 0, ImGuiInputTextCallback InCallback = nullptr, void* InUserData = nullptr);
static bool InputTextWithHint(const char* InText, const char* InHint, FString& InValue, ImGuiInputTextFlags InFlags = 0, ImGuiInputTextCallback InCallback = nullptr, void* InUserData = nullptr);
static bool BeginRightAlign(const char* Id);
static void EndRightAlign();
static void MenuItemShortcut(const char* Id, const FString& Text);
template <typename TCLass, typename TMember>
static void InputChordProperty(TCLass* InConfig, TMember TCLass::* InInputChordPointerToMember);
template <typename TCLass, typename TMember>
static void TextInputChordProperty(TCLass* InConfig, TMember TCLass::* InInputChordPointerToMember);
static bool BrowseToAssetButton(const UObject* InAsset, const ImVec2& InSize = ImVec2(0, 0));
static bool BrowseToAssetButton(const FAssetData& InAssetData, const ImVec2& InSize = ImVec2(0, 0));
static bool BrowseToObjectAssetButton(const UObject* InObject, const ImVec2& InSize = ImVec2(0, 0));
static bool OpenAssetButton(const UObject* InAsset, const ImVec2& InSize = ImVec2(0, 0));
static bool OpenObjectAssetButton(const UObject* InObject, const ImVec2& InSize = ImVec2(0, 0));
static void RenderCloseButton(const ImVec2& InPos);
static bool PickButton(const char* InLabel, const ImVec2& InSize, ImGuiButtonFlags InFlags = ImGuiButtonFlags_None);
static FString RemoveFirstZero(const FString& InText);
static FString FormatSmallFloat(float InValue);
static void FloatArray(const char* InLabel, TArray<float>& InArray, int32 InMaxEntries = 0, const ImVec2& Size = ImVec2(0, 0));
static void IntArray(const char* InLabel, TArray<int>& InArray, int32 InMaxEntries = 0, const ImVec2& Size = ImVec2(0, 0));
template<typename T>
static bool ScalarArray(const char* InLabel, ImGuiDataType InDataType, TArray<T>& InArray, int32 InMaxEntries = 0, const ImVec2& Size = ImVec2(0, 0));
static ImVec2 ComputeScreenCornerLocation(const FVector2f& InAlignment, const FIntVector2& InPadding);
static ImVec2 ComputeScreenCornerLocation(const ImVec2& InAlignment, const ImVec2& InPadding);
static FString GetStringAfterCharacter(const FString& InString, TCHAR InChar);
static FString FormatConfigName(const FString& InConfigName);
static FString FormatShortcutName(const FString& InShortcutName);
static void TextInputChordProperty(UObject& InConfig, const FProperty& InInputChordProperty);
static bool InputChordProperty(UObject& InConfig, const FProperty& InInputChordProperty);
static bool IsConfigContainingInputChords(const UObject& InConfig);
static bool AllInputChordsOfConfig(UObject& InConfig, FProperty** InModifiedProperty = nullptr);
static void TextOfAllInputChordsOfConfig(UObject& InConfig);
};
template<typename EnumType>
bool FCogWidgets::ComboboxEnum(const char* Label, const EnumType CurrentValue, EnumType& NewValue)
{
int64 NewValueInt;
if (ComboboxEnum(Label, StaticEnum<EnumType>(), static_cast<int64>(CurrentValue), NewValueInt))
{
NewValue = static_cast<EnumType>(NewValueInt);
return true;
}
return false;
}
template<typename EnumType>
bool FCogWidgets::ComboboxEnum(const char* Label, EnumType& Value)
{
return ComboboxEnum(Label, Value, Value);
}
template<typename T>
bool FCogWidgets::ScalarArray(const char* InLabel, ImGuiDataType InDataType, TArray<T>& InArray, int32 InMaxEntries, const ImVec2& Size)
{
bool Result = false;
ImGui::PushID(InLabel);
if (ImGui::BeginChild("##Entries", Size, ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY, ImGuiWindowFlags_MenuBar))
{
if (ImGui::BeginMenuBar())
{
ImGui::TextUnformatted(InLabel);
int32 NumEntries = InArray.Num();
SetNextItemToShortWidth();
if (ImGui::SliderInt("##Size", &NumEntries, 0, InMaxEntries))
{
InArray.SetNum(NumEntries);
Result = true;
}
ImGui::EndMenuBar();
}
for (int32 i = 0; i < InArray.Num(); i++)
{
ImGui::PushID(i);
ImGui::SetNextItemWidth(-1);
if (ImGui::InputScalar("##Entry", InDataType, &InArray[i]))
{
Result = true;
}
ImGui::PopID();
}
}
ImGui::EndChild();
ImGui::PopID();
return Result;
}
template <typename TCLass, typename TMember>
void FCogWidgets::InputChordProperty(TCLass* InConfig, TMember TCLass::* InInputChordPointerToMember)
{
if (InConfig == nullptr)
{ return; }
FProperty* Property = FCogHelper::FindProperty(InConfig, InInputChordPointerToMember);
if (Property == nullptr)
{ return; }
InputChordProperty(*InConfig, *Property);
}
template <typename TCLass, typename TMember>
void FCogWidgets::TextInputChordProperty(TCLass* InConfig, TMember TCLass::* InInputChordPointerToMember)
{
if (InConfig == nullptr)
{ return; }
FProperty* Property = FCogHelper::FindProperty(InConfig, InInputChordPointerToMember);
if (Property == nullptr)
{ return; }
TextInputChordProperty(*InConfig, *Property);
}
@@ -7,24 +7,25 @@
#include "UObject/ReflectedTypeAccessors.h"
#include "UObject/WeakObjectPtrTemplates.h"
struct FCogDebugContext;
class AActor;
class APawn;
class APlayerController;
class UCogWindowManager;
class UCogSubsystem;
class ULocalPlayer;
class UWorld;
class COGWINDOW_API FCogWindow
class COG_API FCogWindow
{
public:
virtual ~FCogWindow() {}
virtual void Initialize() {}
virtual void Initialize();
virtual void Shutdown() {}
virtual void Shutdown();
virtual void ResetConfig() {}
virtual void ResetConfig();
virtual void PreSaveConfig() {}
@@ -34,15 +35,16 @@ public:
/** Called every frame with a valid imgui context even if the window is hidden. */
virtual void RenderTick(float DeltaTime);
/** Called every frame without a valid imgui context (outside of the imgui NewFrame/EndFrame) even if the window is hidden. */
/** Called every frame without a valid imgui context (outside the imgui NewFrame/EndFrame) even if the window is hidden. */
virtual void GameTick(float DeltaTime);
/** */
virtual float GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) { return -1.0f; }
virtual void RenderMainMenuWidget();
/** */
virtual void RenderMainMenuWidget(int32 SubWidgetIndex, float Width) {}
virtual void RenderSettings();
virtual void BindInputs(UInputComponent* InputComponent) {}
ImGuiID GetID() const { return ID; }
/** The full name of the window, that contains the path in the main menu. For example "Gameplay.Character.Effect" */
@@ -53,7 +55,7 @@ public:
/** The short name of the window. "Effect" if the window full name is "Gameplay.Character.Effect" */
const FString& GetName() const { return Name; }
AActor* GetSelection() const { return CurrentSelection.Get(); }
AActor* GetSelection() const;
void SetSelection(AActor* Actor);
@@ -71,23 +73,27 @@ public:
void SetWidgetOrderIndex(int32 Value) { WidgetOrderIndex = Value; }
void SetOwner(UCogWindowManager* InOwner) { Owner = InOwner; }
void SetOwner(UCogSubsystem* InOwner) { Owner = InOwner; }
UCogWindowManager* GetOwner() const { return Owner; }
UCogSubsystem* GetOwner() const { return Owner; }
float GetDpiScale() const;
template<class T>
T* GetConfig() const { return Cast<T>(GetConfig(T::StaticClass())); }
T* GetConfig(bool InResetConfigOnRequest = true) const { return Cast<T>(GetConfig(T::StaticClass(), InResetConfigOnRequest)); }
UCogCommonConfig* GetConfig(const TSubclassOf<UCogCommonConfig> ConfigClass) const;
UCogCommonConfig* GetConfig(const TSubclassOf<UCogCommonConfig>& InConfigClass, bool InResetConfigOnRequest = true) const;
template<class T>
const T* GetAsset() const { return Cast<T>(GetAsset(T::StaticClass())); }
const UObject* GetAsset(const TSubclassOf<UObject> AssetClass) const;
const UObject* GetAsset(const TSubclassOf<UObject>& AssetClass) const;
protected:
friend class UCogWindowManager;
friend class UCogSubsystem;
virtual const FString& GetTitle() const { return Title; }
@@ -95,30 +101,36 @@ protected:
virtual void RenderHelp();
virtual void PreRender(ImGuiWindowFlags& WindowFlags) {}
virtual void PreBegin(ImGuiWindowFlags& WindowFlags) {}
virtual void PostRender() {}
virtual void PostBegin() {}
virtual void PostEnd() {}
virtual void RenderContent() {}
virtual bool CheckEditorVisibility();
virtual void RenderContextMenu();
virtual void OnWindowVisibilityChanged(bool NewVisibility) { }
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) {}
virtual bool IsWindowRenderedInMainMenu();
virtual void RenderConfigShortcuts(UCogCommonConfig& InConfig) const;
APawn* GetLocalPlayerPawn() const;
APlayerController* GetLocalPlayerController() const;
ULocalPlayer* GetLocalPlayer() const;
protected:
bool bIsInitialized = false;
bool bShowMenu = true;
bool bNoPadding = false;
bool bHasMenu = false;
bool bIsVisible = false;
@@ -127,20 +139,22 @@ protected:
bool bIsWidgetVisible = false;
bool bShowInMainMenu = true;
bool bUseCustomContextMenu = false;
int32 WidgetOrderIndex = -1;
ImGuiID ID;
ImGuiID ID = 0;
FString FullName;
FString Name;
FString Title;
UCogSubsystem* Owner = nullptr;
UCogWindowManager* Owner = nullptr;
TWeakObjectPtr<AActor> CurrentSelection;
TWeakObjectPtr<AActor> OverridenSelection;
mutable TArray<TWeakObjectPtr<UCogCommonConfig>> ConfigsToResetOnRequest;
};
@@ -0,0 +1,23 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
class UPlayerInput;
class COG_API FCogWindow_Layouts : public FCogWindow
{
typedef FCogWindow Super;
public:
FCogWindow_Layouts();
protected:
virtual void RenderContent() override;
virtual void RenderLoadLayoutMenuItem(int InLayoutIndex, const FInputChord& InInputChord);
virtual void RenderSaveLayoutMenuItem(int InLayoutIndex, const FInputChord& InInputChord);
};
@@ -0,0 +1,165 @@
#pragma once
#include "CoreMinimal.h"
#include "CogCommonConfig.h"
#include "CogWindow.h"
#include "CogWindow_Settings.generated.h"
class UCogEngineConfig_Settings;
//--------------------------------------------------------------------------------------------------------------------------
class COG_API FCogWindow_Settings : public FCogWindow
{
typedef FCogWindow Super;
public:
FCogWindow_Settings();
virtual void Initialize() override;
virtual void RenderTick(float DeltaTime) override;
const UCogWindowConfig_Settings* GetSettingsConfig() const { return Config; }
void SetDPIScale(float Value) const;
protected:
virtual void RenderContent() override;
virtual void PreSaveConfig() override;
TObjectPtr<UCogWindowConfig_Settings> Config = nullptr;
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogWidgetAlignment
{
Left = 0,
Center = 1,
Right = 2,
Manual = 3
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(Config = Cog)
class UCogWindowConfig_Settings : public UCogCommonConfig
{
GENERATED_BODY()
public:
UPROPERTY(Config)
float DPIScale = 1.0f;
UPROPERTY(Config)
bool bEnableViewports = false;
UPROPERTY(Config)
bool bCompactMode = false;
UPROPERTY(Config)
bool bTransparentMode = false;
UPROPERTY(Config)
bool bShowHelp = true;
UPROPERTY(Config)
bool bShowWindowsInMainMenu = true;
UPROPERTY(Config)
bool bEnableInput = false;
UPROPERTY(Config)
bool bShareMouse = false;
UPROPERTY(Config)
bool bShareMouseWithGameplay = false;
UPROPERTY(Config)
bool bShareKeyboard = false;
UPROPERTY(Config)
bool bNavEnableKeyboard = false;
UPROPERTY(Config)
bool bDisableConflictingCommands = true;
UPROPERTY(Config)
bool bDisableShortcutsWhenImGuiWantTextInput = false;
UPROPERTY(Config)
ECogWidgetAlignment WidgetAlignment = ECogWidgetAlignment::Right;
UPROPERTY(Config)
bool ShowWidgetBorders = false;
UPROPERTY(Config)
FInputChord Shortcut_ToggleImguiInput = FInputChord(EKeys::F1);
UPROPERTY(Config)
FInputChord Shortcut_LoadLayout1 = FInputChord(EKeys::F2);
UPROPERTY(Config)
FInputChord Shortcut_LoadLayout2 = FInputChord(EKeys::F3);
UPROPERTY(Config)
FInputChord Shortcut_LoadLayout3 = FInputChord(EKeys::F4);
UPROPERTY(Config)
FInputChord Shortcut_LoadLayout4 = FInputChord();
UPROPERTY(Config)
FInputChord Shortcut_SaveLayout1 = FInputChord();
UPROPERTY(Config)
FInputChord Shortcut_SaveLayout2 = FInputChord();
UPROPERTY(Config)
FInputChord Shortcut_SaveLayout3 = FInputChord();
UPROPERTY(Config)
FInputChord Shortcut_SaveLayout4 = FInputChord();
UPROPERTY(Config)
FInputChord Shortcut_ResetLayout = FInputChord();
//UPROPERTY(Config)
//bool bNavEnableGamepad = false;
//UPROPERTY(Config)
//bool bNavNoCaptureInput = true;
virtual void Reset() override
{
Super::Reset();
DPIScale = 1.0f;
bEnableViewports = false;
bCompactMode = false;
bTransparentMode = false;
bShowHelp = true;
bShowWindowsInMainMenu = true;
bEnableInput = false;
bShareMouse = false;
bShareMouseWithGameplay = false;
bShareKeyboard = false;
bNavEnableKeyboard = false;
bDisableConflictingCommands = true;
bDisableShortcutsWhenImGuiWantTextInput = false;
WidgetAlignment = ECogWidgetAlignment::Right;
ShowWidgetBorders = false;
Shortcut_ToggleImguiInput = FInputChord(EKeys::F1);
Shortcut_LoadLayout1 = FInputChord(EKeys::F2);
Shortcut_LoadLayout2 = FInputChord(EKeys::F3);
Shortcut_LoadLayout3 = FInputChord(EKeys::F4);
Shortcut_LoadLayout4 = FInputChord();
Shortcut_SaveLayout1 = FInputChord();
Shortcut_SaveLayout2 = FInputChord();
Shortcut_SaveLayout3 = FInputChord();
Shortcut_SaveLayout4 = FInputChord();
Shortcut_ResetLayout = FInputChord();
}
};
@@ -0,0 +1,17 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
class COG_API FCogWindow_Spacing : public FCogWindow
{
typedef FCogWindow Super;
public:
FCogWindow_Spacing();
virtual void PreBegin(ImGuiWindowFlags& WindowFlags) override;
virtual void PostBegin() override;
};
@@ -0,0 +1,3 @@
#include "CogCommonLogCategory.h"
DEFINE_LOG_CATEGORY(LogCogNotify);
@@ -2,6 +2,7 @@
#include "CoreMinimal.h"
#include "Templates/IsArrayOrRefOfType.h"
#include "CogCommonLogCategory.h"
#ifndef ENABLE_COG
#define ENABLE_COG !UE_BUILD_SHIPPING
@@ -17,6 +18,37 @@
//--------------------------------------------------------------------------------------------------------------------------
#define COG_LOG_ACTIVE_FOR_OBJECT(Object) (FCogDebug::IsDebugActiveForObject(Object))
//--------------------------------------------------------------------------------------------------------------------------
#define COG_NOTIFY(Format, ...) \
{ \
static_assert(TIsArrayOrRefOfType<decltype(Format), TCHAR>::Value, "Formatting string must be a TCHAR array."); \
FMsg::Logf_Internal(nullptr, 0, LogCogNotify.GetCategoryName(), ELogVerbosity::Log, Format, ##__VA_ARGS__); \
}
//--------------------------------------------------------------------------------------------------------------------------
#define COG_NOTIFY_WARNING(Format, ...) \
{ \
static_assert(TIsArrayOrRefOfType<decltype(Format), TCHAR>::Value, "Formatting string must be a TCHAR array."); \
FMsg::Logf_Internal(nullptr, 0, LogCogNotify.GetCategoryName(), ELogVerbosity::Warning, Format, ##__VA_ARGS__); \
}
//--------------------------------------------------------------------------------------------------------------------------
#define COG_NOTIFY_ERROR(Format, ...) \
{ \
static_assert(TIsArrayOrRefOfType<decltype(Format), TCHAR>::Value, "Formatting string must be a TCHAR array."); \
FMsg::Logf_Internal(nullptr, 0, LogCogNotify.GetCategoryName(), ELogVerbosity::Error, Format, ##__VA_ARGS__); \
}
//--------------------------------------------------------------------------------------------------------------------------
#define COG_NOTIFY_VERBOSITY(Verbosity, Format, ...) \
{ \
static_assert(TIsArrayOrRefOfType<decltype(Format), TCHAR>::Value, "Formatting string must be a TCHAR array."); \
if (LogCogNotify.IsSuppressed(Verbosity) == false) \
{ \
FMsg::Logf_Internal(nullptr, 0, LogCogNotify.GetCategoryName(), Verbosity, Format, ##__VA_ARGS__); \
} \
}
//--------------------------------------------------------------------------------------------------------------------------
#define COG_LOG(LogCategory, Verbosity, Format, ...) \
{ \
@@ -50,10 +82,13 @@
#else //ENABLE_COG
#define IF_COG(expr) (0)
#define COG_LOG_CATEGORY FNoLoggingCategory
#define COG_LOG_ABILITY(...) (0)
#define IF_COG(expr) (0)
#define COG_LOG_CATEGORY FNoLoggingCategory
#define COG_LOG_ABILITY(...) (0)
#define COG_NOTIFY(Format, ...) (0)
#define COG_NOTIFY_WARNING(Format, ...) (0)
#define COG_NOTIFY_ERROR(Format, ...) (0)
#define COG_NOTIFY_VERBOSITY(Verbosity, Format, ...) (0)
#define COG_LOG_ACTIVE_FOR_OBJECT(Object) (0)
#define COG_LOG(LogCategory, Verbosity, Format, ...) (0)
#define COG_LOG_FUNC(LogCategory, Verbosity, Format, ...) (0)
@@ -12,7 +12,6 @@ public:
UCogCommonConfig()
{
Reset();
}
virtual void Reset()
@@ -0,0 +1,5 @@
#pragma once
#include "Logging/LogMacros.h"
COGCOMMON_API DECLARE_LOG_CATEGORY_EXTERN(LogCogNotify, All, All);
+129 -105
View File
@@ -5,91 +5,33 @@
#include "CogDebugReplicator.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "imgui.h"
#include "Kismet/KismetMathLibrary.h"
#include "Misc/EngineVersionComparison.h"
//--------------------------------------------------------------------------------------------------------------------------
TWeakObjectPtr<AActor> FCogDebug::Selection[] = {};
TMap<int32, FCogDebugContext> FCogDebug::DebugContexts;
FCogDebugSettings FCogDebug::Settings = FCogDebugSettings();
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::Reset()
FCogDebugContext& FCogDebug::Get(const int32 InPieId)
{
Settings = FCogDebugSettings();
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World == nullptr)
if (InPieId == INDEX_NONE)
{
return true;
}
if (World->GetNetMode() == NM_DedicatedServer)
{
return true;
}
const bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection[GetPieSessionId()].Get(), Settings.bIsFilteringBySelection);
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsReplicatedDebugActiveForObject(const UObject* WorldContextObject, const AActor* ServerSelection, bool IsServerFilteringBySelection)
{
return IsDebugActiveForObject_Internal(WorldContextObject, ServerSelection, IsServerFilteringBySelection);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection)
{
if (InIsFilteringBySelection == false)
{
return true;
}
if (WorldContextObject == nullptr)
{
return true;
}
const AActor* SelectionPtr = InSelection;
if (SelectionPtr == nullptr)
{
return true;
}
const UObject* Outer = WorldContextObject;
for (;;)
{
if (SelectionPtr == Outer)
if (FCogDebugContext* Context = DebugContexts.Find(1))
{
return true;
return *Context;
}
if (Cast<ICogCommonDebugFilteredActorInterface>(Outer))
{
return false;
}
const UObject* NewOuter = Outer->GetOuter();
if (NewOuter == Outer || NewOuter == nullptr)
{
return true;
}
Outer = NewOuter;
}
FCogDebugContext& Context = DebugContexts.FindOrAdd(InPieId);
return Context;
}
//--------------------------------------------------------------------------------------------------------------------------
AActor* FCogDebug::GetSelection()
FCogDebugContext& FCogDebug::Get()
{
return Selection[GetPieSessionId()].Get();
const int32 PieId = GetPieSessionId();
return Get(PieId);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -108,31 +50,91 @@ int32 FCogDebug::GetPieSessionId()
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::SetSelection(const UWorld* World, AActor* Value)
void FCogDebug::Reset()
{
Selection[GetPieSessionId()] = Value;
Settings = FCogDebugSettings();
}
ReplicateSelection(World, Value);
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject)
{
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World == nullptr)
{ return true; }
if (World->GetNetMode() == NM_DedicatedServer)
{ return true; }
const bool Result = IsDebugActiveForObject_Internal(WorldContextObject, GetSelection(), Settings.bIsFilteringBySelection);
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsReplicatedDebugActiveForObject(const UObject* WorldContextObject, const AActor* ServerSelection, bool IsServerFilteringBySelection)
{
return IsDebugActiveForObject_Internal(WorldContextObject, ServerSelection, IsServerFilteringBySelection);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection)
{
if (InIsFilteringBySelection == false)
{ return true; }
if (WorldContextObject == nullptr)
{ return true; }
const AActor* SelectionPtr = InSelection;
if (SelectionPtr == nullptr)
{ return true; }
const UObject* Outer = WorldContextObject;
for (;;)
{
if (SelectionPtr == Outer)
{ return true; }
if (Cast<ICogCommonDebugFilteredActorInterface>(Outer))
{ return false; }
const UObject* NewOuter = Outer->GetOuter();
if (NewOuter == Outer || NewOuter == nullptr)
{ return true; }
Outer = NewOuter;
}
}
//--------------------------------------------------------------------------------------------------------------------------
AActor* FCogDebug::GetSelection()
{
return Get().Selection.Get();
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugTracker& FCogDebug::GetTracker()
{
return Get().Tracker;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::SetSelection(AActor* InValue)
{
Get().Selection = InValue;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::ReplicateSelection(const UWorld* World, AActor* Value)
{
if (World == nullptr)
{
return;
}
{ return; }
ACogDebugReplicator* Replicator = ACogDebugReplicator::GetLocalReplicator(*World);
if (Replicator == nullptr)
{
return;
}
{ return; }
if (Replicator->HasAuthority())
{
return;
}
{ return; }
Replicator->Server_SetSelection(Value, Settings.ReplicateSelection);
}
@@ -144,7 +146,7 @@ bool FCogDebug::GetIsFilteringBySelection()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::SetIsFilteringBySelection(UWorld* World, bool Value)
void FCogDebug::SetIsFilteringBySelection(const UWorld* World, bool Value)
{
Settings.bIsFilteringBySelection = Value;
@@ -173,13 +175,9 @@ float FCogDebug::GetDebugDuration(bool bPersistent)
float FCogDebug::GetDebugTextDuration(bool bPersistent)
{
if (bPersistent)
{
return Settings.Persistent ? 100 : Settings.Duration;
}
else
{
return 0.0f;
}
{ return Settings.Persistent ? 100 : Settings.Duration; }
return 0.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -191,7 +189,7 @@ int FCogDebug::GetDebugSegments()
//--------------------------------------------------------------------------------------------------------------------------
int FCogDebug::GetCircleSegments()
{
return (Settings.Segments * 2) + 2; // because DrawDebugCircle does Segments = FMath::Max((Segments - 2) / 2, 4) for some reason
return (Settings.Segments * 2) + 2; // because DrawDebugCircle do: Segments = FMath::Max((Segments - 2) / 2, 4) for some reason
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -216,14 +214,12 @@ uint8 FCogDebug::GetDebugDepthPriority(float InDepthPriority)
FColor FCogDebug::ModulateDebugColor(const UWorld* World, const FColor& Color, bool bPersistent)
{
if (bPersistent == false)
{
return Color;
}
{ return Color; }
switch (Settings.RecolorMode)
{
case ECogDebugRecolorMode::None:
{
{
return Color;
}
@@ -252,7 +248,7 @@ FColor FCogDebug::ModulateDebugColor(const UWorld* World, const FColor& Color, b
case ECogDebugRecolorMode::HueOverFrames:
{
const FLinearColor BaseColor(Color);
const float Factor = (Settings.RecolorFrameCycle > 0) ? (GFrameCounter % Settings.RecolorFrameCycle) / (float)Settings.RecolorFrameCycle : 0.0f;
const float Factor = (Settings.RecolorFrameCycle > 0) ? (GFrameCounter % Settings.RecolorFrameCycle) / static_cast<float>(Settings.RecolorFrameCycle) : 0.0f;
const FLinearColor NewColor(Factor * 360.0f, 1.0f, 1.0f);
const FLinearColor BlendColor = BaseColor * (1.0f - Settings.RecolorIntensity) + NewColor.HSVToLinearRGB() * Settings.RecolorIntensity;
return BlendColor.ToFColor(true);
@@ -286,9 +282,7 @@ bool FCogDebug::IsSecondarySkeletonBone(FName BoneName)
for (const FString& Wildcard : Settings.SecondaryBoneWildcards)
{
if (BoneString.MatchesWildcard(Wildcard))
{
return true;
}
{ return true; }
}
return false;
@@ -305,12 +299,6 @@ void FCogDebug::GetDebugChannelColors(FColor ChannelColors[ECC_MAX])
ChannelColors[ECC_PhysicsBody] = Settings.ChannelColorPhysicsBody;
ChannelColors[ECC_Vehicle] = Settings.ChannelColorVehicle;
ChannelColors[ECC_Destructible] = Settings.ChannelColorDestructible;
ChannelColors[ECC_EngineTraceChannel1] = Settings.ChannelColorEngineTraceChannel1;
ChannelColors[ECC_EngineTraceChannel2] = Settings.ChannelColorEngineTraceChannel2;
ChannelColors[ECC_EngineTraceChannel3] = Settings.ChannelColorEngineTraceChannel3;
ChannelColors[ECC_EngineTraceChannel4] = Settings.ChannelColorEngineTraceChannel4;
ChannelColors[ECC_EngineTraceChannel5] = Settings.ChannelColorEngineTraceChannel5;
ChannelColors[ECC_EngineTraceChannel6] = Settings.ChannelColorEngineTraceChannel6;
ChannelColors[ECC_GameTraceChannel1] = Settings.ChannelColorGameTraceChannel1;
ChannelColors[ECC_GameTraceChannel2] = Settings.ChannelColorGameTraceChannel2;
ChannelColors[ECC_GameTraceChannel3] = Settings.ChannelColorGameTraceChannel3;
@@ -368,4 +356,40 @@ void FCogDebug::GetDebugDrawSweepSettings(FCogDebugDrawSweepParams& Params)
GetDebugDrawLineTraceSettings(Params);
Params.DrawHitShapes = Settings.CollisionQueryDrawHitShapes;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::Plot(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const float Value)
{
Get().Tracker.Plot(WorldContextObject, InTrackId, Value);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebug::StartEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, bool IsInstant, const int32 Row, const FColor& Color)
{
return Get().Tracker.StartEvent(WorldContextObject, InTrackId, InEventId, IsInstant, Row, Color);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebug::InstantEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugTrackId& InEventId, const int32 Row, const FColor& Color)
{
return Get().Tracker.InstantEvent(WorldContextObject, InTrackId, InEventId, Row, Color);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebug::StartEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugTrackId& InEventId, const int32 Row, const FColor& Color)
{
return Get().Tracker.StartEvent(WorldContextObject, InTrackId, InEventId, Row, Color);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebug::StopEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugTrackId& InEventId)
{
return Get().Tracker.StopEvent(WorldContextObject, InTrackId, InEventId);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebug::ToggleEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugTrackId& InEventId, const bool ToggleValue, const int32 Row, const FColor& Color)
{
return Get().Tracker.ToggleEvent(WorldContextObject, InTrackId, InEventId, ToggleValue, Row, Color);
}
@@ -546,7 +546,7 @@ void FCogDebugDraw::Points(const FLogCategoryBase& LogCategory, const UObject* W
int32 Index = 0;
for (const FVector& Point : Points)
{
const FLinearColor Color = FLinearColor::LerpUsingHSV(FLinearColor(StartColor), FLinearColor(EndColor), Points.Num() <= 1 ? 0.0f : Index / (float)(Points.Num() - 1));
const FLinearColor Color = FLinearColor::LerpUsingHSV(FLinearColor(StartColor), FLinearColor(EndColor), Points.Num() <= 1 ? 0.0f : Index / static_cast<float>(Points.Num() - 1));
Sphere(LogCategory, WorldContextObject, Point, Radius, Color.ToFColor(true), Persistent, DepthPriority);
Index++;
}
@@ -577,7 +577,7 @@ void FCogDebugDraw::Path(const FLogCategoryBase& LogCategory, const UObject* Wor
int32 Index = 0;
for (const FVector& Position : Points)
{
const FLinearColor LinearColor = FLinearColor::LerpUsingHSV(FLinearColor(StartColor), FLinearColor(EndColor), Points.Num() <= 1 ? 0.0f : Index / (float)(Points.Num() - 1));
const FLinearColor LinearColor = FLinearColor::LerpUsingHSV(FLinearColor(StartColor), FLinearColor(EndColor), Points.Num() <= 1 ? 0.0f : Index / static_cast<float>(Points.Num() - 1));
FColor Color = LinearColor.ToFColor(true);
Point(LogCategory, WorldContextObject, Position, PointSize, Color, Persistent, DepthPriority);
@@ -622,7 +622,6 @@ void FCogDebugDraw::Skeleton(const FLogCategoryBase& LogCategory, const USkeleta
const FTransform Transform = ComponentSpaceTransforms[BoneIndex] * WorldTransform;
const FVector BoneLocation = Transform.GetLocation();
const FRotator BoneRotation = FRotator(Transform.GetRotation());
const int32 ParentIndex = ReferenceSkeleton.GetParentIndex(BoneIndex);
FVector ParentLocation;
@@ -703,7 +702,7 @@ void FCogDebugDraw::Sweep(const FLogCategoryBase& LogCategory, const UObject* Wo
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Overlap(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings)
void FCogDebugDraw::Overlap(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, const bool HasHits, TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings)
{
if (FCogDebugLog::IsLogCategoryActive(LogCategory) == false)
{ return; }
@@ -712,7 +711,7 @@ void FCogDebugDraw::Overlap(const FLogCategoryBase& LogCategory, const UObject*
if (World == nullptr)
{ return; }
FCogDebugDrawHelper::DrawOverlap(World, Shape, Location, Rotation, OverlapResults, Settings);
FCogDebugDrawHelper::DrawOverlap(World, Shape, Location, Rotation, HasHits, OverlapResults, Settings);
const FColor Color = OverlapResults.Num() > 0
? Settings.HitColor
@@ -78,7 +78,7 @@ void FCogDebugDrawHelper::DrawArc(
}
float CurrentAngle = AngleStartRad;
const float AngleStep = (AngleEndRad - AngleStartRad) / float(Segments);
const float AngleStep = (AngleEndRad - AngleStartRad) / static_cast<float>(Segments);
FVector PrevVertex = Center + OuterRadius * (AxisZ * FMath::Sin(CurrentAngle) + AxisY * FMath::Cos(CurrentAngle));
int32 Count = Segments;
while (Count--)
@@ -94,7 +94,6 @@ void FCogDebugDrawHelper::DrawArc(
CurrentAngle = AngleStartRad;
PrevVertex = Center + InnerRadius * (AxisZ * FMath::Sin(CurrentAngle) + AxisY * FMath::Cos(CurrentAngle));
Count = Segments;
while (Segments--)
{
CurrentAngle += AngleStep;
@@ -189,8 +188,8 @@ void FCogDebugDrawHelper::DrawFrustum(
const float HozHalfAngleInRadians = FMath::DegreesToRadians(Angle * 0.5f);
float HozLength = 0.0f;
float VertLength = 0.0f;
float HozLength;
float VertLength;
if (Angle > 0.0f)
{
@@ -398,7 +397,7 @@ void FCogDebugDrawHelper::DrawLineTrace(
const FVector& Start,
const FVector& End,
const bool HasHits,
TArray<FHitResult>& HitResults,
const TArray<FHitResult>& HitResults,
const FCogDebugDrawLineTraceParams& Settings
)
{
@@ -460,11 +459,12 @@ void FCogDebugDrawHelper::DrawOverlap(
const FCollisionShape& Shape,
const FVector& Location,
const FQuat& Rotation,
TArray<FOverlapResult>& OverlapResults,
const bool HasHits,
const TArray<FOverlapResult>& OverlapResults,
const FCogDebugDrawOverlapParams& Settings
)
{
const FColor Color = OverlapResults.Num() > 0 ? Settings.HitColor : Settings.NoHitColor;
const FColor Color = HasHits ? Settings.HitColor : Settings.NoHitColor;
DrawShape(World, Shape, Location, Rotation, FVector::OneVector, Color, Settings.Persistent, Settings.LifeTime, Settings.DepthPriority, Settings.Thickness);
if (Settings.DrawHitPrimitives)
@@ -3,6 +3,7 @@
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
float FCogDebugDrawImGui::Time = 0;
TArray<FCogDebugDrawImGui::FLine> FCogDebugDrawImGui::Lines;
TArray<FCogDebugDrawImGui::FTriangle> FCogDebugDrawImGui::Triangles;
TArray<FCogDebugDrawImGui::FTriangle> FCogDebugDrawImGui::TrianglesFilled;
@@ -22,7 +23,7 @@ void FCogDebugDrawImGui::AddLine(const ImVec2& P1, const ImVec2& P2, ImU32 Color
Line.P2 = P2;
Line.Color = Color;
Line.Thickness = Thickness;
Line.Time = ImGui::GetCurrentContext()->Time;
Line.Time = Time;
Line.Duration = Duration;
Line.FadeColor = FadeColor;
Lines.Add_GetRef(Line);
@@ -37,7 +38,7 @@ void FCogDebugDrawImGui::AddRect(const ImVec2& Min, const ImVec2& Max, ImU32 Col
Rectangle.Color = Color;
Rectangle.Rounding = Rounding;
Rectangle.Thickness = Thickness;
Rectangle.Time = ImGui::GetCurrentContext()->Time;
Rectangle.Time = Time;
Rectangle.Duration = Duration;
Rectangle.FadeColor = FadeColor;
Rectangles.Add_GetRef(Rectangle);
@@ -52,7 +53,7 @@ void FCogDebugDrawImGui::AddRectFilled(const ImVec2& Min, const ImVec2& Max, ImU
Rectangle.Color = Color;
Rectangle.Rounding = Rounding;
Rectangle.Thickness = 0.0f;
Rectangle.Time = ImGui::GetCurrentContext()->Time;
Rectangle.Time = Time;
Rectangle.Duration = Duration;
Rectangle.FadeColor = FadeColor;
RectanglesFilled.Add_GetRef(Rectangle);
@@ -68,7 +69,7 @@ void FCogDebugDrawImGui::AddQuad(const ImVec2& P1, const ImVec2& P2, const ImVec
Quad.P4 = P4;
Quad.Color = Color;
Quad.Thickness = Thickness;
Quad.Time = ImGui::GetCurrentContext()->Time;
Quad.Time = Time;
Quad.Duration = Duration;
Quad.FadeColor = FadeColor;
Quads.Add_GetRef(Quad);
@@ -84,7 +85,7 @@ void FCogDebugDrawImGui::AddQuadFilled(const ImVec2& P1, const ImVec2& P2, const
Quad.P4 = P4;
Quad.Color = Color;
Quad.Thickness = 0.0f;
Quad.Time = ImGui::GetCurrentContext()->Time;
Quad.Time = Time;
Quad.Duration = Duration;
Quad.FadeColor = FadeColor;
QuadsFilled.Add_GetRef(Quad);
@@ -99,7 +100,7 @@ void FCogDebugDrawImGui::AddTriangle(const ImVec2& P1, const ImVec2& P2, const I
Triangle.P3 = P3;
Triangle.Color = Color;
Triangle.Thickness = Thickness;
Triangle.Time = ImGui::GetCurrentContext()->Time;
Triangle.Time = Time;
Triangle.Duration = Duration;
Triangle.FadeColor = FadeColor;
Triangles.Add_GetRef(Triangle);
@@ -114,7 +115,7 @@ void FCogDebugDrawImGui::AddTriangleFilled(const ImVec2& P1, const ImVec2& P2, c
Triangle.P3 = P3;
Triangle.Color = Color;
Triangle.Thickness = 0.0f;
Triangle.Time = ImGui::GetCurrentContext()->Time;
Triangle.Time = Time;
Triangle.Duration = Duration;
Triangle.FadeColor = FadeColor;
TrianglesFilled.Add_GetRef(Triangle);
@@ -123,13 +124,14 @@ void FCogDebugDrawImGui::AddTriangleFilled(const ImVec2& P1, const ImVec2& P2, c
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDrawImGui::AddCircle(const ImVec2& Center, float Radius, ImU32 Color, int Segments /*= 0*/, float Thickness /*= 1.0f*/, float Duration /*= 0.0f*/, bool FadeColor /*= false*/)
{
FCircle Circle;
Circle.Center = Center;
Circle.Radius = Radius > 0.0f ? Radius : 1.0f;
Circle.Color = Color;
Circle.Segments = Segments;
Circle.Thickness = Thickness;
Circle.Time = ImGui::GetCurrentContext()->Time;
Circle.Time = Time;
Circle.Duration = Duration;
Circle.FadeColor = FadeColor;
Circles.Add_GetRef(Circle);
@@ -144,7 +146,7 @@ void FCogDebugDrawImGui::AddCircleFilled(const ImVec2& Center, float Radius, ImU
Circle.Color = Color;
Circle.Segments = Segments;
Circle.Thickness = 0.0f;
Circle.Time = ImGui::GetCurrentContext()->Time;
Circle.Time = Time;
Circle.Duration = Duration;
Circle.FadeColor = FadeColor;
CirclesFilled.Add_GetRef(Circle);
@@ -157,7 +159,7 @@ void FCogDebugDrawImGui::AddText(const ImVec2& Pos, const FString& Text, ImU32 C
TextElement.Pos = Pos;
TextElement.Text = Text;
TextElement.Color = Color;
TextElement.Time = ImGui::GetCurrentContext()->Time;
TextElement.Time = Time;
TextElement.Duration = Duration;
TextElement.FadeColor = FadeColor;
Texts.Add_GetRef(TextElement);
@@ -169,7 +171,7 @@ void FCogDebugDrawImGui::AddText(const ImVec2& Pos, const FString& Text, ImU32 C
ShadowTextElement.Text = Text;
const float Alpha = ImGui::ColorConvertU32ToFloat4(Color).w; // Keep original Alpha and set to black
ShadowTextElement.Color = ImGui::ColorConvertFloat4ToU32(ImVec4(0, 0, 0, Alpha));
ShadowTextElement.Time = ImGui::GetCurrentContext()->Time;
ShadowTextElement.Time = Time;
ShadowTextElement.Duration = Duration;
ShadowTextElement.FadeColor = FadeColor;
Texts.Add_GetRef(ShadowTextElement);
@@ -181,7 +183,7 @@ void FCogDebugDrawImGui::AddText(const ImVec2& Pos, const FString& Text, ImU32 C
void FCogDebugDrawImGui::Draw()
{
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
double Time = ImGui::GetCurrentContext()->Time;
Time = ImGui::GetCurrentContext()->Time;
DrawShapes(Lines, [DrawList](const FLine& Line, const ImColor Color) { DrawList->AddLine(Line.P1, Line.P2, Color, Line.Thickness); });
DrawShapes(Rectangles, [DrawList](const FRectangle& Rectangle, const ImColor Color) { DrawList->AddRect(Rectangle.Min, Rectangle.Max, Color, Rectangle.Rounding, Rectangle.Thickness); });
@@ -0,0 +1,77 @@
#include "CogDebugEvent.h"
#include "CogDebugTrack.h"
#include "CogDebugTracker.h"
//--------------------------------------------------------------------------------------------------------------------------
float FCogDebugEvent::GetActualEndTime(const UWorld& World) const
{
if (EndTime != 0.0f)
{ return EndTime; }
const float WorldTime = World.GetTimeSeconds();
return WorldTime;
}
//--------------------------------------------------------------------------------------------------------------------------
uint64 FCogDebugEvent::GetActualEndFrame() const
{
const float ActualEndFame = EndFrame != 0.0f ? EndFrame : GFrameCounter;
return ActualEndFame;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEvent::AddParam(const FCogDebugEventParamId& InParamId, bool InValue)
{
if (Track == nullptr || Track->Owner == nullptr || Track->Owner->IsVisible == false)
{ return *this; }
return AddParam(InParamId, FString::Printf(TEXT("%s"), InValue ? TEXT("True") : TEXT("False")));
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEvent::AddParam(const FCogDebugEventParamId& InParamId, int InValue)
{
if (Track == nullptr || Track->Owner == nullptr || Track->Owner->IsVisible == false)
{ return *this; }
return AddParam(InParamId, FString::Printf(TEXT("%d"), InValue));
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEvent::AddParam(const FCogDebugEventParamId& InParamId, float InValue)
{
if (Track == nullptr || Track->Owner == nullptr || Track->Owner->IsVisible == false)
{ return *this; }
return AddParam(InParamId, FString::Printf(TEXT("%0.2f"), InValue));
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEvent::AddParam(const FCogDebugEventParamId& InParamId, FName InValue)
{
if (Track == nullptr || Track->Owner == nullptr || Track->Owner->IsVisible == false)
{ return *this; }
return AddParam(InParamId, InValue.ToString());
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEvent::AddParam(const FCogDebugEventParamId& InParamId, const FString& InValue)
{
if (Track == nullptr || Track->Owner == nullptr || Track->Owner->IsVisible == false)
{ return *this; }
if (InParamId == "Name")
{
DisplayName = InValue;
}
else
{
FCogDebugEventParams& Param = Params.AddDefaulted_GetRef();
Param.Name = InParamId;
Param.Value = InValue;
}
return *this;
}
@@ -0,0 +1,144 @@
#include "CogDebugEventTrack.h"
#include "CogDebugTracker.h"
#include "CogDebugHelper.h"
#include "CogImguiHelper.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEventTrack::AddEvent(
const FString& OwnerName,
const bool IsInstant,
const FName EventId,
const int32 Row,
const FColor& Color)
{
if (Events.Max() < 200)
{
Events.Reserve(200);
}
//----------------------------
// Stop if it already exist.
//----------------------------
StopEvent(EventId);
FCogDebugEvent* Event;
int32 AddedIndex;
if (Events.Num() < Events.Max())
{
Event = &Events.AddDefaulted_GetRef();
AddedIndex = Events.Num() - 1;
}
else
{
Event = &Events[EventOffset];
AddedIndex = EventOffset;
EventOffset = (EventOffset + 1) % Events.Num();
}
Event->Id = EventId;
Event->OwnerName = OwnerName;
Event->DisplayName = EventId.ToString();
Event->StartTime = Time;
Event->EndTime = IsInstant ? Time : 0.0f;
Event->StartFrame = Frame;
Event->EndFrame = IsInstant ? Frame : 0.0f;
Event->Row = (Row == FCogDebugTracker::AutoRow) ? Owner->FindFreeViewRow(GraphIndex) : Row;
if (IsInstant == false)
{
Owner->OccupyViewRow(GraphIndex, Event->Row);
}
MaxRow = FMath::Max(Event->Row, MaxRow);
const FColor BorderColor = FCogDebugHelper::GetAutoColor(EventId, Color).WithAlpha(200);
const FColor FillColor = BorderColor.WithAlpha(100);
Event->BorderColor = FCogImguiHelper::ToImColor(BorderColor);
Event->FillColor = FCogImguiHelper::ToImColor(FillColor);
Owner->LastAddedEventTrackId = Id;
Owner->LastAddedEventIndex = AddedIndex;
return *Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugEventTrack::StopEvent(const FCogDebugEventId EventId)
{
FCogDebugEvent* Event = FindLastEventByName(EventId);
if (Event == nullptr)
{
return Owner->DefaultEvent;
}
if (Event->EndTime == 0.0f)
{
Event->EndTime = Time;
Event->EndFrame = Frame;
Owner->FreeViewRow(GraphIndex, Event->Row);
}
return *Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent* FCogDebugEventTrack::GetLastEvent()
{
if (Events.Num() == 0)
{
return nullptr;
}
int32 Index = Events.Num() - 1;
if (EventOffset != 0)
{
Index = (Index + EventOffset) % Events.Num();
}
return &Events[Index];
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent* FCogDebugEventTrack::FindLastEventByName(FCogDebugEventId EventId)
{
for (int32 i = Events.Num() - 1; i >= 0; --i)
{
//--------------------------------------------------
// The array cycle so we must offset the index
//--------------------------------------------------
int32 Index = i;
if (EventOffset != 0)
{
Index = (i + EventOffset) % Events.Num();
}
if (Events[Index].Id == EventId)
{
return &Events[Index];
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugEventTrack::Clear()
{
FCogDebugTrack::Clear();
Owner->ResetLastAddedEvent();
MaxRow = 0;
if (Events.Num() > 0)
{
Events.Empty();
Events.Shrink();
EventOffset = 0;
}
}
@@ -3,12 +3,12 @@
#include "CogDebug.h"
#include "CogDebugDrawHelper.h"
#include "CogImguiHelper.h"
#include "DrawDebugHelpers.h"
#include "imgui.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SceneComponent.h"
#include "DrawDebugHelpers.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "imgui.h"
#include "Kismet/GameplayStatics.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -74,11 +74,11 @@ float ScreenDistanceToArc(const APlayerController& InPlayerController, const FVe
const FVector AxisZ = Matrix.GetScaledAxis(EAxis::Z);
float CurrentAngle = AngleStartRad;
const float AngleStep = (AngleEndRad - AngleStartRad) / float(NumSegments);
const float AngleStep = (AngleEndRad - AngleStartRad) / static_cast<float>(NumSegments);
FVector P0 = Center + Radius * (AxisZ * FMath::Sin(CurrentAngle) + AxisY * FMath::Cos(CurrentAngle));
FVector2D ScreenP0;
FVector2D ScreenP0;
UGameplayStatics::ProjectWorldToScreen(&InPlayerController, P0, ScreenP0);
float MinDistanceSqr = FLT_MAX;
@@ -163,14 +163,14 @@ void DrawGizmoText(const ImVec2& Position, ImU32 Color, const char* Text)
bool RenderComponent(const char* Label, double* Value, double Reset)
{
ImGui::TableNextColumn();
ImGui::PushItemWidth(-1);
ImGui::PushItemWidth(-1);
bool Result = FCogImguiHelper::DragDouble(Label, Value, 0.1f, 0.0f, 0.0f, "%.1f");
if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
*Value = Reset;
Result = true;
}
ImGui::PopItemWidth();
}
ImGui::PopItemWidth();
return Result;
}
@@ -240,7 +240,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const float GizmoScale = Settings.GizmoScale * ScaleToKeepGizmoScreenSizeConstant;
const FQuat RotX = Settings.GizmoUseLocalSpace ? InOutTransform.GetRotation() : FQuat(FVector(0.0f, 0.0f, 1.0f), 0.0f);
const FQuat RotY = RotX * FQuat(FVector(0.0f, 0.0f,-1.0f), UE_HALF_PI);
const FQuat RotY = RotX * FQuat(FVector(0.0f, 0.0f, -1.0f), UE_HALF_PI);
const FQuat RotZ = RotX * FQuat(FVector(0.0f, 1.0f, 0.0f), UE_HALF_PI);
const FVector UnitAxisX = Settings.GizmoUseLocalSpace ? RotX.GetAxisX() : FVector::XAxisVector;
@@ -255,11 +255,11 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const ImVec2 ImMousePos = ImGui::GetMousePos() - Viewport->Pos;
const FVector2D MousePos = FCogImguiHelper::ToFVector2D(ImMousePos);
const FColor GizmoAxisColorsZLow[] = { Settings.GizmoAxisColorsZLowX, Settings.GizmoAxisColorsZLowY, Settings.GizmoAxisColorsZLowZ, Settings.GizmoAxisColorsZLowW };
const FColor GizmoAxisColorsZHigh[] = { Settings.GizmoAxisColorsZHighX, Settings.GizmoAxisColorsZHighY, Settings.GizmoAxisColorsZHighZ, Settings.GizmoAxisColorsZHighW };
const FColor GizmoAxisColorsSelection[] = { Settings.GizmoAxisColorsSelectionX, Settings.GizmoAxisColorsSelectionY, Settings.GizmoAxisColorsSelectionZ, Settings.GizmoAxisColorsSelectionW };
const FColor GizmoAxisColorsZLow[] = {Settings.GizmoAxisColorsZLowX, Settings.GizmoAxisColorsZLowY, Settings.GizmoAxisColorsZLowZ, Settings.GizmoAxisColorsZLowW};
const FColor GizmoAxisColorsZHigh[] = {Settings.GizmoAxisColorsZHighX, Settings.GizmoAxisColorsZHighY, Settings.GizmoAxisColorsZHighZ, Settings.GizmoAxisColorsZHighW};
const FColor GizmoAxisColorsSelection[] = {Settings.GizmoAxisColorsSelectionX, Settings.GizmoAxisColorsSelectionY, Settings.GizmoAxisColorsSelectionZ, Settings.GizmoAxisColorsSelectionW};
FCogDebug_GizmoElement GizmoElements[(uint8)ECogDebug_GizmoElementType::MAX];
FCogDebug_GizmoElement GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MAX)];
for (FCogDebug_GizmoElement& GizmoElement : GizmoElements)
{
GizmoElement.Type = ECogDebug_GizmoType::MAX;
@@ -267,35 +267,35 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
if (EnumHasAnyFlags(Flags, ECogDebug_GizmoFlags::NoTranslationAxis) == false)
{
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveX] = { ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + UnitAxisX * Settings.GizmoTranslationAxisLength * GizmoScale };
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveY] = { ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + UnitAxisY * Settings.GizmoTranslationAxisLength * GizmoScale };
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveZ] = { ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + UnitAxisZ * Settings.GizmoTranslationAxisLength * GizmoScale };
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveX)] = {ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + UnitAxisX * Settings.GizmoTranslationAxisLength * GizmoScale};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveY)] = {ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + UnitAxisY * Settings.GizmoTranslationAxisLength * GizmoScale};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveZ)] = {ECogDebug_GizmoType::MoveAxis, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + UnitAxisZ * Settings.GizmoTranslationAxisLength * GizmoScale};
}
if (EnumHasAnyFlags(Flags, ECogDebug_GizmoFlags::NoTranslationPlane) == false)
{
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveXY] = { ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + ((UnitAxisX + UnitAxisY) * Settings.GizmoTranslationPlaneOffset * GizmoScale) };
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveXZ] = { ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + ((UnitAxisX + UnitAxisZ) * Settings.GizmoTranslationPlaneOffset * GizmoScale) };
GizmoElements[(uint8)ECogDebug_GizmoElementType::MoveYZ] = { ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + ((UnitAxisY + UnitAxisZ) * Settings.GizmoTranslationPlaneOffset * GizmoScale) };
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveXY)] = {ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + ((UnitAxisX + UnitAxisY) * Settings.GizmoTranslationPlaneOffset * GizmoScale)};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveXZ)] = {ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + ((UnitAxisX + UnitAxisZ) * Settings.GizmoTranslationPlaneOffset * GizmoScale)};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::MoveYZ)] = {ECogDebug_GizmoType::MovePlane, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + ((UnitAxisY + UnitAxisZ) * Settings.GizmoTranslationPlaneOffset * GizmoScale)};
}
if (EnumHasAnyFlags(Flags, ECogDebug_GizmoFlags::NoRotation) == false)
{
GizmoElements[(uint8)ECogDebug_GizmoElementType::RotateX] = { ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, FVector::ZeroVector };
GizmoElements[(uint8)ECogDebug_GizmoElementType::RotateY] = { ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, FVector::ZeroVector };
GizmoElements[(uint8)ECogDebug_GizmoElementType::RotateZ] = { ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, FVector::ZeroVector };
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::RotateX)] = {ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, FVector::ZeroVector};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::RotateY)] = {ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, FVector::ZeroVector};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::RotateZ)] = {ECogDebug_GizmoType::Rotate, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, FVector::ZeroVector};
}
if (EnumHasAnyFlags(Flags, ECogDebug_GizmoFlags::NoScaleUniform) == false)
{
GizmoElements[(uint8)ECogDebug_GizmoElementType::ScaleXYZ] = { ECogDebug_GizmoType::ScaleUniform, ECogDebug_GizmoAxis::MAX, FVector::OneVector, FVector::OneVector, RotX, GizmoCenter };
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::ScaleXYZ)] = {ECogDebug_GizmoType::ScaleUniform, ECogDebug_GizmoAxis::MAX, FVector::OneVector, FVector::OneVector, RotX, GizmoCenter};
}
if (EnumHasAnyFlags(Flags, ECogDebug_GizmoFlags::NoScaleAxis) == false)
{
GizmoElements[(uint8)ECogDebug_GizmoElementType::ScaleX] = { ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + UnitAxisX * Settings.GizmoScaleBoxOffset * GizmoScale };
GizmoElements[(uint8)ECogDebug_GizmoElementType::ScaleY] = { ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + UnitAxisY * Settings.GizmoScaleBoxOffset * GizmoScale };
GizmoElements[(uint8)ECogDebug_GizmoElementType::ScaleZ] = { ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + UnitAxisZ * Settings.GizmoScaleBoxOffset * GizmoScale };
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::ScaleX)] = {ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::X, FVector::XAxisVector, UnitAxisX, RotX, GizmoCenter + UnitAxisX * Settings.GizmoScaleBoxOffset * GizmoScale};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::ScaleY)] = {ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::Y, FVector::YAxisVector, UnitAxisY, RotY, GizmoCenter + UnitAxisY * Settings.GizmoScaleBoxOffset * GizmoScale};
GizmoElements[static_cast<uint8>(ECogDebug_GizmoElementType::ScaleZ)] = {ECogDebug_GizmoType::ScaleAxis, ECogDebug_GizmoAxis::Z, FVector::ZAxisVector, UnitAxisZ, RotZ, GizmoCenter + UnitAxisZ * Settings.GizmoScaleBoxOffset * GizmoScale};
}
ECogDebug_GizmoElementType HoveredElementType = ECogDebug_GizmoElementType::MAX;
@@ -306,7 +306,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
else if (IO.WantCaptureMouse == false)
{
float MinDistanceToMouse = FLT_MAX;
for (uint8 i = (uint8)ECogDebug_GizmoElementType::MoveX; i < (uint8)ECogDebug_GizmoElementType::MAX; ++i)
for (uint8 i = static_cast<uint8>(ECogDebug_GizmoElementType::MoveX); i < static_cast<uint8>(ECogDebug_GizmoElementType::MAX); ++i)
{
FCogDebug_GizmoElement& Elm = GizmoElements[i];
float DistanceToMouse = FLT_MAX;
@@ -340,22 +340,22 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
break;
}
default:;
default: ;
}
if (DistanceToMouse < Settings.GizmoCursorSelectionThreshold && DistanceToMouse < MinDistanceToMouse)
{
HoveredElementType = (ECogDebug_GizmoElementType)i;
HoveredElementType = static_cast<ECogDebug_GizmoElementType>(i);
MinDistanceToMouse = DistanceToMouse;
}
}
}
for (uint8 i = (uint8)ECogDebug_GizmoElementType::MoveX; i < (uint8)ECogDebug_GizmoElementType::MAX; ++i)
for (uint8 i = static_cast<uint8>(ECogDebug_GizmoElementType::MoveX); i < static_cast<uint8>(ECogDebug_GizmoElementType::MAX); ++i)
{
const FCogDebug_GizmoElement& Elm = GizmoElements[i];
const bool IsClosestToMouse = i == (uint8)HoveredElementType;
const uint8 AxisIndex = (uint8)Elm.AxisType;
const bool IsClosestToMouse = i == static_cast<uint8>(HoveredElementType);
const uint8 AxisIndex = static_cast<uint8>(Elm.AxisType);
const FColor ZLowColor = IsClosestToMouse ? GizmoAxisColorsSelection[AxisIndex] : GizmoAxisColorsZLow[AxisIndex];
const FColor ZHighColor = IsClosestToMouse ? GizmoAxisColorsSelection[AxisIndex] : GizmoAxisColorsZHigh[AxisIndex];
@@ -394,7 +394,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
break;
}
default:
default:
break;
}
}
@@ -409,7 +409,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const FRotationTranslationMatrix Matrix(FRotator(90.0f, 0, 0), GroundHit.ImpactPoint);
FCogDebugDrawHelper::DrawArc(World, Matrix, Settings.GizmoGroundRaycastCircleRadius, Settings.GizmoGroundRaycastCircleRadius, 0.0f, 360.0f, 24, Settings.GizmoGroundRaycastCircleColor, false, 0.0f, Settings.GizmoZLow, ThicknessZLow);
}
DrawDebugLine(World, GizmoCenter, Bottom, Settings.GizmoGroundRaycastColor, false, 0.0f, Settings.GizmoZLow, ThicknessZLow);
DrawDebugLine(World, GizmoCenter, Bottom, Settings.GizmoGroundRaycastColor, false, 0.0f, Settings.GizmoZLow, ThicknessZLow);
}
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
@@ -418,18 +418,18 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
}
else if (DraggedElementType != ECogDebug_GizmoElementType::MAX)
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
{
InOutTransform = InitialTransform;
DraggedElementType = ECogDebug_GizmoElementType::MAX;
}
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, Settings.GizmoCursorDraggingThreshold))
{
const FCogDebug_GizmoElement& DraggedElement = GizmoElements[(uint8)DraggedElementType];
const FCogDebug_GizmoElement& DraggedElement = GizmoElements[static_cast<uint8>(DraggedElementType)];
switch (DraggedElement.Type)
{
case ECogDebug_GizmoType::MoveAxis:
case ECogDebug_GizmoType::MoveAxis:
{
const FVector CursorOnLine = GetMouseCursorOnLine(InPlayerController, InitialTransform.GetTranslation(), DraggedElement.Direction, MousePos - CursorOffset);
const float Delta = FVector::DotProduct(DraggedElement.Direction, CursorOnLine - InitialTransform.GetTranslation());
@@ -472,8 +472,8 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
//DrawDebugPoint(World, InitialTransform.GetTranslation(), 5.0f, FColor::White);
//DrawDebugLine(World, InitialTransform.GetTranslation(), InitialTransform.GetTranslation() + WorldDeltaU, FColor::White);
//DrawDebugLine(World, InitialTransform.GetTranslation() + WorldDeltaU, InitialTransform.GetTranslation() + WorldDeltaU + WorldDeltaV, FColor::White);
//DrawDebugLine(World, InitialTransform.GetTranslation(), InitialTransform.GetTranslation() + WorldDeltaU, FColor::White);
//DrawDebugLine(World, InitialTransform.GetTranslation() + WorldDeltaU, InitialTransform.GetTranslation() + WorldDeltaU + WorldDeltaV, FColor::White);
break;
}
@@ -485,7 +485,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
const float NormalizedAngle = FRotator::NormalizeAxis(DragAmount * Settings.GizmoRotationSpeed);
const float SnappedAngle = FMath::GridSnap(NormalizedAngle, Settings.GizmoRotationSnapEnable ? Settings.GizmoRotationSnapValue : 0.0f);
const FQuat RotDelta(-DraggedElement.Axis, FMath::DegreesToRadians(SnappedAngle));
const FQuat NewRot = (Settings.GizmoUseLocalSpace) ? InitialTransform.GetRotation() * RotDelta : RotDelta * InitialTransform.GetRotation();
const FQuat NewRot = (Settings.GizmoUseLocalSpace) ? InitialTransform.GetRotation() * RotDelta : RotDelta * InitialTransform.GetRotation();
InOutTransform.SetRotation(NewRot);
Result = true;
@@ -526,84 +526,136 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
break;
}
default:
default:
break;
}
}
}
else if (HoveredElementType != ECogDebug_GizmoElementType::MAX)
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
DraggedElementType = HoveredElementType;
DraggedElementType = HoveredElementType;
CursorOffset = MousePos - Center2D;
InitialTransform = InOutTransform;
}
//else if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
//{
// ImGui::OpenPopup(Id);
//}
else if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
{
if (Settings.GizmoSupportContextMenu)
{
ImGui::OpenPopup(Id);
}
}
}
//if (ImGui::BeginPopup(Id))
//{
// FVector Translation = InOutTransform.GetTranslation();
// FRotator Rotation = InOutTransform.GetRotation().Rotator();
// FVector Scale = InOutTransform.GetScale3D();
if (Settings.GizmoSupportContextMenu)
{
if (ImGui::BeginPopup(Id))
{
FVector Translation = InOutTransform.GetTranslation();
FRotator Rotation = InOutTransform.GetRotation().Rotator();
FVector Scale = InOutTransform.GetScale3D();
// ImGui::Checkbox("Local Space", &Settings.GizmoUseLocalSpace);
ImGui::Checkbox("Local Space", &Settings.GizmoUseLocalSpace);
// ImGui::Separator();
ImGui::Separator();
// ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(1.0f, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(1.0f, 1.0f));
// if (ImGui::BeginTable("Pools", 6, ImGuiTableFlags_SizingFixedFit))
// {
// ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 5);
// ImGui::TableSetupColumn("X", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Y", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Z", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("SnapEnable", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
// ImGui::TableSetupColumn("Snap", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 3);
if (ImGui::BeginTable("Pools", 6, ImGuiTableFlags_SizingFixedFit))
{
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 5);
ImGui::TableSetupColumn("X", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Y", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Z", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("SnapEnable", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 4);
ImGui::TableSetupColumn("Snap", ImGuiTableColumnFlags_WidthFixed, ImGui::GetFontSize() * 3);
// ImGui::PushID("Location");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Location");
// if (RenderComponent("##X", &Translation.X, 0.0)) { InOutTransform.SetTranslation(Translation); }
// if (RenderComponent("##Y", &Translation.Y, 0.0)) { InOutTransform.SetTranslation(Translation); }
// if (RenderComponent("##Z", &Translation.Z, 0.0)) { InOutTransform.SetTranslation(Translation); }
// RenderSnap(&Settings.GizmoTranslationSnapEnable, &Settings.GizmoTranslationSnapValue);
// ImGui::PopID();
ImGui::PushID("Location");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Location");
bool Translate = false;
Translate |= RenderComponent("##X", &Translation.X, 0.0);
Translate |= RenderComponent("##Y", &Translation.Y, 0.0);
Translate |= RenderComponent("##Z", &Translation.Z, 0.0);
if (Translate)
{
if (Settings.GizmoTranslationSnapEnable)
{
Translation.X = FMath::GridSnap(Translation.X, Settings.GizmoTranslationSnapValue);
Translation.Y = FMath::GridSnap(Translation.Y, Settings.GizmoTranslationSnapValue);
Translation.Z = FMath::GridSnap(Translation.Z, Settings.GizmoTranslationSnapValue);
}
InOutTransform.SetTranslation(Translation);
Result = true;
}
RenderSnap(&Settings.GizmoTranslationSnapEnable, &Settings.GizmoTranslationSnapValue);
ImGui::PopID();
// ImGui::PushID("Rotation");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Rotation");
// if (RenderComponent("##X", &Rotation.Yaw, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// if (RenderComponent("##Y", &Rotation.Pitch, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// if (RenderComponent("##Z", &Rotation.Roll, 0.0)) { InOutTransform.SetRotation(Rotation.Quaternion()); }
// RenderSnap(&Settings.GizmoRotationSnapEnable, &Settings.GizmoRotationSnapValue);
// ImGui::PopID();
ImGui::PushID("Rotation");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Rotation");
// ImGui::PushID("Scale");
// ImGui::TableNextRow();
// ImGui::TableNextColumn();
// ImGui::Text("Scale");
// if (RenderComponent("##X", &Scale.X, 0.0)) { InOutTransform.SetScale3D(Scale); }
// if (RenderComponent("##Y", &Scale.Y, 0.0)) { InOutTransform.SetScale3D(Scale); }
// if (RenderComponent("##Z", &Scale.Z, 0.0)) { InOutTransform.SetScale3D(Scale); }
// RenderSnap(&Settings.GizmoScaleSnapEnable, &Settings.GizmoScaleSnapValue);
// ImGui::PopID();
bool Rotate = false;
Rotate |= RenderComponent("##X", &Rotation.Yaw, 0.0);
Rotate |= RenderComponent("##Y", &Rotation.Pitch, 0.0);
Rotate |= RenderComponent("##Z", &Rotation.Roll, 0.0);
// ImGui::EndTable();
// }
if (Rotate)
{
if (Settings.GizmoRotationSnapEnable)
{
Rotation.Yaw = FMath::GridSnap(Rotation.Yaw, Settings.GizmoRotationSnapValue);
Rotation.Pitch = FMath::GridSnap(Rotation.Pitch, Settings.GizmoRotationSnapValue);
Rotation.Roll = FMath::GridSnap(Rotation.Roll, Settings.GizmoRotationSnapValue);
}
InOutTransform.SetRotation(Rotation.Quaternion());
Result = true;
}
RenderSnap(&Settings.GizmoRotationSnapEnable, &Settings.GizmoRotationSnapValue);
ImGui::PopID();
// ImGui::PopStyleVar();
ImGui::PushID("Scale");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Scale");
// ImGui::EndPopup();
//}
bool Rescale = false;
Rescale |= RenderComponent("##X", &Scale.X, 1.0);
Rescale |= RenderComponent("##Y", &Scale.Y, 1.0);
Rescale |= RenderComponent("##Z", &Scale.Z, 1.0);
if (Rescale)
{
if (Settings.GizmoScaleSnapEnable)
{
Scale.X = FMath::GridSnap(Scale.X, Settings.GizmoScaleSnapValue);
Scale.Y = FMath::GridSnap(Scale.Y, Settings.GizmoScaleSnapValue);
Scale.Z = FMath::GridSnap(Scale.Z, Settings.GizmoScaleSnapValue);
}
InOutTransform.SetScale3D(Scale);
Result = true;
}
RenderSnap(&Settings.GizmoScaleSnapEnable, &Settings.GizmoScaleSnapValue);
ImGui::PopID();
ImGui::EndTable();
}
ImGui::PopStyleVar();
ImGui::EndPopup();
}
}
return Result;
}
@@ -12,8 +12,8 @@ FColor FCogDebugHelper::GetAutoColor(FName Name, const FColor& UserColor)
const uint32 Hash = GetTypeHash(Name.ToString());
FMath::RandInit(Hash);
const uint8 Hue = (uint8)(FMath::FRand() * 255);
const uint8 Saturation = 255;
const uint8 Hue = static_cast<uint8>(FMath::FRand() * 255);
constexpr uint8 Saturation = 255;
const uint8 Value = FMath::Rand() > 0.5f ? 200 : 255;
return FLinearColor::MakeFromHSV8(Hue, Saturation, Value).ToFColor(true);
@@ -33,9 +33,8 @@ const char* FCogDebugHelper::VerbosityToString(ELogVerbosity::Type Verbosity)
case ELogVerbosity::Log: return "Log";
case ELogVerbosity::Verbose: return "Verbose";
case ELogVerbosity::VeryVerbose: return "Very Verbose";
default: return "None";
}
return "None";
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -97,16 +97,16 @@ ELogVerbosity::Type FCogDebugLog::GetServerVerbosity(const FName CategoryName)
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLog::SetServerVerbosity(UWorld& World, const FName CategoryName, ELogVerbosity::Type Verbosity)
void FCogDebugLog::SetServerVerbosity(const UWorld& World, const FName CategoryName, ELogVerbosity::Type Verbosity)
{
if (ACogDebugReplicator* Replicator = ACogDebugReplicator::GetLocalReplicator(World))
{
Replicator->Server_SetCategoryVerbosity(CategoryName, (ECogLogVerbosity)Verbosity);
Replicator->Server_SetCategoryVerbosity(CategoryName, static_cast<ECogLogVerbosity>(Verbosity));
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLog::SetServerVerbosityActive(UWorld& World, const FName CategoryName, const bool Value)
void FCogDebugLog::SetServerVerbosityActive(const UWorld& World, const FName CategoryName, const bool Value)
{
SetServerVerbosity(World, CategoryName, Value ? ELogVerbosity::Verbose : ELogVerbosity::Warning);
}
@@ -30,6 +30,7 @@ void UCogDebugLogBlueprint::Log(const UObject* WorldContextObject, const FCogLog
}
//--------------------------------------------------------------------------------------------------------------------------
// ReSharper disable once CppPassValueParameterByConstReference
bool UCogDebugLogBlueprint::IsLogActive(const UObject* WorldContextObject, const FCogLogCategory LogCategory)
{
#if ENABLE_COG
@@ -1,560 +0,0 @@
#include "CogDebugPlot.h"
#include "CogDebug.h"
#include "CogDebugHelper.h"
#include "CogImguiHelper.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
FCogDebugPlotEvent FCogDebugPlot::DefaultEvent;
TArray<FCogDebugPlotEntry> FCogDebugPlot::Plots;
TArray<FCogDebugPlotEntry> FCogDebugPlot::Events;
bool FCogDebugPlot::IsVisible = false;
bool FCogDebugPlot::Pause = false;
FName FCogDebugPlot::LastAddedEventPlotName = NAME_None;
int32 FCogDebugPlot::LastAddedEventIndex = INDEX_NONE;
TMap<int32, TMap<int32, int32>> FCogDebugPlot::OccupationMap;
//--------------------------------------------------------------------------------------------------------------------------
// FCogPlotEvent
//--------------------------------------------------------------------------------------------------------------------------
float FCogDebugPlotEvent::GetActualEndTime(const FCogDebugPlotEntry& Plot) const
{
const UWorld* World = Plot.World.Get();
const float WorldTime = World != nullptr ? World->GetTimeSeconds() : 0.0f;
const float ActualEndTime = EndTime != 0.0f ? EndTime : WorldTime;
return ActualEndTime;
}
//--------------------------------------------------------------------------------------------------------------------------
uint64 FCogDebugPlotEvent::GetActualEndFrame(const FCogDebugPlotEntry& Plot) const
{
const float ActualEndFame = EndFrame != 0.0f ? EndFrame : GFrameCounter;
return ActualEndFame;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEvent::AddParam(const FName Name, bool Value)
{
if (FCogDebugPlot::IsVisible)
{
AddParam(Name, FString::Printf(TEXT("%s"), Value ? TEXT("True") : TEXT("False")));
}
return *this;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEvent::AddParam(const FName Name, int Value)
{
if (FCogDebugPlot::IsVisible)
{
AddParam(Name, FString::Printf(TEXT("%d"), Value));
}
return *this;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEvent::AddParam(const FName Name, float Value)
{
if (FCogDebugPlot::IsVisible)
{
AddParam(Name, FString::Printf(TEXT("%0.2f"), Value));
}
return *this;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEvent::AddParam(const FName Name, FName Value)
{
if (FCogDebugPlot::IsVisible)
{
AddParam(Name, Value.ToString());
}
return *this;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEvent::AddParam(const FName Name, const FString& Value)
{
if (FCogDebugPlot::IsVisible)
{
if (Name == "Name")
{
DisplayName = Value;
}
else
{
FCogDebugPlotEventParams& Param = Params.AddDefaulted_GetRef();
Param.Name = Name;
Param.Value = Value;
}
}
return *this;
}
//--------------------------------------------------------------------------------------------------------------------------
// FCogPlotEntry
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::AddPoint(float X, float Y)
{
if (Values.Capacity == 0)
{
Values.reserve(2000);
}
if (Values.size() < Values.Capacity)
{
Values.push_back(ImVec2(X, Y));
}
else
{
Values[ValueOffset] = ImVec2(X, Y);
ValueOffset = (ValueOffset + 1) % Values.size();
}
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEntry::AddEvent(
const FString& OwnerName,
const bool IsInstant,
const FName EventId,
const int32 Row,
const FColor& Color)
{
if (Events.Max() < 200)
{
Events.Reserve(200);
}
//----------------------------
// Stop if it already exist.
//----------------------------
StopEvent(EventId);
FCogDebugPlotEvent* Event = nullptr;
int32 AddedIndex = 0;
if (Events.Num() < Events.Max())
{
Event = &Events.AddDefaulted_GetRef();
AddedIndex = Events.Num() - 1;
}
else
{
Event = &Events[EventOffset];
AddedIndex = EventOffset;
EventOffset = (EventOffset + 1) % Events.Num();
}
Event->Id = EventId;
Event->OwnerName = OwnerName;
Event->DisplayName = EventId.ToString();
Event->StartTime = Time;
Event->EndTime = IsInstant ? Time : 0.0f;
Event->StartFrame = Frame;
Event->EndFrame = IsInstant ? Frame : 0.0f;
Event->Row = (Row == FCogDebugPlot::AutoRow) ? FCogDebugPlot::FindFreeGraphRow(GraphIndex) : Row;
if (IsInstant == false)
{
FCogDebugPlot::OccupyGraphRow(GraphIndex, Event->Row);
}
MaxRow = FMath::Max(Event->Row, MaxRow);
const FColor BorderColor = FCogDebugHelper::GetAutoColor(EventId, Color).WithAlpha(200);
const FColor FillColor = BorderColor.WithAlpha(100);
Event->BorderColor = FCogImguiHelper::ToImColor(BorderColor);
Event->FillColor = FCogImguiHelper::ToImColor(FillColor);
FCogDebugPlot::LastAddedEventPlotName = Name;
FCogDebugPlot::LastAddedEventIndex = AddedIndex;
return *Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlotEntry::StopEvent(const FName EventId)
{
FCogDebugPlotEvent* Event = FindLastEventByName(EventId);
if (Event == nullptr)
{
return FCogDebugPlot::DefaultEvent;
}
if (Event->EndTime == 0.0f)
{
Event->EndTime = Time;
Event->EndFrame = Frame;
FCogDebugPlot::FreeGraphRow(GraphIndex, Event->Row);
}
return *Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent* FCogDebugPlotEntry::GetLastEvent()
{
if (Events.Num() == 0)
{
return nullptr;
}
int32 Index = Events.Num() - 1;
if (EventOffset != 0)
{
Index = (Index + EventOffset) % Events.Num();
}
return &Events[Index];
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent* FCogDebugPlotEntry::FindLastEventByName(FName EventId)
{
for (int32 i = Events.Num() - 1; i >= 0; --i)
{
//--------------------------------------------------
// The array cycle so we must offset the index
//--------------------------------------------------
int32 Index = i;
if (EventOffset != 0)
{
Index = (i + EventOffset) % Events.Num();
}
if (Events[Index].Id == EventId)
{
return &Events[Index];
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::AssignGraphAndAxis(int32 InGraph, ImAxis InYAxis)
{
GraphIndex = InGraph;
YAxis = InYAxis;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::ResetGraphAndAxis()
{
GraphIndex = INDEX_NONE;
YAxis = ImAxis_COUNT;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotEntry::Clear()
{
FCogDebugPlot::ResetLastAddedEvent();
MaxRow = 0;
if (Values.size() > 0)
{
Values.shrink(0);
ValueOffset = 0;
}
if (Events.Num() > 0)
{
Events.Empty();
Events.Shrink();
EventOffset = 0;
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugPlotEntry::FindValue(float x, float& y) const
{
y = 0.0f;
bool FoundAfter = false;
bool FoundBefore = false;
for (int32 i = Values.size() - 1; i >= 0; --i)
{
//--------------------------------------------------
// The array cycle so we must offset the index
//--------------------------------------------------
int32 Index = i;
if (ValueOffset != 0)
{
Index = (i + ValueOffset) % Values.size();
}
const ImVec2 Point = Values[Index];
if (Point.x > x)
{
FoundAfter = true;
}
if (Point.x < x)
{
FoundBefore = true;
}
if (FoundAfter && FoundBefore)
{
y = Point.y;
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------
// FCogPlot
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::Reset()
{
Plots.Empty();
Events.Empty();
OccupationMap.Empty();
Pause = false;
ResetLastAddedEvent();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::Clear()
{
for (FCogDebugPlotEntry& Entry : Plots)
{
Entry.Clear();
}
for (FCogDebugPlotEntry& Entry : Events)
{
Entry.Clear();
}
OccupationMap.Empty();
ResetLastAddedEvent();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::ResetLastAddedEvent()
{
LastAddedEventPlotName = NAME_None;
LastAddedEventIndex = INDEX_NONE;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent* FCogDebugPlot::GetLastAddedEvent()
{
FCogDebugPlotEntry* Plot = FindEntry(true, LastAddedEventPlotName);
if (Plot == nullptr)
{
return nullptr;
}
return Plot->GetLastEvent();
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEntry* FCogDebugPlot::FindEntry(const FName Name)
{
if (FCogDebugPlotEntry* Event = Events.FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; }))
{
return Event;
}
if (FCogDebugPlotEntry* Plot = Plots.FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; }))
{
return Plot;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEntry* FCogDebugPlot::FindEntry(bool IsEvent, const FName Name)
{
TArray<FCogDebugPlotEntry>* Entries = IsEvent ? &Events : &Plots;
FCogDebugPlotEntry* Entry = Entries->FindByPredicate([Name](const FCogDebugPlotEntry& P) { return P.Name == Name; });
return Entry;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEntry* FCogDebugPlot::RegisterPlot(const UObject* WorldContextObject, const FName PlotName, bool IsEventPlot)
{
//----------------------------------------------------------
// When not visible, we don't go further for performances.
//----------------------------------------------------------
if (IsVisible == false)
{
return nullptr;
}
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull);
if (World == nullptr)
{
return nullptr;
}
if (FCogDebug::IsDebugActiveForObject(WorldContextObject) == false)
{
return nullptr;
}
FCogDebugPlotEntry* EntryPtr = FindEntry(IsEventPlot, PlotName);
if (EntryPtr == nullptr)
{
TArray<FCogDebugPlotEntry>* Entries = IsEventPlot ? &Events : &Plots;
EntryPtr = &Entries->AddDefaulted_GetRef();
EntryPtr->Name = PlotName;
EntryPtr->IsEventPlot = IsEventPlot;
Entries->Sort([](const FCogDebugPlotEntry& A, const FCogDebugPlotEntry& B) { return A.Name.ToString().Compare(B.Name.ToString()) < 0; });
}
//if (EntryPtr->YAxis == ImAxis_COUNT)
//{
// return nullptr;
//}
const float Time = World->GetTimeSeconds();
if (Time < EntryPtr->Time)
{
EntryPtr->Clear();
}
EntryPtr->World = World;
EntryPtr->Time = World->GetTimeSeconds();
EntryPtr->Frame = GFrameCounter;
return EntryPtr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::PlotValue(const UObject* WorldContextObject, const FName PlotName, const float Value)
{
FCogDebugPlotEntry* Plot = RegisterPlot(WorldContextObject, PlotName, false);
if (Plot == nullptr)
{
return;
}
Plot->AddPoint(Plot->Time, Value);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlot::PlotEvent(const UObject* WorldContextObject, const FName PlotName, const FName EventId, bool IsInstant, const int32 Row, const FColor& Color)
{
FCogDebugPlotEntry* Plot = RegisterPlot(WorldContextObject, PlotName, true);
if (Plot == nullptr)
{
ResetLastAddedEvent();
return DefaultEvent;
}
FCogDebugPlotEvent& Event = Plot->AddEvent(GetNameSafe(WorldContextObject), IsInstant, EventId, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlot::PlotEventInstant(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row, const FColor& Color)
{
FCogDebugPlotEvent& Event = PlotEvent(WorldContextObject, PlotName, EventId, true, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlot::PlotEventStart(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row, const FColor& Color)
{
FCogDebugPlotEvent& Event = PlotEvent(WorldContextObject, PlotName, EventId, false, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlot::PlotEventStop(const UObject* WorldContextObject, const FName PlotName, const FName EventId)
{
FCogDebugPlotEntry* Plot = RegisterPlot(WorldContextObject, PlotName, true);
if (Plot == nullptr)
{
return DefaultEvent;
}
FCogDebugPlotEvent& Event = Plot->StopEvent(EventId);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotEvent& FCogDebugPlot::PlotEventToggle(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const bool ToggleValue, const int32 Row, const FColor& Color)
{
if (ToggleValue)
{
return PlotEventStart(WorldContextObject, PlotName, EventId, Row, Color);
}
else
{
return PlotEventStop(WorldContextObject, PlotName, EventId);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::OccupyGraphRow(const int32 InGraphIndex, const int32 InRow)
{
TMap<int32, int32>& GraphOccupation = OccupationMap.FindOrAdd(InGraphIndex);
if (int32* RowOccupation = GraphOccupation.Find(InRow))
{
(*RowOccupation)++;
}
else
{
GraphOccupation.Add(InRow, 1);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlot::FreeGraphRow(const int32 InGraphIndex, const int32 Row)
{
TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InGraphIndex);
if (GraphOccupation == nullptr)
{ return; }
int32* RowOccupation = GraphOccupation->Find(Row);
if (RowOccupation == nullptr)
{ return; }
(*RowOccupation)--;
}
//--------------------------------------------------------------------------------------------------------------------------
int32 FCogDebugPlot::FindFreeGraphRow(const int32 InGraphIndex)
{
constexpr int32 MaxRows = 100;
int32 FreeRow = 0;
TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InGraphIndex);
if (GraphOccupation == nullptr)
{
return FreeRow;
}
for (; FreeRow < MaxRows; ++FreeRow)
{
const int32* Occupation = GraphOccupation->Find(FreeRow);
if (Occupation == nullptr || *Occupation == 0)
{
break;
}
}
return FreeRow;
}
@@ -1,12 +1,12 @@
#include "CogDebugPlotBlueprint.h"
#include "CogCommon.h"
#include "CogDebugPlot.h"
#include "CogDebugTracker.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogDebugPlotBlueprint::Plot(const UObject* Owner, const FName Name, const float Value)
{
#if ENABLE_COG
FCogDebugPlot::PlotValue(Owner, Name, Value);
FCogDebug::Plot(Owner, Name, Value);
#endif //ENABLE_COG
}
@@ -1,12 +1,10 @@
#include "CogDebugReplicator.h"
#include "CogDebug.h"
#include "CogDebugDraw.h"
#include "CogDebugLog.h"
#include "EngineUtils.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/WorldSettings.h"
#include "Net/Core/PushModel/PushModel.h"
#include "Net/UnrealNetwork.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -27,17 +25,18 @@ ACogDebugReplicator* ACogDebugReplicator::Spawn(APlayerController* Controller)
//--------------------------------------------------------------------------------------------------------------------------
ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(const UWorld& World)
{
for (TActorIterator<ACogDebugReplicator> It(&World, StaticClass()); It; ++It)
const TActorIterator<ACogDebugReplicator> It(&World, StaticClass());
if (It)
{
ACogDebugReplicator* Replicator = *It;
return Replicator;
return Replicator;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogDebugReplicator::GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators)
void ACogDebugReplicator::GetRemoteReplicators(const UWorld& World, TArray<ACogDebugReplicator*>& Replicators)
{
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
{
@@ -104,7 +103,7 @@ void ACogDebugReplicator::TickActor(float DeltaTime, enum ELevelTick TickType, F
#if !UE_BUILD_SHIPPING
Super::TickActor(DeltaTime, TickType, ThisTickFunction);
if (OwnerPlayerController)
if (OwnerPlayerController.IsValid())
{
if (GetWorld()->GetNetMode() == NM_Client)
{
@@ -128,7 +127,7 @@ void ACogDebugReplicator::Server_SetCategoryVerbosity_Implementation(FName LogCa
{
if (const FCogDebugLogCategoryInfo* LogCategoryInfo = FCogDebugLog::FindLogCategoryInfo(LogCategoryName))
{
LogCategoryInfo->LogCategory->SetVerbosity((ELogVerbosity::Type)Verbosity);
LogCategoryInfo->LogCategory->SetVerbosity(static_cast<ELogVerbosity::Type>(Verbosity));
TArray<FCogServerCategoryData> CategoriesData;
CategoriesData.Add({ LogCategoryName, Verbosity });
@@ -148,7 +147,7 @@ void ACogDebugReplicator::NetMulticast_SendCategoriesVerbosity_Implementation(co
{
for (const FCogServerCategoryData& Category : Categories)
{
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, static_cast<ELogVerbosity::Type>(Category.Verbosity));
}
}
@@ -164,7 +163,7 @@ void ACogDebugReplicator::Client_SendCategoriesVerbosity_Implementation(const TA
{
for (const FCogServerCategoryData& Category : Categories)
{
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, static_cast<ELogVerbosity::Type>(Category.Verbosity));
}
}
@@ -188,7 +187,7 @@ void ACogDebugReplicator::Server_RequestAllCategoriesVerbosity_Implementation()
CategoriesData.Add(
{
CategoryInfo.LogCategory->GetCategoryName(),
(ECogLogVerbosity)CategoryInfo.LogCategory->GetVerbosity()
static_cast<ECogLogVerbosity>(CategoryInfo.LogCategory->GetVerbosity())
});
}
}
@@ -218,11 +217,11 @@ void ACogDebugReplicator::Server_SetSelection_Implementation(AActor* Value, bool
if (ForceSelection)
{
FCogDebug::SetSelection(GetWorld(), Value);
FCogDebug::SetSelection(Value);
}
else
{
FCogDebug::SetSelection(GetWorld(), nullptr);
FCogDebug::SetSelection(nullptr);
}
@@ -248,14 +247,14 @@ public:
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
//--------------------------------------------------------------------------------------------------------------------------
bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParams)
{
if (DeltaParms.bUpdateUnmappedObjects || Owner == nullptr)
if (DeltaParams.bUpdateUnmappedObjects || Owner == nullptr)
{
return true;
}
if (DeltaParms.Writer)
if (DeltaParams.Writer)
{
const bool bIsOwnerClient = !Owner->bHasAuthority;
if (bIsOwnerClient)
@@ -263,10 +262,10 @@ bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms
return false;
}
const FCogReplicatorNetState* OldState = static_cast<FCogReplicatorNetState*>(DeltaParms.OldState);
const FCogReplicatorNetState* OldState = static_cast<FCogReplicatorNetState*>(DeltaParams.OldState);
FCogReplicatorNetState* NewState = new FCogReplicatorNetState();
check(DeltaParms.NewState);
*DeltaParms.NewState = TSharedPtr<INetDeltaBaseState>(NewState);
check(DeltaParams.NewState);
*DeltaParams.NewState = TSharedPtr<INetDeltaBaseState>(NewState);
//------------------------------------------------------------------------------------------------------------------
// Find delta to replicate
@@ -289,7 +288,7 @@ bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms
const bool bMissingOldState = (OldState == nullptr);
const uint8 ShouldUpdateShapes = bMissingOldState || (OldState->ShapesRepCounter != NewState->ShapesRepCounter);
FBitWriter& Writer = *DeltaParms.Writer;
FBitWriter& Writer = *DeltaParams.Writer;
Writer.WriteBit(ShouldUpdateShapes);
if (ShouldUpdateShapes)
{
@@ -297,12 +296,12 @@ bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms
}
}
}
else if (DeltaParms.Reader)
else if (DeltaParams.Reader)
{
//------------------------------------------------------------------------------------------------------------------
// Read
//------------------------------------------------------------------------------------------------------------------
FBitReader& Reader = *DeltaParms.Reader;
FBitReader& Reader = *DeltaParams.Reader;
const uint8 ShouldUpdateShapes = Reader.ReadBit();
if (ShouldUpdateShapes)
{
@@ -0,0 +1,360 @@
#include "CogDebugTracker.h"
#include "CogDebug.h"
#include "CogDebugEventTrack.h"
#include "CogDebugPlotTrack.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
int32 FCogDebugTracker::NumRecordedValues = 2000;
FCogDebugEvent FCogDebugTracker::DefaultEvent;
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::Reset()
{
Values.Empty();
Events.Empty();
OccupationMap.Empty();
Pause = false;
ResetLastAddedEvent();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::Clear()
{
for (auto& kv : Values)
{
kv.Value.Clear();
}
for (auto& kv : Events)
{
kv.Value.Clear();
}
OccupationMap.Empty();
ResetLastAddedEvent();
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugTracker::CanCreateTrack(const UObject* WorldContextObject, const UWorld*& World) const
{
//----------------------------------------------------------
// When not visible, we don't go further for performances.
//----------------------------------------------------------
if (IsVisible == false)
{
return false;
}
World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull);
if (World == nullptr)
{
return false;
}
if (FCogDebug::IsDebugActiveForObject(WorldContextObject) == false)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::InitializeTrack(FCogDebugTrack& OutTrack, const UWorld* InWorld, const FCogDebugTrackId& InTrackId)
{
const float Time = InWorld->GetTimeSeconds();
if (Time < OutTrack.Time)
{
OutTrack.Clear();
}
OutTrack.Id = InTrackId;
OutTrack.Time = InWorld->GetTimeSeconds();
OutTrack.Frame = GFrameCounter;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::OccupyViewRow(const int32 InViewIndex, const int32 InRow)
{
TMap<int32, int32>& GraphOccupation = OccupationMap.FindOrAdd(InViewIndex);
if (int32* RowOccupation = GraphOccupation.Find(InRow))
{
(*RowOccupation)++;
}
else
{
GraphOccupation.Add(InRow, 1);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::FreeViewRow(const int32 InViewIndex, const int32 Row)
{
TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InViewIndex);
if (GraphOccupation == nullptr)
{ return; }
int32* RowOccupation = GraphOccupation->Find(Row);
if (RowOccupation == nullptr)
{ return; }
(*RowOccupation)--;
}
//--------------------------------------------------------------------------------------------------------------------------
int32 FCogDebugTracker::FindFreeViewRow(const int32 InViewIndex)
{
constexpr int32 MaxRows = 100;
int32 FreeRow = 0;
TMap<int32, int32>* GraphOccupation = OccupationMap.Find(InViewIndex);
if (GraphOccupation == nullptr)
{
return FreeRow;
}
for (; FreeRow < MaxRows; ++FreeRow)
{
const int32* Occupation = GraphOccupation->Find(FreeRow);
if (Occupation == nullptr || *Occupation == 0)
{
break;
}
}
return FreeRow;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugTrack* FCogDebugTracker::FindTrack(const FCogDebugTrackId& InTrackId)
{
FCogDebugTrack* Track = Events.Find(InTrackId);
if (Track != nullptr)
{
return Track;
}
Track = Values.Find(InTrackId);
if (Track != nullptr)
{
return Track;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::SetNumRecordedValues(const int32 InValue)
{
NumRecordedValues = InValue;
for (auto& kv : Values)
{
kv.Value.SetNumPlots(InValue);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotTrack::SetNumPlots(const int32 Value)
{
Values.reserve(Value);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotTrack::Plot(float X, float Y)
{
if (Values.Capacity == 0)
{
Values.reserve(FCogDebugTracker::NumRecordedValues);
}
if (Values.size() < Values.Capacity)
{
Values.push_back(ImVec2(X, Y));
}
else
{
Values[ValueOffset] = ImVec2(X, Y);
ValueOffset = (ValueOffset + 1) % Values.size();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugPlotTrack::Clear()
{
FCogDebugTrack::Clear();
if (Values.size() > 0)
{
Values.shrink(0);
ValueOffset = 0;
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugPlotTrack::FindValue(float InX, float& OutY) const
{
OutY = 0.0f;
bool FoundAfter = false;
bool FoundBefore = false;
for (int32 i = Values.size() - 1; i >= 0; --i)
{
//--------------------------------------------------
// The array cycle so we must offset the index
//--------------------------------------------------
int32 Index = i;
if (ValueOffset != 0)
{
Index = (i + ValueOffset) % Values.size();
}
const ImVec2 Point = Values[Index];
if (Point.x > InX)
{
FoundAfter = true;
}
if (Point.x < InX)
{
FoundBefore = true;
}
if (FoundAfter && FoundBefore)
{
OutY = Point.y;
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------
// Plot Track Creation
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugPlotTrack* FCogDebugTracker::GetOrCreatePlotTrack(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId)
{
const UWorld* World;
if (CanCreateTrack(InWorldContextObject, World) == false)
{
return nullptr;
}
FCogDebugPlotTrack& Track = Values.FindOrAdd(InTrackId);
Track.Owner = this;
Track.Type = ECogDebugTrackType::Value;
InitializeTrack(Track, World, InTrackId);
return &Track;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::Plot(const UObject* InWorldContextObject, const FName InTrackId, const float Value)
{
if (Pause && RecordValuesWhenPause == false)
{ return; }
FCogDebugPlotTrack* Track = GetOrCreatePlotTrack(InWorldContextObject, InTrackId);
if (Track == nullptr)
{ return; }
Track->Plot(Track->Time, Value);
}
//--------------------------------------------------------------------------------------------------------------------------
// Event Track Creation
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugTracker::StartEvent(const UObject* InWorldContextObject, const FCogDebugEventId& InTrackId, const FCogDebugEventId& InEventId, bool IsInstant, const int32 Row, const FColor& Color)
{
FCogDebugEventTrack* Track = GetOrCreateEventTrack(InWorldContextObject, InTrackId);
if (Track == nullptr)
{
ResetLastAddedEvent();
return DefaultEvent;
}
FCogDebugEvent& Event = Track->AddEvent(GetNameSafe(InWorldContextObject), IsInstant, InEventId, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugTracker::InstantEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row, const FColor& Color)
{
FCogDebugEvent& Event = StartEvent(InWorldContextObject, InTrackId, InEventId, true, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugTracker::StartEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row, const FColor& Color)
{
FCogDebugEvent& Event = StartEvent(InWorldContextObject, InTrackId, InEventId, false, Row, Color);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugTracker::StopEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId)
{
FCogDebugEventTrack* EventHistory = GetOrCreateEventTrack(InWorldContextObject, InTrackId);
if (EventHistory == nullptr)
{
return DefaultEvent;
}
FCogDebugEvent& Event = EventHistory->StopEvent(InEventId);
return Event;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent& FCogDebugTracker::ToggleEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const bool ToggleValue, const int32 Row, const FColor& Color)
{
if (ToggleValue)
{
return StartEvent(InWorldContextObject, InTrackId, InEventId, Row, Color);
}
else
{
return StopEvent(InWorldContextObject, InTrackId, InEventId);
}
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEventTrack* FCogDebugTracker::GetOrCreateEventTrack(const UObject* InWorldContextObject, const FCogDebugEventId& InTrackId)
{
const UWorld* World;
if (CanCreateTrack(InWorldContextObject, World) == false)
{ return nullptr; }
FCogDebugEventTrack& Track = Events.FindOrAdd(InTrackId);
Track.Type = ECogDebugTrackType::Event;
Track.Owner = this;
InitializeTrack(Track, World, InTrackId);
return &Track;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugTracker::ResetLastAddedEvent()
{
LastAddedEventTrackId = NAME_None;
LastAddedEventIndex = INDEX_NONE;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugEvent* FCogDebugTracker::GetLastAddedEvent()
{
FCogDebugEventTrack* EventHistory = Events.Find(LastAddedEventTrackId);
if (EventHistory == nullptr)
{
return nullptr;
}
return EventHistory->GetLastEvent();
}
+32 -372
View File
@@ -1,9 +1,11 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugEvent.h"
#include "CogDebugSettings.h"
#include "CogDebugTracker.h"
#include "Engine/EngineTypes.h"
#include "UObject/WeakObjectPtrTemplates.h"
#include "CogDebug.generated.h"
class AActor;
class UObject;
@@ -12,387 +14,30 @@ struct FCogDebugDrawLineTraceParams;
struct FCogDebugDrawOverlapParams;
struct FCogDebugDrawSweepParams;
UENUM()
enum class ECogDebugRecolorMode : uint8
//--------------------------------------------------------------------------------------------------------------------------
struct FCogDebugContext
{
None,
Color,
HueOverTime,
HueOverFrames,
};
FCogDebugTracker Tracker;
USTRUCT()
struct FCogDebugSettings
{
GENERATED_BODY()
UPROPERTY(Config)
bool bIsFilteringBySelection = true;
UPROPERTY(Config)
bool ReplicateSelection = true;
UPROPERTY(Config)
bool Persistent = false;
UPROPERTY(Config)
bool TextShadow = true;
UPROPERTY(Config)
bool Fade2D = true;
UPROPERTY(Config)
float Duration = 3.0f;
UPROPERTY(Config)
int DepthPriority = 0;
UPROPERTY(Config)
int Segments = 12;
UPROPERTY(Config)
float Thickness = 0.0f;
UPROPERTY(Config)
float ServerThickness = 2.0f;
UPROPERTY(Config)
float ServerColorMultiplier = 0.8f;
UPROPERTY(Config)
float ArrowSize = 10.0f;
UPROPERTY(Config)
float AxesScale = 1.0f;
UPROPERTY(Config)
ECogDebugRecolorMode RecolorMode = ECogDebugRecolorMode::None;
UPROPERTY(Config)
float RecolorIntensity = 0.0f;
UPROPERTY(Config)
FColor RecolorColor = FColor(255, 0, 0, 255);
UPROPERTY(Config)
float RecolorTimeSpeed = 2.0f;
UPROPERTY(Config)
int32 RecolorFrameCycle = 6;
UPROPERTY(Config)
float TextSize = 1.0f;
UPROPERTY(Config)
bool ActorNameUseLabel = true;
UPROPERTY(Config)
float GizmoScale = 1.0f;
UPROPERTY(Config)
bool GizmoUseLocalSpace = false;
UPROPERTY(Config)
int GizmoZLow = 0;
UPROPERTY(Config)
int GizmoZHigh = 100;
UPROPERTY(Config)
float GizmoThicknessZLow = 1.0f;
UPROPERTY(Config)
float GizmoThicknessZHigh = 0.0f;
UPROPERTY(Config)
float GizmoCursorDraggingThreshold = 4.0f;
UPROPERTY(Config)
float GizmoCursorSelectionThreshold = 10.0f;
UPROPERTY(Config)
float GizmoTranslationAxisLength = 80.0f;
UPROPERTY(Config)
bool GizmoTranslationSnapEnable = false;
UPROPERTY(Config)
float GizmoTranslationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoTranslationPlaneOffset = 18.0f;
UPROPERTY(Config)
float GizmoTranslationPlaneExtent = 5.0f;
UPROPERTY(Config)
bool GizmoRotationSnapEnable = false;
UPROPERTY(Config)
float GizmoRotationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoRotationSpeed = 1.0f;
UPROPERTY(Config)
float GizmoRotationRadius = 40.0f;
UPROPERTY(Config)
int GizmoRotationSegments = 8;
UPROPERTY(Config)
bool GizmoScaleSnapEnable = false;
UPROPERTY(Config)
float GizmoScaleSnapValue = 1.0f;
UPROPERTY(Config)
float GizmoScaleBoxOffset = 85.0f;
UPROPERTY(Config)
float GizmoScaleBoxExtent = 5.0f;
UPROPERTY(Config)
float GizmoScaleSpeed = 0.01f;
UPROPERTY(Config)
float GizmoScaleMin = 0.001f;
UPROPERTY(Config)
float GizmoGroundRaycastLength = 100000.0f;
UPROPERTY(Config)
TEnumAsByte<ECollisionChannel> GizmoGroundRaycastChannel = ECollisionChannel::ECC_WorldStatic;
UPROPERTY(Config)
float GizmoGroundRaycastCircleRadius = 5.0f;
UPROPERTY(Config)
FColor GizmoAxisColorsZHighX = FColor(255, 50, 50, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighY = FColor(50, 255, 50, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighZ = FColor(50, 50, 255, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighW = FColor(255, 255, 255, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowX = FColor(128, 0, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowY = FColor(0, 128, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowZ = FColor(0, 0, 128, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowW = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionX = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionY = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionZ = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionW = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoGroundRaycastColor = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoGroundRaycastCircleColor = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoTextColor = FColor(255, 255, 255, 255);
UPROPERTY(Config)
FColor CollisionQueryHitColor = FColor::Green;
UPROPERTY(Config)
FColor CollisionQueryNoHitColor = FColor::Red;
UPROPERTY(Config)
bool CollisionQueryDrawHitPrimitives = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitPrimitiveActorsName = false;
UPROPERTY(Config)
bool CollisionQueryHitPrimitiveActorsNameShadow = true;
UPROPERTY(Config)
float CollisionQueryHitPrimitiveActorsNameSize = 1.0f;
UPROPERTY(Config)
bool CollisionQueryDrawHitLocation = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitImpactPoints = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitNormals = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitImpactNormals = true;
UPROPERTY(Config)
float CollisionQueryHitPointSize = 5.0f;
UPROPERTY(Config)
FColor CollisionQueryNormalColor = FColor::Yellow;
UPROPERTY(Config)
FColor CollisionQueryImpactNormalColor = FColor::Cyan;
UPROPERTY(Config)
bool CollisionQueryDrawHitShapes = true;
UPROPERTY(Config)
FColor ChannelColorWorldStatic = FColor(255, 0, 0, 5);
UPROPERTY(Config)
FColor ChannelColorWorldDynamic = FColor(255, 0, 188, 5);
UPROPERTY(Config)
FColor ChannelColorPawn = FColor(105, 0, 255, 5);
UPROPERTY(Config)
FColor ChannelColorVisibility = FColor(0, 15, 255, 5);
UPROPERTY(Config)
FColor ChannelColorCamera = FColor(0, 105, 255, 5);
UPROPERTY(Config)
FColor ChannelColorPhysicsBody = FColor(0, 255, 208, 5);
UPROPERTY(Config)
FColor ChannelColorVehicle = FColor(52, 255, 0, 5);
UPROPERTY(Config)
FColor ChannelColorDestructible = FColor(255, 255, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel1 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel2 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel3 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel4 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel5 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorEngineTraceChannel6 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel1 = FColor(255, 105, 0, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel2 = FColor(255, 30, 0, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel3 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel4 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel5 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel6 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel7 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel8 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel9 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel10 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel11 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel12 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel13 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel14 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel15 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel16 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel17 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel18 = FColor(0, 0, 0, 0);
UPROPERTY(Config)
TArray<FString> SecondaryBoneWildcards = {
"interaction",
"center_of_mass",
"ik_*",
"index_*",
"middle_*",
"pinky_*",
"ring_*",
"thumb_*",
"wrist_*",
"*_bck_*",
"*_fwd_*",
"*_in_*",
"*_out_*",
"*_pec_*",
"*_scap_*",
"*_bicep_*",
"*_tricep_*",
"*ankle*",
"*knee*",
"*corrective*",
"*twist*",
"*latissimus*",
};
TWeakObjectPtr<AActor> Selection;
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebug
{
public:
//----------------------------------------------------------------------------------------------------------------------
static bool IsDebugActiveForObject(const UObject* WorldContextObject);
static bool IsReplicatedDebugActiveForObject(const UObject* WorldContextObject, const AActor* ServerSelection, bool IsServerFilteringBySelection);
static AActor* GetSelection();
static void SetSelection(const UWorld* World, AActor* Value);
static void SetSelection(AActor* InValue);
static bool GetIsFilteringBySelection();
static void SetIsFilteringBySelection(UWorld* World, bool Value);
static void SetIsFilteringBySelection(const UWorld* World, bool Value);
static FCogDebugTracker& GetTracker();
static bool GetDebugPersistent(bool bPersistent);
@@ -426,17 +71,32 @@ public:
static void GetDebugDrawSweepSettings(FCogDebugDrawSweepParams& Params);
static FCogDebugContext& Get(int32 InPieId);
static FCogDebugContext& Get();
static int32 GetPieSessionId();
static void Plot(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const float Value);
static FCogDebugEvent& StartEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, bool IsInstant, const int32 Row = -1, const FColor& Color = FColor::Transparent);
static FCogDebugEvent& InstantEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row = -1, const FColor& Color = FColor::Transparent);
static FCogDebugEvent& StartEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row = -1, const FColor& Color = FColor::Transparent);
static FCogDebugEvent& StopEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId);
static FCogDebugEvent& ToggleEvent(const UObject* WorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const bool ToggleValue, const int32 Row = -1, const FColor& Color = FColor::Transparent);
static FCogDebugSettings Settings;
private:
static int32 GetPieSessionId();
static void ReplicateSelection(const UWorld* World, AActor* Value);
static bool IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection);
static constexpr uint32 MaxPie = 16;
static TWeakObjectPtr<AActor> Selection[MaxPie];
static TMap<int32, FCogDebugContext> DebugContexts;
};
@@ -59,7 +59,7 @@ struct COGDEBUG_API FCogDebugDraw
static void Sweep(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FCollisionShape& Shape, const FVector& Start, const FVector& End, const FQuat& Rotation, const bool HasHits, TArray<FHitResult>& HitResults, const FCogDebugDrawSweepParams& Settings);
static void Overlap(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings);
static void Overlap(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, const bool HasHits, TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings);
static void ReplicateShape(const UObject* WorldContextObject, const FCogDebugShape& Shape);
@@ -1,7 +1,7 @@
// ReSharper disable CppUEBlueprintCallableFunctionUnused
#pragma once
#include "CoreMinimal.h"
#include "Kismet/KismetSystemLibrary.h"
#include "CogDebugDrawBlueprint.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -64,13 +64,13 @@ public:
static void DrawPrimitiveComponent(const UPrimitiveComponent& PrimitiveComponent, const int32 BodyIndex, const FColor& Color, const bool Persistent, const float LifeTime, const uint8 DepthPriority, const float Thickness, const bool DrawName = true, const bool DrawNameShadow = true, const float DrawNameSize = 1.0f);
static void DrawOverlap(const UWorld* World, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings);
static void DrawOverlap(const UWorld* World, const FCollisionShape& Shape, const FVector& Location, const FQuat& Rotation, const bool HasHits, const TArray<FOverlapResult>& OverlapResults, const FCogDebugDrawOverlapParams& Settings);
static void DrawHitResult(const UWorld* World, const FHitResult& HitResult, const FCogDebugDrawLineTraceParams& Settings);
static void DrawHitResults(const UWorld* World, const TArray<FHitResult>& HitResults, const FCogDebugDrawLineTraceParams& Settings);
static void DrawLineTrace(const UWorld* World, const FVector& Start, const FVector& End, const bool HasHits, TArray<FHitResult>& HitResults, const FCogDebugDrawLineTraceParams& Settings);
static void DrawLineTrace(const UWorld* World, const FVector& Start, const FVector& End, const bool HasHits, const TArray<FHitResult>& HitResults, const FCogDebugDrawLineTraceParams& Settings);
static void DrawSweep(const UWorld* World, const FCollisionShape& Shape, const FVector& Start, const FVector& End, const FQuat& Rotation, const bool HasHits, TArray<FHitResult>& HitResults, const FCogDebugDrawSweepParams& Settings);
};
@@ -77,6 +77,7 @@ private:
};
//----------------------------------------------------------------------------------------------------------------------
static float Time;
static TArray<FLine> Lines;
static TArray<FTriangle> Triangles;
static TArray<FTriangle> TrianglesFilled;
@@ -92,9 +93,6 @@ private:
template<typename TShape, typename TDrawFunction>
static void DrawShapes(TArray<TShape>& Shapes, TDrawFunction DrawFunction)
{
ImDrawList* ImDrawList = ImGui::GetBackgroundDrawList();
const double Time = ImGui::GetCurrentContext()->Time;
for (int32 i = 0; i < Shapes.Num(); i++)
{
const TShape& Shape = Shapes[i];
@@ -0,0 +1,57 @@
#pragma once
#include "CoreMinimal.h"
#include "imgui.h"
typedef FName FCogDebugEventId;
typedef FName FCogDebugEventParamId;
struct FCogDebugTrack;
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugEventParams
{
FCogDebugEventParamId Name;
FString Value;
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugEvent
{
float GetActualEndTime(const UWorld& World) const;
uint64 GetActualEndFrame() const;
FCogDebugEvent& AddParam(const FCogDebugEventParamId& InParamId, bool InValue);
FCogDebugEvent& AddParam(const FCogDebugEventParamId& InParamId, int InValue);
FCogDebugEvent& AddParam(const FCogDebugEventParamId& InParamId, float InValue);
FCogDebugEvent& AddParam(const FCogDebugEventParamId& InParamId, FName InValue);
FCogDebugEvent& AddParam(const FCogDebugEventParamId& InParamId, const FString& InValue);
FCogDebugTrack* Track = nullptr;
FCogDebugEventParamId Id;
float StartTime = 0.0f;
float EndTime = 0.0f;
uint64 StartFrame = 0;
uint64 EndFrame = 0;
ImU32 BorderColor;
ImU32 FillColor;
int32 Row;
FString OwnerName;
FString DisplayName;
TArray<FCogDebugEventParams> Params;
};
@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugEvent.h"
#include "CogDebugTrack.h"
struct COGDEBUG_API FCogDebugEventTrack : FCogDebugTrack
{
FCogDebugEvent& AddEvent(const FString& OwnerName, bool IsInstant, const FCogDebugEventId EventId, const int32 Row, const FColor& Color);
FCogDebugEvent& StopEvent(const FCogDebugEventId EventId);
FCogDebugEvent* GetLastEvent();
FCogDebugEvent* FindLastEventByName(FCogDebugEventId EventId);
virtual void Clear() override;
int32 EventOffset = 0;
int32 MaxRow = 1;
TArray<FCogDebugEvent> Events;
};
@@ -46,13 +46,13 @@ struct COGDEBUG_API FCogDebugLog
static TMap<FName, FCogDebugLogCategoryInfo>& GetLogCategories() { return LogCategories; }
static void SetServerVerbosityActive(UWorld& World, FName CategoryName, bool Value);
static void SetServerVerbosityActive(const UWorld& World, FName CategoryName, bool Value);
static bool IsServerVerbosityActive(FName CategoryName);
static ELogVerbosity::Type GetServerVerbosity(FName CategoryName);
static void SetServerVerbosity(UWorld& World, FName CategoryName, ELogVerbosity::Type Verbosity);
static void SetServerVerbosity(const UWorld& World, FName CategoryName, ELogVerbosity::Type Verbosity);
static void OnServerVerbosityChanged(FName CategoryName, ELogVerbosity::Type Verbosity);
@@ -10,7 +10,7 @@ class COGDEBUG_API FCogDebugModule : public IModuleInterface
{
public:
static inline FCogDebugModule& Get() { return FModuleManager::LoadModuleChecked<FCogDebugModule>("CogDebug"); }
static FCogDebugModule& Get() { return FModuleManager::LoadModuleChecked<FCogDebugModule>("CogDebug"); }
virtual void StartupModule() override;
@@ -1,165 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "CogCommon.h"
#include "imgui.h"
#include "implot.h"
#ifdef ENABLE_COG
struct FCogDebugPlotEntry;
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugPlotEventParams
{
FName Name;
FString Value;
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugPlotEvent
{
float GetActualEndTime(const FCogDebugPlotEntry& Plot) const;
uint64 GetActualEndFrame(const FCogDebugPlotEntry& Plot) const;
FCogDebugPlotEvent& AddParam(const FName Name, bool Value);
FCogDebugPlotEvent& AddParam(const FName Name, int Value);
FCogDebugPlotEvent& AddParam(const FName Name, float Value);
FCogDebugPlotEvent& AddParam(const FName Name, FName Value);
FCogDebugPlotEvent& AddParam(const FName Name, const FString& Value);
FName Id;
float StartTime = 0.0f;
float EndTime = 0.0f;
uint64 StartFrame = 0;
uint64 EndFrame = 0;
ImU32 BorderColor;
ImU32 FillColor;
int32 Row;
FString OwnerName;
FString DisplayName;
TArray<FCogDebugPlotEventParams> Params;
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugPlotEntry
{
void AssignGraphAndAxis(int32 AssignedRow, ImAxis CurrentYAxis);
void AddPoint(float X, float Y);
bool FindValue(float Time, float& Value) const;
void ResetGraphAndAxis();
void Clear();
FCogDebugPlotEvent& AddEvent(const FString& OwnerName, bool IsInstant, const FName EventId, const int32 Row, const FColor& Color);
FCogDebugPlotEvent& StopEvent(const FName EventId);
FCogDebugPlotEvent* GetLastEvent();
FCogDebugPlotEvent* FindLastEventByName(FName EventId);
FName Name;
bool IsEventPlot = false;
int32 GraphIndex = INDEX_NONE;
ImAxis YAxis = ImAxis_COUNT;
float Time = 0;
uint64 Frame = 0;
TWeakObjectPtr<const UWorld> World;
//--------------------------
// Values
//--------------------------
int32 ValueOffset = 0;
ImVector<ImVec2> Values;
bool ShowValuesMarkers = false;
//--------------------------
// Events
//--------------------------
int32 EventOffset = 0;
TArray<FCogDebugPlotEvent> Events;
int32 MaxRow = 1;
};
//--------------------------------------------------------------------------------------------------------------------------
class COGDEBUG_API FCogDebugPlot
{
public:
static constexpr int32 AutoRow = -1;
static void PlotValue(const UObject* WorldContextObject, const FName PlotName, const float Value);
static FCogDebugPlotEvent& PlotEvent(const UObject* WorldContextObject, const FName PlotName, const FName EventId, bool IsInstant, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventInstant(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventStart(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static FCogDebugPlotEvent& PlotEventStop(const UObject* WorldContextObject, const FName PlotName, const FName EventId);
static FCogDebugPlotEvent& PlotEventToggle(const UObject* WorldContextObject, const FName PlotName, const FName EventId, const bool ToggleValue, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
static void Reset();
static void Clear();
static FCogDebugPlotEntry* FindEntry(const FName Name);
static FCogDebugPlotEntry* FindEntry(bool IsEvent, const FName Name);
static TArray<FCogDebugPlotEntry> Plots;
static TArray<FCogDebugPlotEntry> Events;
static bool IsVisible;
static bool Pause;
private:
friend struct FCogDebugPlotEntry;
static void ResetLastAddedEvent();
static FCogDebugPlotEntry* RegisterPlot(const UObject* Owner, const FName PlotName, bool IsEventPlot);
static FCogDebugPlotEvent* GetLastAddedEvent();
static void OccupyGraphRow(const int32 InGraphIndex, const int32 InRow);
static void FreeGraphRow(const int32 InGraphIndex, const int32 InRow);
static int32 FindFreeGraphRow(const int32 InGraphIndex);
static FName LastAddedEventPlotName;
static int32 LastAddedEventIndex;
static FCogDebugPlotEvent DefaultEvent;
// graph index to row index to number of objects occupying the row
static TMap<int32, TMap<int32, int32>> OccupationMap;
};
#endif //ENABLE_COG
@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugTrack.h"
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugPlotTrack : FCogDebugTrack
{
virtual void Clear() override;
void Plot(float X, float Y);
bool FindValue(float Time, float& Value) const;
void SetNumPlots(const int32 Value);
int32 ValueOffset = 0;
ImVector<ImVec2> Values;
bool ShowValuesMarkers = false;
};
@@ -0,0 +1,15 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "CogDebugPluginSubsystem.generated.h"
UCLASS(Abstract)
class COGDEBUG_API UCogDebugPluginSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
virtual void OnPlayerControllerReady(APlayerController* InController) {}
};
@@ -32,9 +32,9 @@ struct FCogReplicatorNetPack
{
GENERATED_USTRUCT_BODY()
ACogDebugReplicator* Owner = nullptr;
TObjectPtr<ACogDebugReplicator> Owner;
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms);
bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParams);
private:
@@ -63,7 +63,7 @@ public:
static ACogDebugReplicator* GetLocalReplicator(const UWorld& World);
static void GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators);
static void GetRemoteReplicators(const UWorld& World, TArray<ACogDebugReplicator*>& Replicators);
virtual void BeginPlay() override;
@@ -98,7 +98,7 @@ public:
protected:
friend FCogReplicatorNetPack;
TObjectPtr<APlayerController> OwnerPlayerController;
TWeakObjectPtr<APlayerController> OwnerPlayerController;
uint32 bHasAuthority : 1;
@@ -0,0 +1,360 @@
#pragma once
#include "CoreMinimal.h"
#include "Engine/EngineTypes.h"
#include "CogDebugSettings.generated.h"
class AActor;
class UObject;
class UWorld;
UENUM()
enum class ECogDebugRecolorMode : uint8
{
None,
Color,
HueOverTime,
HueOverFrames,
};
USTRUCT()
struct FCogDebugSettings
{
GENERATED_BODY()
UPROPERTY(Config)
bool bIsFilteringBySelection = true;
UPROPERTY(Config)
bool ReplicateSelection = true;
UPROPERTY(Config)
bool Persistent = false;
UPROPERTY(Config)
bool TextShadow = true;
UPROPERTY(Config)
bool Fade2D = true;
UPROPERTY(Config)
float Duration = 3.0f;
UPROPERTY(Config)
int DepthPriority = 0;
UPROPERTY(Config)
int Segments = 12;
UPROPERTY(Config)
float Thickness = 0.0f;
UPROPERTY(Config)
float ServerThickness = 2.0f;
UPROPERTY(Config)
float ServerColorMultiplier = 0.8f;
UPROPERTY(Config)
float ArrowSize = 10.0f;
UPROPERTY(Config)
float AxesScale = 1.0f;
UPROPERTY(Config)
ECogDebugRecolorMode RecolorMode = ECogDebugRecolorMode::None;
UPROPERTY(Config)
float RecolorIntensity = 0.0f;
UPROPERTY(Config)
FColor RecolorColor = FColor(255, 0, 0, 255);
UPROPERTY(Config)
float RecolorTimeSpeed = 2.0f;
UPROPERTY(Config)
int32 RecolorFrameCycle = 6;
UPROPERTY(Config)
float TextSize = 1.0f;
UPROPERTY(Config)
bool ActorNameUseLabel = true;
UPROPERTY(Config)
float GizmoScale = 1.0f;
UPROPERTY(Config)
bool GizmoSupportContextMenu = true;
UPROPERTY(Config)
bool GizmoUseLocalSpace = false;
UPROPERTY(Config)
int GizmoZLow = 0;
UPROPERTY(Config)
int GizmoZHigh = 100;
UPROPERTY(Config)
float GizmoThicknessZLow = 1.0f;
UPROPERTY(Config)
float GizmoThicknessZHigh = 0.0f;
UPROPERTY(Config)
float GizmoCursorDraggingThreshold = 4.0f;
UPROPERTY(Config)
float GizmoCursorSelectionThreshold = 10.0f;
UPROPERTY(Config)
float GizmoTranslationAxisLength = 80.0f;
UPROPERTY(Config)
bool GizmoTranslationSnapEnable = false;
UPROPERTY(Config)
float GizmoTranslationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoTranslationPlaneOffset = 18.0f;
UPROPERTY(Config)
float GizmoTranslationPlaneExtent = 5.0f;
UPROPERTY(Config)
bool GizmoRotationSnapEnable = false;
UPROPERTY(Config)
float GizmoRotationSnapValue = 10.0f;
UPROPERTY(Config)
float GizmoRotationSpeed = 1.0f;
UPROPERTY(Config)
float GizmoRotationRadius = 40.0f;
UPROPERTY(Config)
int GizmoRotationSegments = 8;
UPROPERTY(Config)
bool GizmoScaleSnapEnable = false;
UPROPERTY(Config)
float GizmoScaleSnapValue = 1.0f;
UPROPERTY(Config)
float GizmoScaleBoxOffset = 85.0f;
UPROPERTY(Config)
float GizmoScaleBoxExtent = 5.0f;
UPROPERTY(Config)
float GizmoScaleSpeed = 0.01f;
UPROPERTY(Config)
float GizmoScaleMin = 0.001f;
UPROPERTY(Config)
float GizmoGroundRaycastLength = 100000.0f;
UPROPERTY(Config)
TEnumAsByte<ECollisionChannel> GizmoGroundRaycastChannel = ECollisionChannel::ECC_WorldStatic;
UPROPERTY(Config)
float GizmoGroundRaycastCircleRadius = 5.0f;
UPROPERTY(Config)
FColor GizmoAxisColorsZHighX = FColor(255, 50, 50, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighY = FColor(50, 255, 50, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighZ = FColor(50, 50, 255, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZHighW = FColor(255, 255, 255, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowX = FColor(128, 0, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowY = FColor(0, 128, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowZ = FColor(0, 0, 128, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsZLowW = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionX = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionY = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionZ = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoAxisColorsSelectionW = FColor(255, 255, 0, 255);
UPROPERTY(Config)
FColor GizmoGroundRaycastColor = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoGroundRaycastCircleColor = FColor(128, 128, 128, 255);
UPROPERTY(Config)
FColor GizmoTextColor = FColor(255, 255, 255, 255);
UPROPERTY(Config)
FColor CollisionQueryHitColor = FColor::Green;
UPROPERTY(Config)
FColor CollisionQueryNoHitColor = FColor::Red;
UPROPERTY(Config)
bool CollisionQueryDrawHitPrimitives = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitPrimitiveActorsName = false;
UPROPERTY(Config)
bool CollisionQueryHitPrimitiveActorsNameShadow = true;
UPROPERTY(Config)
float CollisionQueryHitPrimitiveActorsNameSize = 1.0f;
UPROPERTY(Config)
bool CollisionQueryDrawHitLocation = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitImpactPoints = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitNormals = true;
UPROPERTY(Config)
bool CollisionQueryDrawHitImpactNormals = true;
UPROPERTY(Config)
float CollisionQueryHitPointSize = 5.0f;
UPROPERTY(Config)
FColor CollisionQueryNormalColor = FColor::Yellow;
UPROPERTY(Config)
FColor CollisionQueryImpactNormalColor = FColor::Cyan;
UPROPERTY(Config)
bool CollisionQueryDrawHitShapes = true;
UPROPERTY(Config)
FColor ChannelColorWorldStatic = FColor(255, 0, 0, 5);
UPROPERTY(Config)
FColor ChannelColorWorldDynamic = FColor(255, 0, 188, 5);
UPROPERTY(Config)
FColor ChannelColorPawn = FColor(105, 0, 255, 5);
UPROPERTY(Config)
FColor ChannelColorVisibility = FColor(0, 15, 255, 5);
UPROPERTY(Config)
FColor ChannelColorCamera = FColor(0, 105, 255, 5);
UPROPERTY(Config)
FColor ChannelColorPhysicsBody = FColor(0, 255, 208, 5);
UPROPERTY(Config)
FColor ChannelColorVehicle = FColor(52, 255, 0, 5);
UPROPERTY(Config)
FColor ChannelColorDestructible = FColor(255, 255, 0, 0);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel1 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel2 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel3 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel4 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel5 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel6 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel7 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel8 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel9 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel10 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel11 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel12 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel13 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel14 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel15 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel16 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel17 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
FColor ChannelColorGameTraceChannel18 = FColor(255, 255, 255, 5);
UPROPERTY(Config)
TArray<FString> SecondaryBoneWildcards = {
"interaction",
"center_of_mass",
"ik_*",
"index_*",
"middle_*",
"pinky_*",
"ring_*",
"thumb_*",
"wrist_*",
"*_bck_*",
"*_fwd_*",
"*_in_*",
"*_out_*",
"*_pec_*",
"*_scap_*",
"*_bicep_*",
"*_tricep_*",
"*ankle*",
"*knee*",
"*corrective*",
"*twist*",
"*latissimus*",
};
};
@@ -30,7 +30,7 @@ struct COGDEBUG_API FCogDebugShape
{
ECogDebugShape Type = ECogDebugShape::Invalid;
TArray<FVector> ShapeData;
FColor Color;
FColor Color = FColor::White;
bool bPersistent = false;
float Thickness = 0.0f;
uint8 DepthPriority = 0;
@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugReplicator.h"
#include "CogDebugPluginSubsystem.h"
#include "CogDebugSubsystem.generated.h"
UCLASS()
class COGDEBUG_API UCogDebugSubsystem : public UCogDebugPluginSubsystem
{
GENERATED_BODY()
public:
virtual void OnPlayerControllerReady(APlayerController* InController) override
{
if (InController != nullptr)
{
ACogDebugReplicator::Spawn(InController);
}
}
};
@@ -0,0 +1,34 @@
#pragma once
#include "CoreMinimal.h"
struct FCogDebugTracker;
typedef FName FCogDebugTrackId;
//--------------------------------------------------------------------------------------------------------------------------
enum class ECogDebugTrackType
{
Value,
Event,
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugTrack
{
virtual ~FCogDebugTrack() {}
virtual void Clear() {}
FCogDebugTrackId Id;
float Time = 0;
uint64 Frame = 0;
int32 GraphIndex = 0;
ECogDebugTrackType Type = ECogDebugTrackType::Value;
FCogDebugTracker* Owner = nullptr;
};
@@ -0,0 +1,82 @@
#pragma once
#include "CoreMinimal.h"
#include "CogDebugTrack.h"
#include "CogDebugEvent.h"
#include "CogDebugPlotTrack.h"
#include "CogDebugEventTrack.h"
struct COGDEBUG_API FCogDebugTracker
{
static constexpr int32 AutoRow = -1;
static constexpr int32 MaxNumViews = 5;
static constexpr int32 MaxNumTrackPerView = 10;
void Plot(const UObject* InWorldContextObject, const FCogDebugTrackId InTrackId, const float Value);
FCogDebugEvent& InstantEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
FCogDebugEvent& StartEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, bool IsInstant, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
FCogDebugEvent& StartEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
FCogDebugEvent& StopEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId);
FCogDebugEvent& ToggleEvent(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId, const FCogDebugEventId& InEventId, const bool ToggleValue, const int32 Row = AutoRow, const FColor& Color = FColor::Transparent);
FCogDebugTrack* FindTrack(const FCogDebugTrackId& InTrackId);
void SetNumRecordedValues(int32 InValue);
void Reset();
void Clear();
TMap<FCogDebugTrackId, FCogDebugPlotTrack> Values;
TMap<FCogDebugTrackId, FCogDebugEventTrack> Events;
bool IsVisible = false;
bool Pause = false;
bool RecordValuesWhenPause = true;
private:
friend struct FCogDebugEvent;
friend struct FCogDebugTrack;
friend struct FCogDebugEventTrack;
friend struct FCogDebugPlotTrack;
void ResetLastAddedEvent();
FCogDebugPlotTrack* GetOrCreatePlotTrack(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId);
FCogDebugEventTrack* GetOrCreateEventTrack(const UObject* InWorldContextObject, const FCogDebugTrackId& InTrackId);
bool CanCreateTrack(const UObject* WorldContextObject, const UWorld*& World) const;
static void InitializeTrack(FCogDebugTrack& OutTrack, const UWorld* InWorld, const FCogDebugTrackId& InTrackId);
FCogDebugEvent* GetLastAddedEvent();
void OccupyViewRow(const int32 InViewIndex, const int32 InRow);
void FreeViewRow(const int32 InViewIndex, const int32 InRow);
int32 FindFreeViewRow(const int32 InViewIndex);
static int32 NumRecordedValues;
static FCogDebugEvent DefaultEvent;
FCogDebugTrackId LastAddedEventTrackId = NAME_None;
int32 LastAddedEventIndex = INDEX_NONE;
// view index to row index to number of objects occupying the row
TMap<int32, TMap<int32, int32>> OccupationMap;
};
@@ -18,7 +18,7 @@ private:
/** Pin factory for abilities graph; Cached so it can be unregistered */
TSharedPtr<FCogGraphPanelPinFactory> GraphPanelPinFactory;
EAssetTypeCategories::Type AssetCategory;
EAssetTypeCategories::Type AssetCategory = EAssetTypeCategories::None;
};
IMPLEMENT_MODULE(FCogDebugEditorModule, CogDebugEditor);
@@ -64,7 +64,7 @@ void FCogLogCategoryDetails::CustomizeChildren(TSharedRef<IPropertyHandle> Struc
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogLogCategoryDetails::OnLogCategoryChanged(FName SelectedName)
void FCogLogCategoryDetails::OnLogCategoryChanged(const FName SelectedName) const
{
if (NameProperty.IsValid())
{
@@ -123,7 +123,7 @@ public:
*/
void Construct(const FArguments& InArgs);
virtual ~SLogCategoryListWidget();
virtual ~SLogCategoryListWidget() override;
private:
typedef TTextFilter<const FName&> FLogCategoryTextFilter;
@@ -132,10 +132,10 @@ private:
void OnFilterTextChanged(const FText& InFilterText);
/** Creates the row widget when called by Slate when an item appears on the list. */
TSharedRef< ITableRow > OnGenerateRowForLogCategoryViewer(TSharedPtr<FLogCategoryViewerNode> Item, const TSharedRef< STableViewBase >& OwnerTable);
TSharedRef< ITableRow > OnGenerateRowForLogCategoryViewer(TSharedPtr<FLogCategoryViewerNode> Item, const TSharedRef< STableViewBase >& OwnerTable) const;
/** Called by Slate when an item is selected from the tree/list. */
void OnLogCategorySelectionChanged(TSharedPtr<FLogCategoryViewerNode> Item, ESelectInfo::Type SelectInfo);
void OnLogCategorySelectionChanged(TSharedPtr<FLogCategoryViewerNode> Item, ESelectInfo::Type SelectInfo) const;
/** Updates the list of items in the dropdown menu */
TSharedPtr<FLogCategoryViewerNode> UpdatePropertyOptions();
@@ -146,7 +146,7 @@ private:
/** The search box */
TSharedPtr<SSearchBox> SearchBoxPtr;
/** Holds the Slate List widget which holds the LogCategorys for the LogCategory Viewer. */
/** Holds the Slate List widget which holds the LogCategory for the LogCategory Viewer. */
TSharedPtr<SListView<TSharedPtr< FLogCategoryViewerNode > >> LogCategoryList;
/** Array of items that can be selected in the dropdown menu */
@@ -229,7 +229,7 @@ void SLogCategoryListWidget::Construct(const FArguments& InArgs)
}
//--------------------------------------------------------------------------------------------------------------------------
TSharedRef<ITableRow> SLogCategoryListWidget::OnGenerateRowForLogCategoryViewer(TSharedPtr<FLogCategoryViewerNode> Item, const TSharedRef< STableViewBase >& OwnerTable)
TSharedRef<ITableRow> SLogCategoryListWidget::OnGenerateRowForLogCategoryViewer(TSharedPtr<FLogCategoryViewerNode> Item, const TSharedRef< STableViewBase >& OwnerTable) const
{
TSharedRef< SLogCategoryItem > ReturnRow = SNew(SLogCategoryItem, OwnerTable)
.HighlightText(SearchBoxPtr->GetText())
@@ -273,7 +273,7 @@ void SLogCategoryListWidget::OnFilterTextChanged(const FText& InFilterText)
}
//--------------------------------------------------------------------------------------------------------------------------
void SLogCategoryListWidget::OnLogCategorySelectionChanged(TSharedPtr<FLogCategoryViewerNode> Item, ESelectInfo::Type SelectInfo)
void SLogCategoryListWidget::OnLogCategorySelectionChanged(TSharedPtr<FLogCategoryViewerNode> Item, ESelectInfo::Type SelectInfo) const
{
OnLogCategoryPicked.ExecuteIfBound(Item->Name);
}
@@ -1,4 +1,3 @@
#pragma once
#include "Modules/ModuleInterface.h"
@@ -9,7 +8,7 @@ class ICogDebugEditorModule : public IModuleInterface
public:
static inline ICogDebugEditorModule& Get() { return FModuleManager::LoadModuleChecked<ICogDebugEditorModule>("CogDebugEditor"); }
static ICogDebugEditorModule& Get() { return FModuleManager::LoadModuleChecked<ICogDebugEditorModule>("CogDebugEditor"); }
static inline bool IsAvailable() { return FModuleManager::Get().IsModuleLoaded("CogDebugEditor"); }
static bool IsAvailable() { return FModuleManager::Get().IsModuleLoaded("CogDebugEditor"); }
};
@@ -17,6 +17,6 @@ class FCogGraphPanelPinFactory : public FGraphPanelPinFactory
{
return SNew(SCogLogCategoryGraphPin, InPin);
}
return NULL;
return nullptr;
}
};
@@ -20,5 +20,5 @@ private:
TSharedPtr<IPropertyHandle> NameProperty;
TArray<TSharedPtr<FString>> PropertyOptions;
void OnLogCategoryChanged(FName SelectedName);
void OnLogCategoryChanged(FName SelectedName) const;
};
@@ -15,16 +15,18 @@ public class CogEngine : ModuleRules
PrivateDependencyModuleNames.AddRange(
new []
{
"ApplicationCore",
"CogCommon",
"CogImgui",
"CogWindow",
"Cog",
"Core",
"CoreUObject",
"Engine",
"InputCore",
"NetCore",
"Slate",
"SlateCore",
"SlateCore",
"BuildSettings",
});
if (Target.bBuildEditor)
@@ -14,10 +14,10 @@ ACogEngineCollisionTester::ACogEngineCollisionTester(const FObjectInitializer& O
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
StartComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Start"));
StartComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Start"));
RootComponent = StartComponent;
EndComponent = CreateDefaultSubobject<USceneComponent>(TEXT("End"));
EndComponent = CreateDefaultSubobject<USceneComponent>(TEXT("End"));
EndComponent->SetupAttachment(RootComponent);
EndComponent->SetRelativeLocation(FVector(1000, 0, 0));
}
@@ -29,7 +29,7 @@ bool ACogEngineCollisionTester::ShouldTickIfViewportsOnly() const
{
return true;
}
return false;
}
@@ -42,11 +42,13 @@ void ACogEngineCollisionTester::Tick(float DeltaSeconds)
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineCollisionTester::Query() const
{
const UWorld* World = GetWorld();
FVector QueryStart = StartComponent->GetComponentLocation();
FVector QueryEnd = EndComponent->GetComponentLocation();
FQuat QueryRotation = StartComponent->GetComponentQuat();
bool HasHits = false;
static const FName TraceTag(TEXT("FCogWindow_Collision"));
const FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogHitDetection), TraceComplex);
@@ -58,243 +60,284 @@ void ACogEngineCollisionTester::Query() const
{
switch (Shape)
{
case ECogEngine_CollisionQueryShape::Sphere: QueryShape.SetSphere(ShapeExtent.X); break;
case ECogEngine_CollisionQueryShape::Capsule: QueryShape.SetCapsule(ShapeExtent.X, ShapeExtent.Z); break;
case ECogEngine_CollisionQueryShape::Box: QueryShape.SetBox(FVector3f(ShapeExtent)); break;
case ECogEngine_CollisionQueryShape::Sphere: QueryShape.SetSphere(ShapeExtent.X);
break;
case ECogEngine_CollisionQueryShape::Capsule: QueryShape.SetCapsule(ShapeExtent.X, ShapeExtent.Z);
break;
case ECogEngine_CollisionQueryShape::Box: QueryShape.SetBox(FVector3f(ShapeExtent));
break;
}
}
switch (Type)
{
case ECogEngine_CollisionQueryType::Overlap:
{
TArray<FOverlapResult> Overlaps;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
HasHits = GetWorld()->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryType::Overlap:
{
TArray<FOverlapResult> Overlaps;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (OverlapMode)
{
case ECogEngine_CollisionQueryOverlapMode::AnyTest:
HasHits = World->OverlapAnyTestByChannel(QueryStart, QueryRotation, TraceChannel, QueryShape, QueryParams);
break;
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
HasHits = GetWorld()->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryOverlapMode::BlockingTest:
HasHits = World->OverlapBlockingTestByChannel(QueryStart, QueryRotation, TraceChannel, QueryShape, QueryParams);
break;
case ECogEngine_CollisionQueryBy::Profile:
{
HasHits = GetWorld()->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
case ECogEngine_CollisionQueryOverlapMode::Multi:
HasHits = World->OverlapMultiByChannel(Overlaps, QueryStart, QueryRotation, TraceChannel, QueryShape, QueryParams);
break;
}
break;
}
FCogDebugDrawOverlapParams DrawParams;
FCogDebug::GetDebugDrawOverlapSettings(DrawParams);
FCogDebugDrawHelper::DrawOverlap(GetWorld(), QueryShape, QueryStart, QueryRotation, Overlaps, DrawParams);
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
case ECogEngine_CollisionQueryType::LineTrace:
{
TArray<FHitResult> Hits;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, Channel, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, Channel, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByChannel(QueryStart, QueryEnd, Channel, QueryParams);
break;
}
}
switch (OverlapMode)
{
case ECogEngine_CollisionQueryOverlapMode::AnyTest:
HasHits = World->OverlapAnyTestByObjectType(QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
break;
}
case ECogEngine_CollisionQueryOverlapMode::BlockingTest:
break;
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
case ECogEngine_CollisionQueryOverlapMode::Multi:
HasHits = World->OverlapMultiByObjectType(Overlaps, QueryStart, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
break;
}
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByObjectType(QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (OverlapMode)
{
case ECogEngine_CollisionQueryOverlapMode::AnyTest:
HasHits = World->OverlapAnyTestByProfile(QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, ProfileName, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->LineTraceTestByProfile(QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
}
break;
}
}
case ECogEngine_CollisionQueryOverlapMode::BlockingTest:
HasHits = World->OverlapBlockingTestByProfile(QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
FCogDebugDrawLineTraceParams DrawParams;
FCogDebug::GetDebugDrawLineTraceSettings(DrawParams);
FCogDebugDrawHelper::DrawLineTrace(GetWorld(), QueryStart, QueryEnd, HasHits, Hits, DrawParams);
break;
}
case ECogEngine_CollisionQueryOverlapMode::Multi:
HasHits = World->OverlapMultiByProfile(Overlaps, QueryStart, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
break;
}
}
case ECogEngine_CollisionQueryType::Sweep:
{
TArray<FHitResult> Hits;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByChannel(QueryStart, QueryEnd, QueryRotation, Channel, QueryShape, QueryParams);
break;
}
}
break;
}
FCogDebugDrawOverlapParams DrawParams;
FCogDebug::GetDebugDrawOverlapSettings(DrawParams);
FCogDebugDrawHelper::DrawOverlap(World, QueryShape, QueryStart, QueryRotation, HasHits, Overlaps, DrawParams);
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
case ECogEngine_CollisionQueryType::LineTrace:
{
TArray<FHitResult> Hits;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->LineTraceSingleByChannel(Hit, QueryStart, QueryEnd, TraceChannel, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->LineTraceMultiByChannel(Hits, QueryStart, QueryEnd, TraceChannel, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->LineTraceTestByChannel(QueryStart, QueryEnd, TraceChannel, QueryParams);
break;
}
}
break;
}
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByObjectType(Hit, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByObjectType(QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
case ECogEngine_CollisionQueryBy::Profile:
{
switch (Mode)
{
case ECogEngine_CollisionQueryMode::Single:
{
FHitResult Hit;
HasHits = GetWorld()->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryMode::Multi:
{
HasHits = GetWorld()->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryMode::Test:
{
HasHits = GetWorld()->SweepTestByProfile(QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
}
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->LineTraceSingleByObjectType(Hit, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->LineTraceMultiByObjectType(Hits, QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->LineTraceTestByObjectType(QueryStart, QueryEnd, QueryObjectParams, QueryParams);
break;
}
}
break;
}
FCogDebugDrawSweepParams DrawParams;
FCogDebug::GetDebugDrawSweepSettings(DrawParams);
FCogDebugDrawHelper::DrawSweep(GetWorld(), QueryShape, QueryStart, QueryEnd, QueryRotation, HasHits, Hits, DrawParams);
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->LineTraceSingleByProfile(Hit, QueryStart, QueryEnd, ProfileName, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->LineTraceMultiByProfile(Hits, QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->LineTraceTestByProfile(QueryStart, QueryEnd, ProfileName, QueryParams);
break;
}
}
break;
}
}
FCogDebugDrawLineTraceParams DrawParams;
FCogDebug::GetDebugDrawLineTraceSettings(DrawParams);
FCogDebugDrawHelper::DrawLineTrace(World, QueryStart, QueryEnd, HasHits, Hits, DrawParams);
break;
}
case ECogEngine_CollisionQueryType::Sweep:
{
TArray<FHitResult> Hits;
switch (By)
{
case ECogEngine_CollisionQueryBy::Channel:
{
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->SweepSingleByChannel(Hit, QueryStart, QueryEnd, QueryRotation, TraceChannel, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->SweepMultiByChannel(Hits, QueryStart, QueryEnd, QueryRotation, TraceChannel, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->SweepTestByChannel(QueryStart, QueryEnd, QueryRotation, TraceChannel, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::ObjectType:
{
FCollisionObjectQueryParams QueryObjectParams;
QueryObjectParams.ObjectTypesToQuery = ObjectTypesToQuery;
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->SweepSingleByObjectType(Hit, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->SweepMultiByObjectType(Hits, QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->SweepTestByObjectType(QueryStart, QueryEnd, QueryRotation, QueryObjectParams, QueryShape, QueryParams);
break;
}
}
break;
}
case ECogEngine_CollisionQueryBy::Profile:
{
switch (TraceMode)
{
case ECogEngine_CollisionQueryTraceMode::Single:
{
FHitResult Hit;
HasHits = World->SweepSingleByProfile(Hit, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
if (HasHits)
{
Hits.Add(Hit);
}
break;
}
case ECogEngine_CollisionQueryTraceMode::Multi:
{
HasHits = World->SweepMultiByProfile(Hits, QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
case ECogEngine_CollisionQueryTraceMode::Test:
{
HasHits = World->SweepTestByProfile(QueryStart, QueryEnd, QueryRotation, ProfileName, QueryShape, QueryParams);
break;
}
}
break;
}
}
FCogDebugDrawSweepParams DrawParams;
FCogDebug::GetDebugDrawSweepSettings(DrawParams);
FCogDebugDrawHelper::DrawSweep(World, QueryShape, QueryStart, QueryEnd, QueryRotation, HasHits, Hits, DrawParams);
break;
}
}
}
@@ -1,12 +1,12 @@
#include "CogEngineDataAsset.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineCheat_Execution::Execute_Implementation(const AActor* Instigator, const TArray<AActor*>& Targets) const
void UCogEngineCheat_Execution::Execute_Implementation(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const
{
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState UCogEngineCheat_Execution::IsActiveOnTargets_Implementation(const TArray<AActor*>& Targets) const
ECogEngineCheat_ActiveState UCogEngineCheat_Execution::IsActiveOnTargets_Implementation(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const
{
return ECogEngineCheat_ActiveState::Inactive;
}
@@ -1,8 +1,7 @@
#include "CogEngineHelper.h"
#include "CogEngineReplicator.h"
#include "CogWindowHelper.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "imgui.h"
#include "GameFramework/Actor.h"
#include "GameFramework/Pawn.h"
@@ -15,10 +14,10 @@
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineHelper::ActorContextMenu(AActor& Actor)
{
FCogWindowWidgets::ThinSeparatorText("Object");
FCogWidgets::ThinSeparatorText("Object");
#if WITH_EDITOR
FCogWindowWidgets::OpenObjectAssetButton(&Actor, ImVec2(-1, 0));
FCogWidgets::OpenObjectAssetButton(&Actor, ImVec2(-1, 0));
#endif
if (ImGui::Button("Delete", ImVec2(-1, 0)))
@@ -31,7 +30,7 @@ void FCogEngineHelper::ActorContextMenu(AActor& Actor)
if (APawn* Pawn = Cast<APawn>(&Actor))
{
FCogWindowWidgets::ThinSeparatorText("Pawn");
FCogWidgets::ThinSeparatorText("Pawn");
if (ImGui::Button("Possess", ImVec2(-1, 0)))
{
@@ -55,4 +54,17 @@ void FCogEngineHelper::ActorContextMenu(AActor& Actor)
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineHelper::RenderConfigureMessage(const TWeakObjectPtr<const UCogEngineDataAsset> InAsset)
{
if (InAsset == nullptr)
{
ImGui::Text("Create a DataAsset child of '%s' to configure. ", StringCast<ANSICHAR>(*UCogEngineDataAsset::StaticClass()->GetName()).Get());
}
else
{
ImGui::Text("Can be configured in the '%s' DataAsset. ", StringCast<ANSICHAR>(*GetNameSafe(InAsset.Get())).Get());
}
}
@@ -3,6 +3,7 @@
#include "CogCommon.h"
#include "CogCommonPossessorInterface.h"
#include "CogEngineDataAsset.h"
#include "CogSubsystem.h"
#include "Engine/EngineTypes.h"
#include "Engine/World.h"
#include "EngineUtils.h"
@@ -32,12 +33,13 @@ ACogEngineReplicator* ACogEngineReplicator::Spawn(APlayerController* Controller)
//--------------------------------------------------------------------------------------------------------------------------
ACogEngineReplicator* ACogEngineReplicator::GetLocalReplicator(const UWorld& World)
{
for (TActorIterator<ACogEngineReplicator> It(&World, StaticClass()); It; ++It)
const TActorIterator<ACogEngineReplicator> It(&World, StaticClass());
if (It)
{
ACogEngineReplicator* Replicator = *It;
return Replicator;
}
return nullptr;
}
@@ -226,20 +228,24 @@ void ACogEngineReplicator::Server_DeleteActor_Implementation(AActor* Actor)
void ACogEngineReplicator::Server_ApplyCheat_Implementation(const AActor* CheatInstigator, const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat) const
{
if (Cheat.Execution == nullptr)
{
return;
}
{ return; }
Cheat.Execution->Execute(CheatInstigator, Targets);
if (GetWorld() == nullptr)
{ return; }
Cheat.Execution->Execute(GetWorld(), CheatInstigator, Targets);
}
//--------------------------------------------------------------------------------------------------------------------------
ECogEngineCheat_ActiveState ACogEngineReplicator::IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat)
ECogEngineCheat_ActiveState ACogEngineReplicator::IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat) const
{
if (GetWorld() == nullptr)
{ return ECogEngineCheat_ActiveState::Inactive; }
if (Cheat.Execution == nullptr)
{
return ECogEngineCheat_ActiveState::Inactive;
}
return Cheat.Execution->IsActiveOnTargets(Targets);
return Cheat.Execution->IsActiveOnTargets(GetWorld(), Targets);
}
@@ -5,9 +5,7 @@
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Audio::RenderHelp()
{
ImGui::Text(
"This window displays audio settings. "
);
ImGui::Text("This window displays audio settings.");
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,126 @@
#include "CogEngineWindow_BuildInfo.h"
#include "CogImguiHelper.h"
#include "imgui.h"
#include "BuildSettings.h"
#include "GenericPlatform/GenericPlatformMisc.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_BuildInfo::Initialize()
{
FCogWindow::Initialize();
Config = GetConfig<UCogEngineConfig_BuildInfo>();
BuildText();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_BuildInfo::RenderHelp()
{
ImGui::Text(
"This window can be used to display the build information such as the build version, changelist, date, target, and so on."
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_BuildInfo::RenderTick(float DeltaTime)
{
FCogWindow::RenderTick(DeltaTime);
if (FApp::GetBuildTargetType() == EBuildTargetType::Editor)
{
if (Config->ShowInEditor == false)
{ return; }
}
else
{
if (Config->ShowInPackage == false)
{ return;}
}
const auto TextStr = StringCast<ANSICHAR>(*Text);
ImDrawList* DrawList = Config->ShowInForeground ? ImGui::GetForegroundDrawList() : ImGui::GetBackgroundDrawList();
const ImVec2 WindowPadding = ImGui::GetStyle().WindowPadding;
const ImVec2 TextSize = ImGui::CalcTextSize(TextStr.Get(), nullptr, false);
const ImVec2 RectSize = TextSize + WindowPadding * 2;
const ImVec2 Pos = FCogWidgets::ComputeScreenCornerLocation(Config->Alignment, Config->Padding);
const ImVec2 AlignedPos = Pos - (FCogImguiHelper::ToImVec2(Config->Alignment) * RectSize);
DrawList->AddRectFilled(AlignedPos, AlignedPos + RectSize, FCogImguiHelper::ToImU32(Config->BackgroundColor), Config->Rounding);
DrawList->AddRect(AlignedPos, AlignedPos + RectSize, FCogImguiHelper::ToImU32(Config->BorderColor), Config->Rounding);
DrawList->AddText(AlignedPos + WindowPadding, FCogImguiHelper::ToImU32(Config->TextColor), TextStr.Get());
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_BuildInfo::RenderContent()
{
Super::RenderContent();
FCogWidgets::ThinSeparatorText("Build Properties");
if (ImGui::BeginChild("Settings", ImVec2(-1, 100 * GetDpiScale()), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY))
{
if (ImGui::Checkbox("Branch Name", &Config->ShowBranchName)) { BuildText(); }
if (ImGui::Checkbox("Build Date", &Config->ShowBuildDate)) { BuildText(); }
if (ImGui::Checkbox("Build Configuration", &Config->ShowBuildConfiguration)) { BuildText(); }
if (ImGui::Checkbox("Build User", &Config->ShowBuildUser)) { BuildText(); }
if (ImGui::Checkbox("Build Machine", &Config->ShowBuildMachine)) { BuildText(); }
if (ImGui::Checkbox("Build Target Type", &Config->ShowBuildTargetType)) { BuildText(); }
if (ImGui::Checkbox("Current Change list", &Config->ShowCurrentChangelist)) { BuildText(); }
if (ImGui::Checkbox("Compatible Change list", &Config->ShowCompatibleChangelist)) { BuildText(); }
}
ImGui::EndChild();
FCogWidgets::ThinSeparatorText("Display");
ImGui::Checkbox("Show In Editor", &Config->ShowInEditor);
ImGui::Checkbox("Show In Package", &Config->ShowInPackage);
ImGui::Checkbox("Show In Foreground", &Config->ShowInForeground);
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat2("Alignment", &Config->Alignment.X, 0, 1.0f, "%.2f");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt2("Padding", &Config->Padding.X, 0, 100);
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Rounding", &Config->Rounding, 0, 12);
if (FCogWidgets::InputText("Separator", Config->Separator))
{
BuildText();
}
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("Background Color", Config->BackgroundColor, ColorEditFlags);
FCogImguiHelper::ColorEdit4("Border Color", Config->BorderColor, ColorEditFlags);
FCogImguiHelper::ColorEdit4("Text Color", Config->TextColor, ColorEditFlags);
ImGui::Separator();
if (ImGui::Button("Reset Settings", ImVec2(-1, 0)))
{
ResetConfig();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_BuildInfo::BuildText()
{
FStringBuilderBase S;
bool AddSeparator = false;
if (Config->ShowBranchName) { S.Append(BuildSettings::GetBranchName()); S.Append(Config->Separator); }
if (Config->ShowBuildDate) { S.Append(BuildSettings::GetBuildDate()); S.Append(Config->Separator); }
if (Config->ShowBuildConfiguration) { S.Append(LexToString(FApp::GetBuildConfiguration())); S.Append(Config->Separator); }
if (Config->ShowBuildTargetType) { S.Append(LexToString(FApp::GetBuildTargetType())); S.Append(Config->Separator); }
if (Config->ShowBuildUser) { S.Append(BuildSettings::GetBuildUser()); S.Append(Config->Separator); }
if (Config->ShowBuildMachine) { S.Append(BuildSettings::GetBuildMachine()); S.Append(Config->Separator); }
if (Config->ShowCurrentChangelist) { S.Appendf(TEXT("%d"), BuildSettings::GetCurrentChangelist()); S.Append(Config->Separator); }
if (Config->ShowCompatibleChangelist) { S.Appendf(TEXT("%d"),BuildSettings::GetCompatibleChangelist()); S.Append(Config->Separator); }
S.RemoveSuffix(Config->Separator.Len());
Text = FString(S);
}
@@ -3,9 +3,10 @@
#include "CogEngineDataAsset.h"
#include "CogEngineReplicator.h"
#include "CogCommonAllegianceActorInterface.h"
#include "CogEngineHelper.h"
#include "CogImguiHelper.h"
#include "CogWindowConsoleCommandManager.h"
#include "CogWindowWidgets.h"
#include "CogConsoleCommandManager.h"
#include "CogWidgets.h"
#include "EngineUtils.h"
#include "GameFramework/Character.h"
#include "imgui.h"
@@ -16,13 +17,13 @@ void FCogEngineWindow_Cheats::RenderHelp()
{
ImGui::Text(
"This window can be used to apply cheats to the selected actor (by default). "
"The cheats can be configured in the '%s' data asset. "
"When clicking a cheat button, press:\n"
" [CTRL] to apply the cheat to controlled actor\n"
" [ALT] to apply the cheat to the allies of the selected actor\n"
" [SHIFT] to apply the cheat to the enemies of the selected actor\n"
, TCHAR_TO_ANSI(*GetNameSafe(Asset.Get()))
);
FCogEngineHelper::RenderConfigureMessage(Asset);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -35,26 +36,34 @@ void FCogEngineWindow_Cheats::Initialize()
Asset = GetAsset<UCogEngineDataAsset>();
Config = GetConfig<UCogEngineConfig_Cheats>();
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.Cheat"),
TEXT("Apply a cheat to the selection. Cog.Cheat <CheatName> -Allies -Enemies -Controlled"),
GetWorld(),
FCogWindowConsoleCommandDelegate::CreateLambda([this](const TArray<FString>& InArgs, UWorld* InWorld)
FCogWindowConsoleCommandDelegate::CreateLambda([this](const TArray<FString>& InArgs, const UWorld* InWorld)
{
if (InArgs.Num() > 0)
{
if (const FCogEngineCheat* cheat = FindCheatByName(InArgs[0], false))
{
const bool ApplyToEnemies = InArgs.Contains("-Enemies");
const bool ApplyToAllies = InArgs.Contains("-Allies");
const bool ApplyToControlled = InArgs.Contains("-Controlled");
RequestCheat(GetLocalPlayerPawn(), GetSelection(), *cheat, ApplyToEnemies, ApplyToAllies, ApplyToControlled);
}
else
const FCogEngineCheat* Cheat = FindCheatByName(InArgs[0], false);
if (Cheat == nullptr)
{
UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Cheat not found"), *InArgs[0]);
return;
}
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*InWorld);
if (Replicator == nullptr)
{
UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Replicator not found"), *InArgs[0]);
return;
}
const bool ApplyToEnemies = InArgs.Contains("-Enemies");
const bool ApplyToAllies = InArgs.Contains("-Allies");
const bool ApplyToControlled = InArgs.Contains("-Controlled");
AActor* Selection = GetSelection();
RequestCheat(*Replicator, GetLocalPlayerPawn(), Selection, *Cheat, ApplyToEnemies, ApplyToAllies, ApplyToControlled);
}
}));
@@ -64,12 +73,12 @@ void FCogEngineWindow_Cheats::Initialize()
for (const FCogEngineCheatCategory& CheatCategory : Asset->CheatCategories)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
UpdateCheatColor(Cheat);
}
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
UpdateCheatColor(Cheat);
}
@@ -90,14 +99,6 @@ void FCogEngineWindow_Cheats::UpdateCheatColor(const FCogEngineCheat& Cheat) con
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Cheats::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Cheats::GameTick(float DeltaTime)
{
@@ -187,6 +188,13 @@ void FCogEngineWindow_Cheats::RenderContent()
return;
}
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
ImGui::TextDisabled("No Replicator");
return;
}
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
@@ -243,7 +251,7 @@ void FCogEngineWindow_Cheats::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::SearchBar(Filter);
FCogWidgets::SearchBar("##Filter", Filter);
ImGui::EndMenuBar();
}
@@ -266,7 +274,7 @@ void FCogEngineWindow_Cheats::RenderContent()
bool Open = true;
if (Config->bGroupByCategories)
{
Open = FCogWindowWidgets::DarkCollapsingHeader(CategoryStr.Get(), ImGuiTreeNodeFlags_DefaultOpen);
Open = FCogWidgets::DarkCollapsingHeader(CategoryStr.Get(), ImGuiTreeNodeFlags_DefaultOpen);
if (Open && Config->bUseTwoColumns)
{
@@ -284,9 +292,9 @@ void FCogEngineWindow_Cheats::RenderContent()
}
int Index = 0;
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
AddCheat(Index, ControlledActor, SelectedActor, Cheat, true);
AddCheat(*Replicator, Index, ControlledActor, SelectedActor, Cheat, true);
Index++;
}
@@ -298,10 +306,10 @@ void FCogEngineWindow_Cheats::RenderContent()
//----------------------------------------------------------------------------
if (SelectedActor == ControlledActor)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
TArray<AActor*> Targets = { SelectedActor };
if (ACogEngineReplicator::IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active)
if (Replicator->IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active)
{
Config->AppliedCheats.AddUnique(Cheat.Name);
}
@@ -315,9 +323,9 @@ void FCogEngineWindow_Cheats::RenderContent()
ImGui::TableNextColumn();
Index = 0;
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
AddCheat(Index, ControlledActor, SelectedActor, Cheat, false);
AddCheat(*Replicator, Index, ControlledActor, SelectedActor, Cheat, false);
Index++;
}
@@ -335,7 +343,7 @@ void FCogEngineWindow_Cheats::RenderContent()
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool IsPersistent)
bool FCogEngineWindow_Cheats::AddCheat(ACogEngineReplicator& Replicator, const int32 Index, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool IsPersistent)
{
const auto CheatName = StringCast<ANSICHAR>(*Cheat.Name);
@@ -344,7 +352,7 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
ImGui::PushID(Index);
FCogWindowWidgets::PushBackColor(FCogImguiHelper::ToImVec4(Cheat.CustomColor));
FCogWidgets::PushBackColor(FCogImguiHelper::ToImVec4(Cheat.CustomColor));
const bool IsShiftDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Shift) != 0;
const bool IsAltDown = (ImGui::GetCurrentContext()->IO.KeyMods & ImGuiMod_Alt) != 0;
@@ -354,10 +362,10 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
if (IsPersistent)
{
TArray<AActor*> Targets = { SelectedActor };
bool isEnabled = ACogEngineReplicator::IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active;
bool isEnabled = Replicator.IsCheatActiveOnTargets(Targets, Cheat) == ECogEngineCheat_ActiveState::Active;
if (ImGui::Checkbox(CheatName.Get(), &isEnabled))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
RequestCheat(Replicator, ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
@@ -365,7 +373,7 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
{
if (ImGui::Button(CheatName.Get(), ImVec2(-1, 0)))
{
RequestCheat(ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
RequestCheat(Replicator, ControlledActor, SelectedActor, Cheat, IsShiftDown, IsAltDown, IsControlDown);
bIsPressed = true;
}
}
@@ -373,14 +381,14 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown || IsAltDown || IsControlDown ? 0.5f : 1.0f), "On Selection");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown ? 1.0f : 0.5f), "On Enemies [SHIFT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsAltDown ? 1.0f : 0.5f), "On Allies [ALT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "On Controlled [CTRL]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown || IsAltDown || IsControlDown ? 0.5f : 1.0f), "Selection");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsShiftDown ? 1.0f : 0.5f), "Enemies [SHIFT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsAltDown ? 1.0f : 0.5f), "Allies [ALT]");
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, IsControlDown ? 1.0f : 0.5f), "Controlled [CTRL]");
ImGui::EndTooltip();
}
FCogWindowWidgets::PopBackColor();
FCogWidgets::PopBackColor();
ImGui::PopID();
@@ -388,7 +396,7 @@ bool FCogEngineWindow_Cheats::AddCheat(const int32 Index, AActor* ControlledActo
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled)
void FCogEngineWindow_Cheats::RequestCheat(ACogEngineReplicator& Replicator, AActor* ControlledActor, AActor* SelectedActor, const FCogEngineCheat& Cheat, bool ApplyToEnemies, bool ApplyToAllies, bool ApplyToControlled)
{
TArray<AActor*> Actors;
@@ -424,22 +432,18 @@ void FCogEngineWindow_Cheats::RequestCheat(AActor* ControlledActor, AActor* Sele
Actors.Add(SelectedActor);
}
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_ApplyCheat(ControlledActor, Actors, Cheat);
}
else
{
UE_LOG(LogCogImGui, Warning, TEXT("FCogAbilityWindow_Cheats::RequestCheat | Replicator not found"));
}
Replicator.Server_ApplyCheat(ControlledActor, Actors, Cheat);
}
//--------------------------------------------------------------------------------------------------------------------------
const FCogEngineCheat* FCogEngineWindow_Cheats::FindCheatByName(const FString& CheatName, const bool OnlyPersistentCheats)
{
if (Asset == nullptr)
{ return nullptr; }
for (const FCogEngineCheatCategory& CheatCategory : Asset->CheatCategories)
{
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.PersistentCheats)
{
if (Cheat.Name == CheatName)
{
@@ -448,19 +452,15 @@ const FCogEngineCheat* FCogEngineWindow_Cheats::FindCheatByName(const FString& C
}
if (OnlyPersistentCheats)
{
continue;
}
{ continue; }
for (const FCogEngineCheat& Cheat : CheatCategory.InstantEffects)
for (const FCogEngineCheat& Cheat : CheatCategory.InstantCheats)
{
if (Cheat.Name == CheatName)
{
return &Cheat;
}
}
}
return nullptr;
@@ -2,7 +2,7 @@
#include "CogDebug.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SceneComponent.h"
#include "Engine/CollisionProfile.h"
@@ -25,14 +25,6 @@ void FCogEngineWindow_CollisionTester::RenderHelp()
ImGui::Text("This window is used to test a collision query.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionTester::RenderContent()
{
@@ -55,7 +47,7 @@ void FCogEngineWindow_CollisionTester::RenderContent()
NewActor->SetActorLabel(NewActor->GetName().Replace(TEXT("CogEngine"), TEXT("")));
#endif
FCogDebug::SetSelection(GetWorld(), NewActor);
FCogDebug::SetSelection(NewActor);
}
if (ImGui::BeginItemTooltip())
{
@@ -85,9 +77,9 @@ void FCogEngineWindow_CollisionTester::RenderContent()
ImGui::SetNextItemWidth(-1);
AActor* NewSelection = nullptr;
if (FCogWindowWidgets::MenuActorsCombo("CollisionTesters", NewSelection, *GetWorld(), ACogEngineCollisionTester::StaticClass()))
if (FCogWidgets::MenuActorsCombo("CollisionTesters", NewSelection, *GetWorld(), ACogEngineCollisionTester::StaticClass()))
{
FCogDebug::SetSelection(GetWorld(), NewSelection);
FCogDebug::SetSelection(NewSelection);
}
ImGui::EndMenuBar();
@@ -111,28 +103,41 @@ void FCogEngineWindow_CollisionTester::RenderContent()
if (const APlayerController* LocalPlayerController = GetLocalPlayerController())
{
StartGizmo.Draw("CollisionTesterStartGizmo", *LocalPlayerController, *CollisionTester->StartComponent);
EndGizmo.Draw("CollisionTesterEndGizmo", *LocalPlayerController, *CollisionTester->EndComponent, ECogDebug_GizmoFlags::NoRotation | ECogDebug_GizmoFlags::NoScale);
if (CollisionTester->Type != ECogEngine_CollisionQueryType::Overlap)
{
EndGizmo.Draw("CollisionTesterEndGizmo", *LocalPlayerController, *CollisionTester->EndComponent, ECogDebug_GizmoFlags::NoRotation | ECogDebug_GizmoFlags::NoScale);
}
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Type", CollisionTester->Type);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Type", CollisionTester->Type);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Mode", CollisionTester->Mode);
if (CollisionTester->Type == ECogEngine_CollisionQueryType::Overlap)
{
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Mode", CollisionTester->OverlapMode);
}
else
{
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Mode", CollisionTester->TraceMode);
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("By", CollisionTester->By);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("By", CollisionTester->By);
//-------------------------------------------------
// Channel
//-------------------------------------------------
if (CollisionTester->By == ECogEngine_CollisionQueryBy::Channel)
{
FCogWindowWidgets::SetNextItemToShortWidth();
ECollisionChannel Channel = CollisionTester->Channel.GetValue();
if (FCogWindowWidgets::ComboCollisionChannel("Channel", Channel))
FCogWidgets::SetNextItemToShortWidth();
ECollisionChannel Channel = CollisionTester->TraceChannel.GetValue();
if (FCogWidgets::ComboTraceChannel("Channel", Channel))
{
CollisionTester->Channel = Channel;
CollisionTester->TraceChannel = Channel;
}
}
//-------------------------------------------------
@@ -143,7 +148,7 @@ void FCogEngineWindow_CollisionTester::RenderContent()
const FCollisionResponseTemplate* SelectedProfile = CollisionProfile->GetProfileByIndex(CollisionTester->ProfileIndex);
const FName SelectedProfileName = SelectedProfile != nullptr ? SelectedProfile->Name : FName("Custom");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("Profile", TCHAR_TO_ANSI(*SelectedProfileName.ToString()), ImGuiComboFlags_HeightLargest))
{
for (int i = 0; i < CollisionProfile->GetNumOfProfiles(); ++i)
@@ -153,13 +158,12 @@ void FCogEngineWindow_CollisionTester::RenderContent()
{
CollisionTester->ProfileIndex = i;
CollisionTester->ObjectTypesToQuery = 0;
SelectedProfile = CollisionProfile->GetProfileByIndex(CollisionTester->ProfileIndex);
if (Profile->CollisionEnabled != ECollisionEnabled::NoCollision)
{
for (int j = 0; j < ECC_MAX; ++j)
{
const ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j);
const ECollisionResponse Response = Profile->ResponseToChannels.GetResponse(static_cast<ECollisionChannel>(j));
if (Response != ECR_Ignore)
{
CollisionTester->ObjectTypesToQuery |= ECC_TO_BITFIELD(j);
@@ -180,31 +184,31 @@ void FCogEngineWindow_CollisionTester::RenderContent()
if (CollisionTester->Type != ECogEngine_CollisionQueryType::LineTrace)
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Shape", CollisionTester->Shape);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Shape", CollisionTester->Shape);
switch (CollisionTester->Shape)
{
case ECogEngine_CollisionQueryShape::Sphere:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Sphere Radius", &CollisionTester->ShapeExtent.X, 1.0f, 0, FLT_MAX, "%.1f");
break;
}
case ECogEngine_CollisionQueryShape::Box:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragFVector("Box Extent", CollisionTester->ShapeExtent, 1.0f, 0, FLT_MAX, "%.1f");
break;
}
case ECogEngine_CollisionQueryShape::Capsule:
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Capsule Radius", &CollisionTester->ShapeExtent.X, 1.0f, 0, FLT_MAX, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
FCogImguiHelper::DragDouble("Capsule Half Height", &CollisionTester->ShapeExtent.Z, 1.0f, 0, FLT_MAX, "%.1f");
break;
}
@@ -218,12 +222,12 @@ void FCogEngineWindow_CollisionTester::RenderContent()
{
ImGui::Separator();
ImGui::BeginDisabled();
FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery);
FCogWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery);
ImGui::EndDisabled();
}
else if (CollisionTester->By == ECogEngine_CollisionQueryBy::ObjectType)
{
ImGui::Separator();
FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery);
FCogWidgets::CollisionObjectTypeChannels(CollisionTester->ObjectTypesToQuery);
}
}
@@ -2,9 +2,8 @@
#include "CogDebugDrawHelper.h"
#include "CogDebug.h"
#include "CogEngineCollisionTester.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Components/PrimitiveComponent.h"
#include "Components/SceneComponent.h"
#include "DrawDebugHelpers.h"
@@ -32,14 +31,6 @@ void FCogEngineWindow_CollisionViewer::RenderHelp()
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionViewer::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_CollisionViewer::RenderContent()
{
@@ -128,7 +119,7 @@ void FCogEngineWindow_CollisionViewer::RenderContent()
{
for (int j = 0; j < ECC_MAX; ++j)
{
ECollisionResponse Response = Profile->ResponseToChannels.GetResponse((ECollisionChannel)j);
ECollisionResponse Response = Profile->ResponseToChannels.GetResponse(static_cast<ECollisionChannel>(j));
if (Response != ECR_Ignore)
{
Config->ObjectTypesToQuery |= ECC_TO_BITFIELD(j);
@@ -141,7 +132,7 @@ void FCogEngineWindow_CollisionViewer::RenderContent()
}
ImGui::Separator();
FCogWindowWidgets::CollisionProfileChannels(Config->ObjectTypesToQuery);
FCogWidgets::CollisionObjectTypeChannels(Config->ObjectTypesToQuery);
//-------------------------------------------------
// Perform Query
@@ -190,6 +181,8 @@ void FCogEngineWindow_CollisionViewer::RenderContent()
QueryRadius = Config->QueryThickness;
break;
}
default: break;
}
static const FName TraceTag(TEXT("FCogWindow_Collision"));
@@ -1,7 +1,7 @@
#include "CogEngineWindow_CommandBindings.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/PlayerInput.h"
#include "imgui.h"
@@ -35,51 +35,44 @@ void FCogEngineWindow_CommandBindings::RenderContent()
int32 Index = 0;
int32 IndexToRemove = INDEX_NONE;
if (FCogWindowWidgets::ButtonWithTooltip("Add", "Add a new item in the array"))
if (FCogWidgets::ButtonWithTooltip("Add", "Add a new item in the array"))
{
PlayerInput->DebugExecBindings.AddDefaulted();
PlayerInput->SaveConfig();
}
ImGui::SameLine();
if (FCogWindowWidgets::ButtonWithTooltip("Sort", "Sort the array"))
if (FCogWidgets::ButtonWithTooltip("Sort", "Sort the array"))
{
UCogWindowManager::SortCommands(PlayerInput);
UCogSubsystem::SortCommands(PlayerInput);
PlayerInput->SaveConfig();
}
ImGui::SameLine();
if (FCogWindowWidgets::ButtonWithTooltip(
"Register Default Commands",
"Register the default commands used to control Cog:\n\n"
"[Tab] Cog.ToggleInput\n"
"[F1] Cog.LoadLayout 1\n"
"[F2] Cog.LoadLayout 2\n"
"[F3] Cog.LoadLayout 3\n"
"[F4] Cog.LoadLayout 4\n"
"[F5] Cog.ToggleSelectionMode\n"
if (FCogWidgets::ButtonWithTooltip(
"Disable Conflicting Commands",
"Disable the existing Unreal command shortcuts mapped to same shortcuts Cog is using. Typically, if the F1 shortcut is used to toggle Inputs, the Unreal wireframe command will get disabled."
))
{
GetOwner()->RegisterDefaultCommandBindings();
//GetOwner()->OnShortcutsDefined();
}
for (FKeyBind& KeyBind : PlayerInput->DebugExecBindings)
{
ImGui::PushID(Index);
if (FCogWindowWidgets::DeleteArrayItemButton())
if (FCogWidgets::DeleteArrayItemButton())
{
IndexToRemove = Index;
}
ImGui::SameLine();
if (FCogWindowWidgets::KeyBind(KeyBind))
if (FCogWidgets::KeyBind(KeyBind))
{
PlayerInput->SaveConfig();
}
ImGui::PopID();
Index++;
}
@@ -0,0 +1,655 @@
#include "CogEngineWindow_Console.h"
#include "CogImguiHelper.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "imgui.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderHelp()
{
ImGui::Text("This window can be used as a replacement of the Unreal console.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::Initialize()
{
FCogWindow::Initialize();
Config = GetConfig<UCogEngineConfig_Console>();
bHasMenu = true;
bHasWidget = true;
bIsWidgetVisible = true;
SelectedCommandIndex = -1;
RefreshCommandList();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::PreBegin(ImGuiWindowFlags& WindowFlags)
{
WindowFlags |= ImGuiWindowFlags_NoScrollbar;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::PostBegin()
{
ImGui::PopStyleVar();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderContent()
{
Super::RenderContent();
const APlayerController* PlayerController = GetLocalPlayerController();
if (PlayerController == nullptr)
{
return;
}
if (ImGui::BeginMenuBar())
{
RenderMenu();
ImGui::EndMenuBar();
}
ImGui::Spacing();
if (Config->DockInputInMenuBar == false)
{
ImGui::SetNextItemWidth(-1);
RenderInput();
}
RenderCommandList();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderTick(float DeltaTime)
{
if (GetOwner()->GetContext().GetEnableInput() == false)
{
WidgetMode_OpenCommandList = false;
}
if (WidgetMode_OpenCommandList)
{
bIsWidgetMode = true;
const ImGuiContext& g = *GImGui;
ImGui::SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.90f);
ImGui::SetNextWindowSize(ImVec2(Config->WidgetWidth, ImGui::GetFontSize() * 30), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowPos(WidgetMode_CommandListPosition, ImGuiCond_Always);
ImGuiWindowFlags Flags =
ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoFocusOnAppearing; // We want the console input text to keep the focus.
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
const bool IsCommandListWindowVisible = ImGui::Begin("ConsoleCommandList", nullptr, Flags);
ImGui::PopStyleVar();
if (IsCommandListWindowVisible)
{
ImGui::Spacing();
RenderCommandList();
if (ImGui::BeginPopupContextWindow("ConsoleCommandListPopup"))
{
RenderMenu();
ImGui::EndPopup();
}
const bool IsWindowFocused = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
if (IsWindowFocused)
{
if (ImGui::IsKeyPressed(ImGuiKey_DownArrow))
{
SelectNextCommand();
ActivateInputText();
}
else if (ImGui::IsKeyPressed(ImGuiKey_UpArrow))
{
SelectPreviousCommand();
ActivateInputText();
}
else if (ImGui::IsKeyPressed(ImGuiKey_Tab))
{
SelectNextCommand();
ActivateInputText();
}
else if (ImGui::IsKeyPressed(ImGuiKey_Escape))
{
WidgetMode_OpenCommandList = false;
}
}
if (IsWindowFocused == false && WidgetMode_IsTextInputActive == false)
{
WidgetMode_OpenCommandList = false;
}
}
ImGui::End();
bIsWidgetMode = false;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderMainMenuWidget()
{
bIsWidgetMode = true;
const ImGuiWindow* Window = ImGui::GetCurrentWindow();
WidgetMode_CommandListPosition = Window->DC.CursorPos;
WidgetMode_CommandListPosition.y += Window->MenuBarHeight;
ImGui::SetNextItemWidth(Config->WidgetWidth);
RenderInput();
WidgetMode_IsTextInputActive = ImGui::IsItemActive();
if (Config->FocusWidgetWhenAppearing && ImGui::IsWindowAppearing())
{
SelectedCommandIndex = -1;
RefreshCommandList();
ActivateInputText();
}
if (ImGui::BeginPopupContextItem())
{
RenderMenu();
ImGui::EndPopup();
}
bIsWidgetMode = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderMenu()
{
if (ImGui::BeginMenu("Options"))
{
FCogWidgets::ThinSeparatorText("General");
ImGui::Checkbox("Show Help", &Config->ShowHelp);
if (ImGui::Checkbox("Sort Commands", &Config->SortCommands))
{
RefreshCommandList();
}
// if (ImGui::Checkbox("Use Clipper", &Config->UseClipper))
// {
// RefreshCommandList();
// }
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Completion Minimum Characters", &Config->CompletionMinimumCharacters, 0, 3))
{
RefreshCommandList();
}
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Num History Commands", &Config->NumHistoryCommands, 0, 100))
{
RefreshCommandList();
}
ImGui::ColorEdit4("History Color", &Config->HistoryColor.X, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
FCogWidgets::ThinSeparatorText("Window");
if (ImGui::Checkbox("Dock Input in Menu Bar", &Config->DockInputInMenuBar))
{
RefreshCommandList();
}
FCogWidgets::ThinSeparatorText("Widget");
if (ImGui::Checkbox("Focus Console Widget When Appearing", &Config->FocusWidgetWhenAppearing))
{
RefreshCommandList();
}
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Widget Width", &Config->WidgetWidth, 0, 1000);
ImGui::EndMenu();
}
if (bIsWidgetMode == false && Config->DockInputInMenuBar)
{
ImGui::SetNextItemWidth(-1);
RenderInput();
}
//ImGui::Text("%d", SelectedCommandIndex);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderInput()
{
constexpr ImGuiInputTextFlags InputFlags =
ImGuiInputTextFlags_EnterReturnsTrue
| ImGuiInputTextFlags_EscapeClearsAll
| ImGuiInputTextFlags_CallbackCompletion
| ImGuiInputTextFlags_CallbackHistory
| ImGuiInputTextFlags_CallbackEdit
| ImGuiInputTextFlags_CallbackAlways;
const bool IsEnterPressed = FCogWidgets::InputTextWithHint("##Command", "Command", CurrentUserInput, InputFlags, &OnTextInputCallbackStub, this);
InputTextId = ImGui::GetItemID();
if (IsEnterPressed)
{
ExecuteCommand(CurrentUserInput);
ActivateInputText();
}
ImGui::SetItemDefaultFocus();
//-------------------------------------------------------------------------------------------------
// In Widget mode, do not want to show the command list as soon as the input text has focus,
// but wait for the user to click on the input text (or interact with it). This is because
// we want the text input to always have focus so the user can directly type text if he wants to,
// but if he doesn't the command list should not clutter the screen.
//-------------------------------------------------------------------------------------------------
if (bIsWidgetMode && ImGui::IsItemActive() && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
WidgetMode_OpenCommandList = true;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::SelectNextCommand()
{
SelectedCommandIndex += 1;
bScroll = true;
if (SelectedCommandIndex >= CommandList.Num())
{
SelectedCommandIndex = 0;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::SelectPreviousCommand()
{
SelectedCommandIndex -= 1;
bScroll = true;
if (SelectedCommandIndex < 0)
{
SelectedCommandIndex = CommandList.Num() - 1;
}
}
//--------------------------------------------------------------------------------------------------------------------------
int FCogEngineWindow_Console::OnTextInputCallback(ImGuiInputTextCallbackData* InData)
{
bool DoCompletion = false;
if (InData->EventFlag == ImGuiInputTextFlags_CallbackHistory)
{
if (InData->EventKey == ImGuiKey_UpArrow)
{
SelectPreviousCommand();
}
else if (InData->EventKey == ImGuiKey_DownArrow)
{
SelectNextCommand();
}
DoCompletion = true;
}
else if (InData->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
{
SelectNextCommand();
DoCompletion = true;
}
else if (InData->EventFlag == ImGuiInputTextFlags_CallbackEdit)
{
CurrentUserInput = FString(InData->Buf);
RefreshCommandList();
if (bIsWidgetMode)
{
WidgetMode_OpenCommandList = true;
}
}
else if (InData->EventFlag == ImGuiInputTextFlags_CallbackAlways)
{
if (bSetBufferToSelectedCommand)
{
DoCompletion = true;
bSetBufferToSelectedCommand = false;
}
if (ImGui::IsKeyPressed(ImGuiKey_Tab) && ImGui::IsKeyDown(ImGuiKey_ReservedForModShift))
{
SelectPreviousCommand();
DoCompletion = true;
}
}
if (DoCompletion && CommandList.IsValidIndex(SelectedCommandIndex))
{
const FString SelectedCommand = CommandList[SelectedCommandIndex];
const FString CleanupSelectedCommand = SelectedCommand.TrimEnd();
const auto& CommandStr = StringCast<ANSICHAR>(*CleanupSelectedCommand);
InData->DeleteChars(0, InData->BufTextLen);
InData->InsertChars(0, CommandStr.Get());
InData->InsertChars(InData->CursorPos, " ");
if (bIsWidgetMode)
{
WidgetMode_OpenCommandList = true;
}
}
return 0;
}
//--------------------------------------------------------------------------------------------------------------------------
int FCogEngineWindow_Console::OnTextInputCallbackStub(ImGuiInputTextCallbackData* InData)
{
FCogEngineWindow_Console& ConsoleWindow = *static_cast<FCogEngineWindow_Console*>(InData->UserData);
return ConsoleWindow.OnTextInputCallback(InData);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderCommandList()
{
const float HelpHeight = Config->ShowHelp ? ImGui::GetFontSize() * 5 : 0.0f;
const float Indent = ImGui::GetFontSize() * 0.5f;
const ImVec2 Size = IsWindowRenderedInMainMenu() ? ImVec2(0, ImGui::GetFontSize() * 20) : ImVec2(0.0f, ImGui::GetContentRegionAvail().y - HelpHeight);
if (ImGui::BeginChild("Commands", Size, ImGuiChildFlags_None))
{
ImGui::Indent(Indent);
//--------------------------------------------------------------------
// Gather the child window region min max so we can check if the
// selected command is clipped to know if we should scroll.
//--------------------------------------------------------------------
const float RegionMinY = ImGui::GetItemRectMin().y;
const float RegionMaxY = RegionMinY + ImGui::GetContentRegionAvail().y;
//--------------------------------------------------------------------
// Reset the scroll when the command list reappear, otherwise we
// keep the previous scroll which can be confusing.
//--------------------------------------------------------------------
if (ImGui::IsWindowAppearing())
{
ImGui::SetScrollHereY(0.0f);
SelectedCommandIndex = -1;
}
int32 Index = 0;
//--------------------------------------------------------------------
// TODO: The Clipper is currently not working correctly
//--------------------------------------------------------------------
ImGuiListClipper Clipper;
Clipper.Begin(CommandList.Num());
while (Clipper.Step())
{
const int32 Start = Config->UseClipper ? Clipper.DisplayStart : 0;
const int32 End = Config->UseClipper ? Clipper.DisplayEnd : CommandList.Num();
for (Index = Start; Index < End; Index++)
{
if (CommandList.IsValidIndex(Index))
{
ImGui::PushID(Index);
const FString& CommandName = CommandList[Index];
RenderCommand(CommandName, Index, RegionMinY, RegionMaxY);
ImGui::PopID();
}
}
if (Config->UseClipper == false)
{ break; }
}
Clipper.End();
//--------------------------------------------------------------------
// If any is available, draw an additional command below the clipper
// to be able to scroll when pressing bottom
//--------------------------------------------------------------------
if (CommandList.IsValidIndex(Index + 1))
{
const FString& Command = CommandList[Index + 1];
RenderCommand(Command, Index, RegionMinY, RegionMaxY);
}
ImGui::Unindent(Indent);
}
ImGui::EndChild();
//--------------------------------------------------------------------
// Render Help
//--------------------------------------------------------------------
if (Config->ShowHelp)
{
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.2f, 0.2f, 0.2f, 0.5f));
if (ImGui::BeginChild("Help", ImVec2(0.0f, ImGui::GetContentRegionAvail().y)))
{
ImGui::Spacing();
ImGui::BeginDisabled();
ImGui::Indent(Indent);
if (CommandList.IsValidIndex(SelectedCommandIndex))
{
const FString SelectedCommand = CommandList[SelectedCommandIndex];
const FString Help = GetConsoleCommandHelp(SelectedCommand);
const auto& HelpStr = StringCast<ANSICHAR>(*Help);
ImGui::TextWrapped(HelpStr.Get());
}
ImGui::Unindent(Indent);
ImGui::EndDisabled();
}
ImGui::EndChild();
ImGui::PopStyleColor();
}
}
//--------------------------------------------------------------------------------------------------------------------------
IConsoleObject* FCogEngineWindow_Console::GetCommandObjectFromCommandLine(const FString& InCommandLine)
{
if (InCommandLine.IsEmpty())
{ return nullptr; }
TArray<FString> CommandSplitWithSpaces;
InCommandLine.ParseIntoArrayWS(CommandSplitWithSpaces);
if (CommandSplitWithSpaces.Num() == 0)
{ return nullptr; }
return IConsoleManager::Get().FindConsoleObject(*CommandSplitWithSpaces[0]);
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogEngineWindow_Console::GetConsoleCommandHelp(const FString& InCommandLine)
{
if (IConsoleObject* ConsoleObject = GetCommandObjectFromCommandLine(InCommandLine))
{
return ConsoleObject->GetHelp();
}
return FString("Unknown command.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RenderCommand(const FString& CommandName, const int32 Index, float RegionMinY, float RegionMaxY)
{
const auto& CommandNameStr = StringCast<ANSICHAR>(*CommandName);
bool IsSelected = Index == SelectedCommandIndex;
// ImGui::Text("%d - ", Index);
// ImGui::SameLine();
if (Index < NumHistoryCommands)
{
ImGui::PushStyleColor(ImGuiCol_Text, FCogImguiHelper::ToImVec4(Config->HistoryColor));
}
ImGuiSelectableFlags Flags =
ImGuiSelectableFlags_AllowDoubleClick // Double click executes the selected command
| ImGuiSelectableFlags_SelectOnClick; // Need to focus the console text input right away, otherwise the Selectable take back the focus on mouse release
const bool Pressed = ImGui::Selectable(CommandNameStr.Get(), &IsSelected, Flags);
const int32 IsClippedTop = ImGui::GetItemRectMin().y < RegionMinY;
const int32 IsClippedBottom = ImGui::GetItemRectMax().y > RegionMaxY;
if (Pressed)
{
SelectedCommandIndex = Index;
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
ExecuteCommand(CommandName);
}
else
{
bSetBufferToSelectedCommand = true;
}
ActivateInputText();
}
if (ImGui::BeginItemTooltip())
{
const FString Help = GetConsoleCommandHelp(CommandName);
const auto& HelpStr = StringCast<ANSICHAR>(*Help);
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(HelpStr.Get());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
if (Index < NumHistoryCommands)
{
ImGui::PopStyleColor();
}
if (NumHistoryCommands > 0 && Index == NumHistoryCommands - 1)
{
ImGui::Separator();
}
if (IsSelected && bScroll)
{
if (IsClippedBottom)
{
ImGui::SetScrollHereY(1.0f);
}
if (IsClippedTop)
{
ImGui::SetScrollHereY(0.0f);
}
bScroll = false;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::RefreshCommandList()
{
FString CurrentUserInputWithoutArgs = CurrentUserInput;
//------------------------------------------------------------------------------------------------------
// Split the user input with spaces tp get the first part of the command so the completion is made on
// "Cog.Cheat" instead of "Cog.Cheat God", as the later would return no results
//------------------------------------------------------------------------------------------------------
TArray<FString> UserInputSplitWithSpaces;
CurrentUserInput.ParseIntoArrayWS(UserInputSplitWithSpaces);
if (UserInputSplitWithSpaces.Num() > 0)
{
CurrentUserInputWithoutArgs = UserInputSplitWithSpaces[0];
}
CommandList.Empty();
TArray<FString> AllHistory;
IConsoleManager::Get().GetConsoleHistory(TEXT(""), AllHistory);
NumHistoryCommands = 0;
for (int32 i = AllHistory.Num() - 1; i >= 0; i--)
{
FString Command = AllHistory[i];
if (Command.IsEmpty())
{ continue; }
if (CurrentUserInput.IsEmpty() == false && Command.Contains(CurrentUserInput) == false)
{ continue; }
if (CommandList.Num() >= Config->NumHistoryCommands)
{ break; }
CommandList.Add(Command);
NumHistoryCommands++;
}
TArray<FString> Commands;
if (CurrentUserInputWithoutArgs.Len() >= Config->CompletionMinimumCharacters)
{
auto OnConsoleObject = [&](const TCHAR *InName, const IConsoleObject* InConsoleObject)
{
if (InConsoleObject->TestFlags(ECVF_Unregistered) || InConsoleObject->TestFlags(ECVF_ReadOnly))
{ return; }
Commands.Add(InName);
};
IConsoleManager::Get().ForEachConsoleObjectThatContains(FConsoleObjectVisitor::CreateLambda(OnConsoleObject), *CurrentUserInputWithoutArgs);
}
if (Config->SortCommands)
{
Commands.Sort();
}
CommandList.Append(Commands);
//-------------------------------------------------------------------------------------
// Reset to -1 so the next down arrow will select the first entry in history/command
//-------------------------------------------------------------------------------------
SelectedCommandIndex = -1;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::ActivateInputText() const
{
return ImGui::ActivateItemByID(InputTextId);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Console::ExecuteCommand(const FString& InCommand)
{
const FString CleanupCommand = InCommand.TrimEnd();
if (CleanupCommand.IsEmpty() == false)
{
IConsoleManager::Get().AddConsoleHistoryEntry(TEXT(""), *CleanupCommand);
GEngine->DeferredCommands.Add(CleanupCommand);
}
if (bIsWidgetMode)
{
WidgetMode_OpenCommandList = false;
}
CurrentUserInput = FString();
RefreshCommandList();
}
@@ -2,7 +2,7 @@
#include "CogDebug.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Engine/CollisionProfile.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -27,25 +27,23 @@ void FCogEngineWindow_DebugSettings::Initialize()
FCogDebug::SetIsFilteringBySelection(GetWorld(), Config->Data.bIsFilteringBySelection);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_DebugSettings::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_DebugSettings::PreSaveConfig()
{
Super::PreSaveConfig();
if (Config == nullptr)
{ return; }
Config->Data = FCogDebug::Settings;
}
//--------------------------------------------------------------------------------------------------------------------------
void RenderCollisionChannelColor(const UCollisionProfile& CollisionProfile, FColor& Color, ECollisionChannel Channel, ImGuiColorEditFlags ColorEditFlags)
{
if (CollisionProfile.ConvertToObjectType(Channel) == TraceTypeQuery_MAX && CollisionProfile.ConvertToTraceType(Channel) == TraceTypeQuery_MAX)
{ return; }
const FString ChannelName = CollisionProfile.ReturnChannelNameFromContainerIndex(Channel).ToString();
FCogImguiHelper::ColorEdit4(StringCast<ANSICHAR>(*ChannelName).Get(), Color, ColorEditFlags);
}
@@ -91,53 +89,53 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Text Shadow", &Settings.TextShadow);
ImGui::SetItemTooltip("Show a shadow below debug text.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Fade 2D", &Settings.Fade2D);
ImGui::SetItemTooltip("Does the 2D debug is fading out.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Duration", &Settings.Duration, 0.01f, 0.0f, 100.0f, "%.1f");
ImGui::SetItemTooltip("The duration of debug elements.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Thickness", &Settings.Thickness, 0.05f, 0.0f, 5.0f, "%.1f");
ImGui::SetItemTooltip("The thickness of debug lines.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Server Thickness", &Settings.ServerThickness, 0.05f, 0.0f, 5.0f, "%.1f");
ImGui::SetItemTooltip("The thickness the server debug lines.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Server Color Mult", &Settings.ServerColorMultiplier, 0.01f, 0.0f, 1.0f, "%.1f");
ImGui::SetItemTooltip("The color multiplier applied to the server debug lines.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Depth Priority", &Settings.DepthPriority, 0.1f, 0, 100);
ImGui::SetItemTooltip("The depth priority of debug elements.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Segments", &Settings.Segments, 0.1f, 4, 20.0f);
ImGui::SetItemTooltip("The number of segments used for circular shapes.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Axes Scale", &Settings.AxesScale, 0.1f, 0, 10.0f, "%.1f");
ImGui::SetItemTooltip("The scaling debug axis.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Arrow Size", &Settings.ArrowSize, 1.0f, 0.0f, 200.0f, "%.0f");
ImGui::SetItemTooltip("The size of debug arrows.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Text Size", &Settings.TextSize, 0.1f, 0.1f, 5.0f, "%.1f");
ImGui::SetItemTooltip("The size of the debug texts.");
}
if (ImGui::CollapsingHeader("Recolor", ImGuiTreeNodeFlags_DefaultOpen))
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ECogDebugRecolorMode Mode = Settings.RecolorMode;
if (FCogWindowWidgets::ComboboxEnum("Recolor mode", Mode))
if (FCogWidgets::ComboboxEnum("Recolor mode", Mode))
{
Settings.RecolorMode = Mode;
}
@@ -145,7 +143,7 @@ void FCogEngineWindow_DebugSettings::RenderContent()
if (Settings.RecolorMode != ECogDebugRecolorMode::None)
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Recolor Intensity", &Settings.RecolorIntensity, 0.01f, 0.0f, 1.0f, "%.2f");
ImGui::SetItemTooltip("How much the debug elements color should be changed.");
}
@@ -156,13 +154,13 @@ void FCogEngineWindow_DebugSettings::RenderContent()
}
else if (Settings.RecolorMode == ECogDebugRecolorMode::HueOverTime)
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Recolor Speed", &Settings.RecolorTimeSpeed, 0.1f, 0.0f, 10.0f, "%.1f");
ImGui::SetItemTooltip("The speed of the recolor.");
}
else if (Settings.RecolorMode == ECogDebugRecolorMode::HueOverFrames)
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Recolor Cycle", &Settings.RecolorFrameCycle, 1, 2, 100);
ImGui::SetItemTooltip("How many frames are used to perform a full hue cycle.");
}
@@ -174,92 +172,95 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Use Local Space", &Settings.GizmoUseLocalSpace);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Gizmo Scale", &Settings.GizmoScale, 0.1f, 0.1f, 10.0f, "%.1f");
ImGui::Checkbox("Support Context Menu", &Settings.GizmoSupportContextMenu);
ImGui::SetItemTooltip("Does right clicking on the gizmo displays a context menu ?");
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale", &Settings.GizmoScale, 0.1f, 0.1f, 10.0f, "%.1f");
ImGui::SetItemTooltip("The scale of the gizmo.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Z Low", &Settings.GizmoZLow, 0.5f, 0, 1000);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Z High", &Settings.GizmoZHigh, 0.5f, 0, 1000);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Thickness Z Low", &Settings.GizmoThicknessZLow, 0.1f, 0.0f, 10.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Thickness Z High", &Settings.GizmoThicknessZHigh, 0.1f, 0.0f, 10.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Mouse Max Distance", &Settings.GizmoCursorSelectionThreshold, 0.1f, 0.0f, 50.0f, "%.1f");
ImGui::SeparatorText("Translation");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Translation Snap Enable", &Settings.GizmoTranslationSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Translation Snap", &Settings.GizmoTranslationSnapValue, 0.1f, 0.0f, 1000.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Translation Axis Length", &Settings.GizmoTranslationAxisLength, 0.1f, 0.1f, 500.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Translation Plane Offset", &Settings.GizmoTranslationPlaneOffset, 0.1f, 0.0f, 500.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Translation Plane Extent", &Settings.GizmoTranslationPlaneExtent, 0.1f, 0.0f, 100.0f, "%.1f");
ImGui::SeparatorText("Rotation");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Rotation Snap Enable", &Settings.GizmoRotationSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Rotation Snap", &Settings.GizmoRotationSnapValue, 0.1f, 0.0f, 360.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Rotation Speed", &Settings.GizmoRotationSpeed, 0.01f, 0.01f, 100.0f, "%.2f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Rotation Radius", &Settings.GizmoRotationRadius, 0.1f, 0.1f, 500.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragInt("Rotation Segments", &Settings.GizmoRotationSegments, 0.5f, 2, 12);
ImGui::SeparatorText("Scale");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Scale Snap Enable", &Settings.GizmoScaleSnapEnable);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale Snap", &Settings.GizmoScaleSnapValue, 0.1f, 0.0f, 10.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale Box Offset", &Settings.GizmoScaleBoxOffset, 0.0f, 0.0f, 500.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale Box Extent", &Settings.GizmoScaleBoxExtent, 0.1f, 0.0f, 100.0f, "%.1f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale Speed", &Settings.GizmoScaleSpeed, 0.01f, 0.01f, 100.0f, "%.2f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Scale Min", &Settings.GizmoScaleMin, 0.001f, 0.001f, 1.0f, "%.3f");
ImGui::SeparatorText("Ground Raycast");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Ground Raycast Length", &Settings.GizmoGroundRaycastLength, 10.0f, 0.0f, 1000000.0f, "%.0f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ECollisionChannel Channel = Settings.GizmoGroundRaycastChannel.GetValue();
if (FCogWindowWidgets::ComboCollisionChannel("Channel", Channel))
if (FCogWidgets::ComboTraceChannel("Channel", Channel))
{
Settings.GizmoGroundRaycastChannel = Channel;
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Ground Raycast Circle Radius", &Settings.GizmoGroundRaycastCircleRadius, 0.1f, 0.1f, 1000.0f, "%.1f");
FCogImguiHelper::ColorEdit4("Ground Raycast Color", Settings.GizmoGroundRaycastColor, ColorEditFlags);
@@ -297,12 +298,7 @@ void FCogEngineWindow_DebugSettings::RenderContent()
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorPhysicsBody, ECC_PhysicsBody, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorVehicle, ECC_Vehicle, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorDestructible, ECC_Destructible, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel1, ECC_EngineTraceChannel1, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel2, ECC_EngineTraceChannel2, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel3, ECC_EngineTraceChannel3, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel4, ECC_EngineTraceChannel4, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel5, ECC_EngineTraceChannel5, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorEngineTraceChannel6, ECC_EngineTraceChannel6, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorGameTraceChannel1, ECC_GameTraceChannel1, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorGameTraceChannel2, ECC_GameTraceChannel2, ColorEditFlags);
RenderCollisionChannelColor(*CollisionProfile, Settings.ChannelColorGameTraceChannel3, ECC_GameTraceChannel3, ColorEditFlags);
@@ -350,11 +346,11 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::Checkbox("Draw Hit Impact Normals", &Settings.CollisionQueryDrawHitImpactNormals);
ImGui::SetItemTooltip("Draw the hit impact normal of hit results.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Primitive Actors Name Size", &Settings.CollisionQueryHitPrimitiveActorsNameSize, 0.1f, 0.5f, 10.0f, "%0.1f");
ImGui::SetItemTooltip("Size of the actor name of the primitives that have been hit.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Hit Point Size", &Settings.CollisionQueryHitPointSize, 0.5f, 0.0f, 100.0f, "%0.1f");
ImGui::SetItemTooltip("Size of the hit result location and impact point.");
@@ -1,6 +1,6 @@
#include "CogEngineWindow_Inspector.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Containers/SortedMap.h"
#include "Engine/Engine.h"
#include "imgui_internal.h"
@@ -57,14 +57,14 @@ void FCogEngineWindow_Inspector::SetInspectedObject(UObject* Value)
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Inspector::AddFavorite(UObject* Object)
{
Favorite& Favorite = Favorites.AddDefaulted_GetRef();
FFavorite& Favorite = Favorites.AddDefaulted_GetRef();
Favorite.Object = Object;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Inspector::AddFavorite(UObject* Object, FCogEngineInspectorApplyFunction ApplyFunction)
{
Favorite& Favorite = Favorites.AddDefaulted_GetRef();
FFavorite& Favorite = Favorites.AddDefaulted_GetRef();
Favorite.Object = Object;
Favorite.ApplyFunction = ApplyFunction;
}
@@ -110,7 +110,7 @@ void FCogEngineWindow_Inspector::RenderContent()
//--------------------------------------------------------------------------------------------------------------------------
FCogEngineInspectorApplyFunction FCogEngineWindow_Inspector::FindObjectApplyFunction(const UObject* Object) const
{
for (const Favorite& Favorite : Favorites)
for (const FFavorite& Favorite : Favorites)
{
if (Favorite.Object == Object)
{
@@ -166,23 +166,18 @@ void FCogEngineWindow_Inspector::RenderMenu()
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
ImGui::SameLine();
if (ImGui::Button(InspectedObjectName.Get(), ImVec2(FCogWindowWidgets::GetFontWidth() * 20, 0)))
if (ImGui::Button(InspectedObjectName.Get(), ImVec2(FCogWidgets::GetFontWidth() * 20, 0)))
{
ImGui::OpenPopup("SelectionPopup");
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Current Inspected Object: %s", InspectedObjectName.Get());
ImGui::SetTooltip("%s", InspectedObjectName.Get());
}
ImGui::PopStyleVar(1);
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("%s", InspectedObjectName.Get());
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(1);
@@ -192,7 +187,7 @@ void FCogEngineWindow_Inspector::RenderMenu()
ImGui::SetNextWindowPos(Pos + ImVec2(0, ImGui::GetFrameHeight()));
if (ImGui::BeginPopup("SelectionPopup"))
{
ImGui::BeginChild("Popup", ImVec2(FCogWindowWidgets::GetFontWidth() * 30, FCogWindowWidgets::GetFontWidth() * 40), false);
ImGui::BeginChild("Popup", ImVec2(FCogWidgets::GetFontWidth() * 30, FCogWidgets::GetFontWidth() * 40), false);
//-----------------------------------
// FAVORITES
@@ -206,7 +201,7 @@ void FCogEngineWindow_Inspector::RenderMenu()
}
ImGui::PushID("Favorites");
for (Favorite& Favorite : Favorites)
for (FFavorite& Favorite : Favorites)
{
const TWeakObjectPtr<UObject>& Object = Favorite.Object;
if (ImGui::MenuItem(TCHAR_TO_ANSI(*GetNameSafe(Object.Get()))))
@@ -256,7 +251,7 @@ void FCogEngineWindow_Inspector::RenderMenu()
//-----------------------------------
// Search
//-----------------------------------
FCogWindowWidgets::SearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9);
FCogWidgets::SearchBar("##Filter", Filter, -FCogWidgets::GetFontWidth() * 9);
//-----------------------------------
// Options
@@ -273,7 +268,7 @@ void FCogEngineWindow_Inspector::RenderMenu()
ImGui::Checkbox("Sort by Name", &Config->bSortByName);
ImGui::Checkbox("Show Background", &Config->bShowRowBackground);
ImGui::Checkbox("Show Sorders", &Config->bShowBorders);
ImGui::Checkbox("Show Borders", &Config->bShowBorders);
#if WITH_EDITORONLY_DATA
ImGui::Checkbox("Show Display Name", &Config->bShowDisplayName);
ImGui::Checkbox("Show Categories", &Config->bShowCategories);
@@ -349,7 +344,7 @@ bool FCogEngineWindow_Inspector::RenderInspector()
ImGui::SetNextItemOpen(false);
}
if (ImGui::CollapsingHeader(TCHAR_TO_ANSI(*Entry.Key), nullptr, ImGuiTreeNodeFlags_DefaultOpen))
if (ImGui::CollapsingHeader(TCHAR_TO_UTF8(*Entry.Key), nullptr, ImGuiTreeNodeFlags_DefaultOpen))
{
if (RenderBegin())
{
@@ -381,7 +376,7 @@ bool FCogEngineWindow_Inspector::RenderInspector()
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::RenderBegin()
{
FCogWindowWidgets::PushStyleCompact();
FCogWidgets::PushStyleCompact();
ImGuiTableFlags TableFlags = ImGuiTableFlags_Resizable;
if ((Config->bShowBorders) != 0)
@@ -412,7 +407,7 @@ bool FCogEngineWindow_Inspector::RenderBegin()
void FCogEngineWindow_Inspector::RenderEnd()
{
ImGui::EndTable();
FCogWindowWidgets::PopStyleCompact();
FCogWidgets::PopStyleCompact();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -456,7 +451,7 @@ bool FCogEngineWindow_Inspector::RenderPropertyList(TArray<const FProperty*>& Pr
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8* PointerToValue, int IndexInArray)
bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8* PointerToValue, int IndexInArray, const char* NameSuffix)
{
bool HasChanged = false;
@@ -473,6 +468,11 @@ bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8
if (IndexInArray != -1)
{
PropertyName = FString::Printf(TEXT("[%d]"), IndexInArray);
if (NameSuffix != nullptr)
{
PropertyName.Append(" ");
PropertyName.Append(NameSuffix);
}
}
else
{
@@ -510,7 +510,7 @@ bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8
ImGui::TableNextColumn();
ImGui::Text("DisplayName:");
ImGui::TableNextColumn();
ImGui::Text(TCHAR_TO_ANSI(*Property->GetDisplayNameText().ToString()));
ImGui::Text(TCHAR_TO_UTF8(*Property->GetDisplayNameText().ToString()));
#endif // WITH_EDITORONLY_DATA
ImGui::TableNextRow();
@@ -532,7 +532,7 @@ bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8
ImGui::TableNextColumn();
if (Property->HasMetaData("Tooltip"))
{
ImGui::Text(TCHAR_TO_ANSI(*Property->GetToolTipText(false).ToString()));
ImGui::Text(TCHAR_TO_UTF8(*Property->GetToolTipText(false).ToString()));
}
#endif // WITH_EDITORONLY_DATA
@@ -550,7 +550,7 @@ bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::Text(TCHAR_TO_ANSI(*Property->GetToolTipText(false).ToString()));
ImGui::Text(TCHAR_TO_UTF8(*Property->GetToolTipText(false).ToString()));
ImGui::Text("Details [CTRL]");
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
@@ -635,6 +635,14 @@ bool FCogEngineWindow_Inspector::RenderProperty(const FProperty* Property, uint8
{
HasChanged = RenderArray(ArrayProperty, PointerToValue, ShowChildren);
}
else if (const FSetProperty* SetProperty = CastField<FSetProperty>(Property))
{
HasChanged = RenderSet(SetProperty, PointerToValue, ShowChildren);
}
else if (const FMapProperty* MapProperty = CastField<FMapProperty>(Property))
{
HasChanged = RenderMap(MapProperty, PointerToValue, ShowChildren);
}
else if (const FDelegateProperty* DelegateProperty = CastField<FDelegateProperty>(Property))
{
}
@@ -680,7 +688,7 @@ bool FCogEngineWindow_Inspector::RenderByte(const FByteProperty* ByteProperty, u
if (ImGui::InputInt("##Byte", &Value))
{
HasChanged = true;
ByteProperty->SetPropertyValue(PointerToValue, (uint8)Value);
ByteProperty->SetPropertyValue(PointerToValue, static_cast<uint8>(Value));
}
return HasChanged;
@@ -695,7 +703,7 @@ bool FCogEngineWindow_Inspector::RenderInt8(const FInt8Property* Int8Property, u
if (ImGui::InputInt("##Int8", &Value))
{
HasChanged = true;
Int8Property->SetPropertyValue(PointerToValue, (int8)Value);
Int8Property->SetPropertyValue(PointerToValue, static_cast<int8>(Value));
}
return HasChanged;
@@ -721,11 +729,11 @@ bool FCogEngineWindow_Inspector::RenderInt64(const FInt64Property* Int64Property
{
bool HasChanged = false;
int Value = (int)Int64Property->GetPropertyValue(PointerToValue);
int Value = static_cast<int>(Int64Property->GetPropertyValue(PointerToValue));
if (ImGui::InputInt("##UInt64", &Value))
{
HasChanged = true;
Int64Property->SetPropertyValue(PointerToValue, (uint64)Value);
Int64Property->SetPropertyValue(PointerToValue, static_cast<uint64>(Value));
}
return HasChanged;
@@ -736,11 +744,11 @@ bool FCogEngineWindow_Inspector::RenderUInt32(const FUInt32Property* UInt32Prope
{
bool HasChanged = false;
int Value = (int)UInt32Property->GetPropertyValue(PointerToValue);
int Value = static_cast<int>(UInt32Property->GetPropertyValue(PointerToValue));
if (ImGui::InputInt("##UInt32", &Value))
{
HasChanged = true;
UInt32Property->SetPropertyValue(PointerToValue, (uint32)Value);
UInt32Property->SetPropertyValue(PointerToValue, static_cast<uint32>(Value));
}
return HasChanged;
@@ -779,7 +787,7 @@ bool FCogEngineWindow_Inspector::RenderDouble(const FDoubleProperty* DoublePrope
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::RenderEnum(const FEnumProperty* EnumProperty, uint8* PointerToValue)
{
return FCogWindowWidgets::ComboboxEnum("##Enum", EnumProperty, PointerToValue);
return FCogWidgets::ComboboxEnum("##Enum", EnumProperty, PointerToValue);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -819,7 +827,7 @@ bool FCogEngineWindow_Inspector::RenderText(const FTextProperty* TextProperty, u
FString Text;
TextProperty->ExportTextItem_Direct(Text, PointerToValue, nullptr, nullptr, PPF_None, nullptr);
ImGui::BeginDisabled();
ImGui::Text("%s", TCHAR_TO_ANSI(*Text));
ImGui::Text("%s", TCHAR_TO_UTF8(*Text));
ImGui::EndDisabled();
return false;
@@ -869,7 +877,7 @@ bool FCogEngineWindow_Inspector::RenderObject(UObject* Object, bool ShowChildren
bool FCogEngineWindow_Inspector::RenderStruct(const FStructProperty* StructProperty, uint8* PointerToValue, bool ShowChildren)
{
ImGui::BeginDisabled();
ImGui::Text("%s", TCHAR_TO_ANSI(*StructProperty->Struct->GetClass()->GetName()));
ImGui::Text("%s", TCHAR_TO_ANSI(*StructProperty->Struct->GetStructCPPName()));
ImGui::EndDisabled();
bool HasChanged = false;
@@ -936,7 +944,12 @@ bool FCogEngineWindow_Inspector::RenderArray(const FArrayProperty* ArrayProperty
const int32 Num = Helper.Num();
ImGui::BeginDisabled();
ImGui::Text("%s [%d]", TCHAR_TO_ANSI(*ArrayProperty->Inner->GetClass()->GetName()), Num);
FString ElementPropertyName = ArrayProperty->Inner->GetClass()->GetName();
if (const FStructProperty* StructProperty = CastField<FStructProperty>(ArrayProperty->Inner))
{
ElementPropertyName = StructProperty->Struct->GetStructCPPName();
}
ImGui::Text("%s [%d]", StringCast<ANSICHAR>(*ElementPropertyName).Get(), Num);
ImGui::EndDisabled();
bool HasChanged = false;
@@ -955,6 +968,75 @@ bool FCogEngineWindow_Inspector::RenderArray(const FArrayProperty* ArrayProperty
return HasChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::RenderSet(const FSetProperty* SetProperty, uint8* PointerToValue, bool ShowChildren)
{
FScriptSetHelper Helper(SetProperty, PointerToValue);
const int32 Num = Helper.Num();
ImGui::BeginDisabled();
FString ElementPropertyName = SetProperty->GetElementProperty()->GetClass()->GetName();
if (const FStructProperty* StructProperty = CastField<FStructProperty>(SetProperty->GetElementProperty()))
{
ElementPropertyName = StructProperty->Struct->GetStructCPPName();
}
ImGui::Text("%s {%d}", StringCast<ANSICHAR>(*ElementPropertyName).Get(), Num);
ImGui::EndDisabled();
bool HasChanged = false;
if (ShowChildren)
{
for (int32 i = 0; i < Num; ++i)
{
ImGui::PushID(i);
HasChanged |= RenderProperty(SetProperty->GetElementProperty(), Helper.GetElementPtr(i), i);
ImGui::PopID();
}
ImGui::TreePop();
}
return HasChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::RenderMap(const FMapProperty* MapProperty, uint8* PointerToValue, bool ShowChildren)
{
FScriptMapHelper Helper(MapProperty, PointerToValue);
const int32 Num = Helper.Num();
ImGui::BeginDisabled();
FString KeyPropertyName = MapProperty->GetKeyProperty()->GetClass()->GetName();
if (const FStructProperty* StructProperty = CastField<FStructProperty>(MapProperty->GetKeyProperty()))
{
KeyPropertyName = StructProperty->Struct->GetStructCPPName();
}
FString ValuePropertyName = MapProperty->GetValueProperty()->GetClass()->GetName();
if (const FStructProperty* StructProperty = CastField<FStructProperty>(MapProperty->GetValueProperty()))
{
ValuePropertyName = StructProperty->Struct->GetStructCPPName();
}
ImGui::Text("%s -> %s [%d]", StringCast<ANSICHAR>(*KeyPropertyName).Get(), StringCast<ANSICHAR>(*ValuePropertyName).Get(), Num);
ImGui::EndDisabled();
bool HasChanged = false;
if (ShowChildren)
{
for (int32 i = 0; i < Num; ++i)
{
ImGui::PushID(i);
// @todo: refactor this so it's better?
HasChanged |= RenderProperty(MapProperty->GetKeyProperty(), Helper.GetKeyPtr(i), i, "Key");
HasChanged |= RenderProperty(MapProperty->GetValueProperty(), Helper.GetValuePtr(i), i, "Value");
ImGui::PopID();
}
ImGui::TreePop();
}
return HasChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Inspector::HasPropertyAnyChildren(const FProperty* Property, uint8* PointerToValue)
{
@@ -963,25 +1045,34 @@ bool FCogEngineWindow_Inspector::HasPropertyAnyChildren(const FProperty* Propert
const TFieldIterator<FProperty> It(StructProperty->Struct);
return It ? true : false;
}
else if (const FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
if (const FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
{
const FScriptArrayHelper Helper(ArrayProperty, PointerToValue);
const int32 Num = Helper.Num();
if (Num == 0)
{ return false; }
return true;
}
if (const FSetProperty* SetProperty = CastField<FSetProperty>(Property))
{
const FScriptSetHelper Helper(SetProperty, PointerToValue);
const int32 Num = Helper.Num();
if (Num == 0)
{
return false;
}
return true;
}
else if (const FClassProperty* ClassProperty = CastField<FClassProperty>(Property))
if (const FMapProperty* MapProperty = CastField<FMapProperty>(Property))
{
return false;
}
else if (const FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property))
{
const UObject* ReferencedObject = ObjectProperty->GetObjectPropertyValue(PointerToValue);
if (ReferencedObject == nullptr)
const FScriptMapHelper Helper(MapProperty, PointerToValue);
const int32 Num = Helper.Num();
if (Num == 0)
{
return false;
}
@@ -989,6 +1080,18 @@ bool FCogEngineWindow_Inspector::HasPropertyAnyChildren(const FProperty* Propert
return true;
}
if (const FClassProperty* ClassProperty = CastField<FClassProperty>(Property))
{ return false; }
if (const FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property))
{
const UObject* ReferencedObject = ObjectProperty->GetObjectPropertyValue(PointerToValue);
if (ReferencedObject == nullptr)
{ return false; }
return true;
}
return false;
}
@@ -0,0 +1,175 @@
#include "CogEngineWindow_Levels.h"
#include "CogImguiHelper.h"
#include "CogWidgets.h"
#include "AssetRegistry/AssetRegistryModule.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RenderHelp()
{
ImGui::Text("This window can be used to load levels.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::Initialize()
{
Super::Initialize();
bHasMenu = true;
Config = GetConfig<UCogEngineWindowConfig_LevelLoader>();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::GetAllLevels(TArray<FAssetData>& OutLevels)
{
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
const IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();
FARFilter AssetFilter;
AssetFilter.ClassPaths.Add(UWorld::StaticClass()->GetClassPathName());
AssetRegistry.GetAssets(AssetFilter, OutLevels);
RefreshSorting();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RefreshSorting()
{
Levels = UnsortedLevels;
if (Config->SortByName)
{
if (Config->ShowPath)
{
Levels.Sort([](const auto& InA, const auto& InB) { return InA.PackagePath.Compare(InB.PackagePath) < 0; });
}
else
{
Levels.Sort([](const auto& InA, const auto& InB) { return InA.AssetName.Compare(InB.AssetName) < 0; });
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RenderMenu()
{
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
if (ImGui::Checkbox("Sort by Name", &Config->SortByName))
{
RefreshSorting();
}
if (ImGui::Checkbox("Show Path", &Config->ShowPath))
{
RefreshSorting();
}
ImGui::EndMenu();
}
FCogWidgets::SearchBar("##Filter", Filter);
ImGui::EndMenuBar();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RenderContent()
{
Super::RenderContent();
if (HasGatheredLevels == false)
{
GetAllLevels(UnsortedLevels);
RefreshSorting();
HasGatheredLevels = true;
}
RenderMenu();
const float FooterHeight = ImGui::GetFrameHeightWithSpacing();
const ImVec2 Size = IsWindowRenderedInMainMenu()
? ImVec2(0.f, ImGui::GetFontSize() * 10 - FooterHeight)
: ImVec2(0.f, ImGui::GetContentRegionAvail().y - FooterHeight);
const bool Visible = ImGui::BeginChild("Levels", Size, 0, ImGuiWindowFlags_HorizontalScrollbar);
if (Visible)
{
for (int32 i = 0; i < Levels.Num(); i++)
{
ImGui::PushID(i);
const FAssetData& Asset = Levels[i];
RenderLevel(i, Asset);
ImGui::PopID();
}
}
ImGui::EndChild();
const bool CanLoad = Levels.IsValidIndex(SelectedIndex);
if (CanLoad == false)
{
ImGui::BeginDisabled();
}
if (ImGui::Button("Load", ImVec2(-1, 0)))
{
if (Levels.IsValidIndex(SelectedIndex))
{
LoadLevel(Levels[SelectedIndex]);
}
}
if (CanLoad == false)
{
ImGui::EndDisabled();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RenderLevel(int32 InIndex, const FAssetData& InAsset)
{
const FString Label = Config->ShowPath ? InAsset.PackageName.ToString() : InAsset.AssetName.ToString();
const auto LabelStr = StringCast<ANSICHAR>(*Label);
if (Filter.PassFilter(LabelStr.Get()) == false)
{ return; }
if (ImGui::Selectable(LabelStr.Get(), SelectedIndex == InIndex, ImGuiSelectableFlags_AllowDoubleClick))
{
SelectedIndex = InIndex;
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
LoadLevel(InAsset);
}
}
ImGui::SetItemTooltip(StringCast<ANSICHAR>(*InAsset.PackageName.ToString()).Get());
RenderLevelContextMenu(InIndex, InAsset);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::LoadLevel(const FAssetData& InAsset)
{
APlayerController* LocalPlayerController = GetLocalPlayerController();
if (LocalPlayerController == nullptr)
{ return; }
LocalPlayerController->ConsoleCommand(FString::Printf(TEXT("Travel %s"), *InAsset.PackageName.ToString()));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Levels::RenderLevelContextMenu(int Index, const FAssetData& Asset)
{
if (ImGui::BeginPopupContextItem())
{
FCogWidgets::BrowseToAssetButton(Asset);
ImGui::EndPopup();
}
}
@@ -2,7 +2,7 @@
#include "CogDebugHelper.h"
#include "CogDebug.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "CogDebugLog.h"
#include "DrawDebugHelpers.h"
#include "Engine/World.h"
@@ -76,12 +76,12 @@ void FCogEngineWindow_LogCategories::RenderContent()
bool bIsFilteringBySelection = FCogDebug::GetIsFilteringBySelection();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 2);
FCogWindowWidgets::PushStyleCompact();
FCogWidgets::PushStyleCompact();
if (ImGui::Checkbox("Filter", &bIsFilteringBySelection))
{
FCogDebug::SetIsFilteringBySelection(GetWorld(), bIsFilteringBySelection);
}
FCogWindowWidgets::PopStyleCompact();
FCogWidgets::PopStyleCompact();
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
{
@@ -111,8 +111,6 @@ void FCogEngineWindow_LogCategories::RenderContent()
const bool IsClient = World->GetNetMode() == NM_Client;
ImGuiStyle& Style = ImGui::GetStyle();
int Index = 0;
for (const auto& Entry : FCogDebugLog::GetLogCategories())
{
@@ -221,13 +219,13 @@ void FCogEngineWindow_LogCategories::RenderContent()
if (IsClient)
{
const ELogVerbosity::Type CurrentVerbosity = FCogDebugLog::GetServerVerbosity(CategoryName);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("##Server", FCogDebugHelper::VerbosityToString(CurrentVerbosity)))
{
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
for (int32 i = ELogVerbosity::Error; i <= static_cast<int32>(ELogVerbosity::VeryVerbose); ++i)
{
const bool IsSelected = i == (int32)CurrentVerbosity;
const ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
const bool IsSelected = i == static_cast<int32>(CurrentVerbosity);
const ELogVerbosity::Type Verbosity = static_cast<ELogVerbosity::Type>(i);
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
{
@@ -251,13 +249,13 @@ void FCogEngineWindow_LogCategories::RenderContent()
{
const ELogVerbosity::Type CurrentVerbosity = Category->GetVerbosity();
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("##Local", FCogDebugHelper::VerbosityToString(CurrentVerbosity)))
{
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
for (int32 i = ELogVerbosity::Error; i <= static_cast<int32>(ELogVerbosity::VeryVerbose); ++i)
{
const bool IsSelected = i == (int32)CurrentVerbosity;
const ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
const bool IsSelected = i == static_cast<int32>(CurrentVerbosity);
const ELogVerbosity::Type Verbosity = static_cast<ELogVerbosity::Type>(i);
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
{
@@ -1,7 +1,7 @@
#include "CogEngineWindow_Metrics.h"
#include "CogDebugMetric.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "imgui.h"
#include "Engine/World.h"
@@ -27,19 +27,14 @@ void FCogEngineWindow_Metrics::RenderHelp()
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Metrics::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Metrics::PreSaveConfig()
{
Super::PreSaveConfig();
if (Config == nullptr)
{ return; }
Config->MaxDurationSetting = FCogDebugMetric::MaxDurationSetting;
Config->RestartDelaySetting = FCogDebugMetric::RestartDelaySetting;
}
@@ -62,13 +57,13 @@ void FCogEngineWindow_Metrics::RenderContent()
{
if (ImGui::BeginMenu("Options"))
{
FCogWindowWidgets::PushStyleCompact();
FCogWidgets::PushStyleCompact();
ImGui::DragFloat("Auto Restart Delay", &FCogDebugMetric::RestartDelaySetting, 0.1f, 0.0f, FLT_MAX, "%0.1f");
FCogWindowWidgets::PopStyleCompact();
FCogWidgets::PopStyleCompact();
FCogWindowWidgets::PushStyleCompact();
FCogWidgets::PushStyleCompact();
ImGui::DragFloat("Max Time", &FCogDebugMetric::MaxDurationSetting, 0.1f, 0.0f, FLT_MAX, "%0.1f");
FCogWindowWidgets::PopStyleCompact();
FCogWidgets::PopStyleCompact();
ImGui::EndMenu();
}
@@ -108,7 +103,7 @@ void FCogEngineWindow_Metrics::RenderContent()
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Metrics::DrawMetric(FCogDebugMetricEntry& Metric)
{
FCogWindowWidgets::PushBackColor(ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
FCogWidgets::PushBackColor(ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
if (ImGui::BeginTable("MetricTable", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_RowBg))
{
@@ -128,25 +123,25 @@ void FCogEngineWindow_Metrics::DrawMetric(FCogDebugMetricEntry& Metric)
}
ImGui::Text("Crits");
ImGui::SameLine(FCogWindowWidgets::GetFontWidth() * 20);
FCogWindowWidgets::ProgressBarCentered(Metric.Count == 0 ? 0.0f : Metric.Crits / (float)Metric.Count, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), Metric.Crits, Metric.Count)));
ImGui::SameLine(FCogWidgets::GetFontWidth() * 20);
FCogWidgets::ProgressBarCentered(Metric.Count == 0 ? 0.0f : Metric.Crits / static_cast<float>(Metric.Count), ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%d / %d"), Metric.Crits, Metric.Count)));
if (FCogDebugMetric::MaxDurationSetting > 0.0f)
{
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::GetFontWidth() * 20);
FCogWindowWidgets::ProgressBarCentered(Metric.Timer / (float)FCogDebugMetric::MaxDurationSetting, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%0.1f / %0.1f"), Metric.Timer, FCogDebugMetric::MaxDurationSetting)));
ImGui::SameLine(FCogWidgets::GetFontWidth() * 20);
FCogWidgets::ProgressBarCentered(Metric.Timer / (float)FCogDebugMetric::MaxDurationSetting, ImVec2(-1, 0), TCHAR_TO_ANSI(*FString::Printf(TEXT("%0.1f / %0.1f"), Metric.Timer, FCogDebugMetric::MaxDurationSetting)));
}
else
{
ImGui::Text("Timer");
ImGui::SameLine(FCogWindowWidgets::GetFontWidth() * 20);
ImGui::SameLine(FCogWidgets::GetFontWidth() * 20);
ImGui::Text("%0.1f", Metric.Timer);
}
ImGui::Spacing();
FCogWindowWidgets::PopBackColor();
FCogWidgets::PopBackColor();
if (ImGui::Button("Restart"))
{
@@ -1,7 +1,8 @@
#include "CogEngineWindow_NetEmulation.h"
#include "CogEngineWindow_Stats.h"
#include "CogWindowWidgets.h"
#include "CogImguiHelper.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "Engine/NetConnection.h"
#include "Engine/NetDriver.h"
@@ -16,6 +17,25 @@ void FCogEngineWindow_NetEmulation::RenderHelp()
ImGui::Text("This window is used to configure the network emulation.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetEmulation::Initialize()
{
Super::Initialize();
Config = GetConfig<UCogEngineWindowConfig_Stats>();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetEmulation::RenderContextMenu()
{
Config->RenderColorConfig();
Config->RenderPingConfig();
Config->RenderPacketLossConfig();
ImGui::Separator();
FCogWindow::RenderContextMenu();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetEmulation::RenderContent()
{
@@ -42,7 +62,7 @@ void FCogEngineWindow_NetEmulation::DrawStats()
const float Ping = PlayerState->GetPingInMilliseconds();
ImGui::Text("Ping ");
ImGui::SameLine();
ImGui::TextColored(FCogEngineWindow_Stats::GetPingColor(Ping), "%0.0fms", Ping);
ImGui::TextColored(Config->GetPingColor(Ping), "%0.0fms", Ping);
}
if (UNetConnection* Connection = PlayerController->GetNetConnection())
@@ -50,12 +70,12 @@ void FCogEngineWindow_NetEmulation::DrawStats()
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
ImGui::Text("Packet Loss Out ");
ImGui::SameLine();
ImGui::TextColored(FCogEngineWindow_Stats::GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
ImGui::TextColored(Config->GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
ImGui::Text("Packet Loss In ");
ImGui::SameLine();
ImGui::TextColored(FCogEngineWindow_Stats::GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
ImGui::TextColored(Config->GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
}
}
@@ -82,7 +102,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
return;
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("Driver", TCHAR_TO_ANSI(*SelectedNetDriver->NetDriver->GetName())))
{
int i = 0;
@@ -113,7 +133,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
FPacketSimulationSettings Settings = SelectedNetDriver->NetDriver->PacketSimulationSettings;
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::DragInt("Lag Min", &Settings.PktLagMin, 5.0f, 0, INT_MAX, "%d ms"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -125,7 +145,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::DragInt("Lag Max", &Settings.PktLagMax, 5.0f, 0, INT_MAX, "%d ms"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -137,7 +157,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Packet Loss", &Settings.PktLoss, 0, 100, "%d%%"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -153,7 +173,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Packet Order", &Settings.PktOrder, 0, 100, "%d%%"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -168,7 +188,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Packet Dup", &Settings.PktDup, 0, 100, "%d%%"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -186,7 +206,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
ImGui::Separator();
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::DragInt("Incoming Lag Min", &Settings.PktIncomingLagMin, 5.0f, 0, INT_MAX, "%d ms"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -198,7 +218,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::DragInt("Incoming Lag Max", &Settings.PktIncomingLagMax, 5.0f, 0, INT_MAX, "%d ms"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -210,7 +230,7 @@ void FCogEngineWindow_NetEmulation::DrawControls()
}
//-------------------------------------------------------------------------------------------
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Incoming Packet Loss", &Settings.PktIncomingLoss, 0, 100, "%d%%"))
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
@@ -2,9 +2,9 @@
#include "CogImguiContext.h"
#include "CogImguiHelper.h"
#include "CogWindowConsoleCommandManager.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "CogConsoleCommandManager.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "Engine/EngineBaseTypes.h"
#include "Engine/World.h"
#include "imgui.h"
@@ -12,6 +12,13 @@
#include "Misc/Paths.h"
#include "NetImgui_Api.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::RenderHelp()
{
ImGui::Text("This window manage the connection to the NetImgui server."
"See https://github.com/sammyfreg/netImgui for more info.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::Initialize()
{
@@ -19,7 +26,7 @@ void FCogEngineWindow_NetImgui::Initialize()
Config = GetConfig<UCogEngineWindowConfig_NetImgui>();
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.NetImgui.Connect"),
TEXT("Connect to NetImgui server"),
GetWorld(),
@@ -28,7 +35,7 @@ void FCogEngineWindow_NetImgui::Initialize()
ConnectTo();
}));
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.NetImgui.Listen"),
TEXT("Listen for NetImgui server connection"),
GetWorld(),
@@ -37,7 +44,7 @@ void FCogEngineWindow_NetImgui::Initialize()
ConnectFrom();
}));
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.NetImgui.Disconnect"),
TEXT("Disconnect from NetImgui server"),
GetWorld(),
@@ -46,7 +53,7 @@ void FCogEngineWindow_NetImgui::Initialize()
Disconnect();
}));
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.NetImgui.RunServer"),
TEXT("Run NetImgui server application"),
GetWorld(),
@@ -55,7 +62,7 @@ void FCogEngineWindow_NetImgui::Initialize()
RunServer();
}));
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
TEXT("Cog.NetImgui.CloseServer"),
TEXT("Close NetImgui server application"),
GetWorld(),
@@ -76,20 +83,6 @@ void FCogEngineWindow_NetImgui::Shutdown()
CloseServer();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::RenderHelp()
{
ImGui::Text("This window manage the connection to the NetImgui server."
"See https://github.com/sammyfreg/netImgui for more info.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::RenderTick(float DeltaTime)
{
@@ -107,7 +100,7 @@ void FCogEngineWindow_NetImgui::RenderTick(float DeltaTime)
RunServer();
}
ECogNetImguiAutoConnectionMode AutoConnectMode = ECogNetImguiAutoConnectionMode::NoAutoConnect;
ECogNetImguiAutoConnectionMode AutoConnectMode;
switch (GetWorld()->GetNetMode())
{
case NM_Client: AutoConnectMode = Config->AutoConnectOnClient; break;
@@ -221,38 +214,38 @@ void FCogEngineWindow_NetImgui::RenderContent()
{
ImGui::SeparatorText("Connection");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::InputText("Server Address", Config->ServerAddress);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::InputText("Server Address", Config->ServerAddress);
ImGui::SetItemTooltip("NetImgui server application address.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::InputInt("Server Port", &Config->ServerPort);
ImGui::SetItemTooltip("Port of the NetImgui Server application to connect to.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::InputText("Client Name", Config->ClientName);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::InputText("Client Name", Config->ClientName);
ImGui::SetItemTooltip("Client name displayed in the server's clients list.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::InputInt("Client Port", &Config->ClientPort);
ImGui::SetItemTooltip("Port this client should wait for connection from server application.");
ImGui::SeparatorText("Auto-Connect");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Dedicated Server", Config->AutoConnectOnDedicatedServer);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Dedicated Server", Config->AutoConnectOnDedicatedServer);
ImGui::SetItemTooltip("Auto-connect mode to the NetImgui server when launching on dedicated server mode.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Listen Server", Config->AutoConnectOnListenServer);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Listen Server", Config->AutoConnectOnListenServer);
ImGui::SetItemTooltip("Auto-connect mode to the NetImgui server when launching on listen server mode.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Client", Config->AutoConnectOnClient);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Client", Config->AutoConnectOnClient);
ImGui::SetItemTooltip("Auto-connect mode to the NetImgui server when launching on client mode.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::ComboboxEnum("Standalone", Config->AutoConnectOnStandalone);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::ComboboxEnum("Standalone", Config->AutoConnectOnStandalone);
ImGui::SetItemTooltip("Auto-connect mode to the NetImgui server when launching on standalone mode.");
ImGui::SeparatorText("Server App");
@@ -260,19 +253,19 @@ void FCogEngineWindow_NetImgui::RenderContent()
ImGui::Checkbox("Auto Run Server", &Config->AutoRunServer);
ImGui::SetItemTooltip("Automatically run the NetImgui server executable at startup.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::InputText("Server Executable", Config->ServerExecutable);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::InputText("Server Executable", Config->ServerExecutable);
ImGui::SetItemTooltip("Filename of the NetImgui server executable.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::InputText("Server Directory", Config->ServerDirectory);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::InputText("Server Directory", Config->ServerDirectory);
ImGui::SetItemTooltip("Directory of the NetImgui server executable.");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWindowWidgets::InputText("Server Arguments", Config->ServerArguments);
FCogWidgets::SetNextItemToShortWidth();
FCogWidgets::InputText("Server Arguments", Config->ServerArguments);
ImGui::SetItemTooltip("Argument used when launching the NetImgui server executable.");
}
#endif // #if NETIMGUI_ENABLED
#endif
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -292,7 +285,7 @@ FString FCogEngineWindow_NetImgui::GetClientName() const
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::ConnectTo()
void FCogEngineWindow_NetImgui::ConnectTo() const
{
FCogImGuiContextScope ImGuiContextScope(GetOwner()->GetContext());
@@ -309,7 +302,7 @@ void FCogEngineWindow_NetImgui::ConnectTo()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::ConnectFrom()
void FCogEngineWindow_NetImgui::ConnectFrom() const
{
FCogImGuiContextScope ImGuiContextScope(GetOwner()->GetContext());
@@ -325,7 +318,7 @@ void FCogEngineWindow_NetImgui::ConnectFrom()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_NetImgui::Disconnect()
void FCogEngineWindow_NetImgui::Disconnect() const
{
FCogImGuiContextScope ImGuiContextScope(GetOwner()->GetContext());
@@ -0,0 +1,333 @@
#include "CogEngineWindow_Notifications.h"
#include "CogCommon.h"
#include "CogCommonLogCategory.h"
#include "CogImguiHelper.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "Misc/StringBuilder.h"
int32 FCogEngineWindow_Notifications::NotificationsId = 0;
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::Initialize()
{
Super::Initialize();
Config = GetConfig<UCogEngineConfig_Notifications>();
OutputDevice.Notifications = this;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::RenderHelp()
{
ImGui::Text("This window manage the notifications.");
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::Clear()
{
Notifications.Empty();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::AddNotification(const TCHAR* InMessage, ELogVerbosity::Type InVerbosity)
{
FNotification& Notification = Notifications.AddDefaulted_GetRef();
Notification.Id = FString::Printf(TEXT("###Notify%d"), NotificationsId);
Notification.Time = FDateTime::Now();
Notification.Verbosity = InVerbosity;
Notification.Message = InMessage;
NotificationsId++;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::OnLogReceived(const TCHAR* InMessage, ELogVerbosity::Type InVerbosity, const class FName& InCategory)
{
if (Config == nullptr)
{ return; }
if (Config->DisableNotifications)
{ return; }
static FName CmdName("Cmd");
#if ENABLE_COG
if (InCategory == LogCogNotify.GetCategoryName()
|| (InCategory == CmdName && Config->NotifyConsoleCommands)
|| (InVerbosity == ELogVerbosity::Warning && Config->NotifyAllWarnings)
|| (InVerbosity == ELogVerbosity::Error && Config->NotifyAllErrors))
{
AddNotification(InMessage, InVerbosity);
}
#endif
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::RenderTick(float DeltaTime)
{
Super::RenderTick(DeltaTime);
if (Config->DisableNotifications)
{ return; }
RenderNotifications();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::RenderNotifications()
{
if (Notifications.Num() == 0)
{ return; }
constexpr ImGuiWindowFlags Flags =
ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoDecoration
| ImGuiWindowFlags_NoDocking
| ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoFocusOnAppearing
| ImGuiWindowFlags_NoNav
| ImGuiWindowFlags_NoInputs;
const ImGuiViewport* Viewport = ImGui::GetMainViewport();
const float DpiScale = GetDpiScale();
ImVec2 WindowPos = FCogWidgets::ComputeScreenCornerLocation(Config->Alignment, Config->Padding);
const ImVec2 WindowPadding = ImGui::GetStyle().WindowPadding;
const ImVec2 ItemSpacing = ImGui::GetStyle().ItemSpacing;
const float MaxHeight = Config->MaxHeight * DpiScale + WindowPadding.y * 2;
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, Config->Rounding);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, Config->ShowBorder);
const FDateTime Now = FDateTime::Now();
for (int32 i = Notifications.Num() - 1; i >= 0; i--)
{
const FNotification& Notification = Notifications[i];
const FTimespan Span = Now - Notification.Time;
if (Span > FTimespan::FromSeconds(Config->Duration + Config->FadeOut))
{
Notifications.RemoveAt(i);
continue;
}
ImVec4 TextColor, BackColor, BorderColor;
switch (Notification.Verbosity)
{
case ELogVerbosity::Error:
{
TextColor = FCogImguiHelper::ToImVec4(Config->TextErrorColor);
BackColor = FCogImguiHelper::ToImVec4(Config->BackgroundErrorColor);
BorderColor = FCogImguiHelper::ToImVec4(Config->BorderErrorColor);
break;
}
case ELogVerbosity::Warning:
{
TextColor = FCogImguiHelper::ToImVec4(Config->TextWarningColor);
BackColor = FCogImguiHelper::ToImVec4(Config->BackgroundWarningColor);
BorderColor = FCogImguiHelper::ToImVec4(Config->BorderWarningColor);
break;
}
default:
{
TextColor = FCogImguiHelper::ToImVec4(Config->TextDefaultColor);
BackColor = FCogImguiHelper::ToImVec4(Config->BackgroundDefaultColor);
BorderColor = FCogImguiHelper::ToImVec4(Config->BorderDefaultColor);
break;
}
}
const float ElapsedTime = Span.GetTotalSeconds();
const float Alpha = FMath::GetMappedRangeValueClamped(FVector2d(Config->Duration, Config->Duration + Config->FadeOut), FVector2d(1.0f, 0.0f), ElapsedTime);
BackColor.w *= Alpha;
TextColor.w *= Alpha;
BorderColor.w *= Alpha;
ImGui::PushStyleColor(ImGuiCol_WindowBg, BackColor);
ImGui::PushStyleColor(ImGuiCol_Border, BorderColor);
ImGui::PushStyleColor(ImGuiCol_Text, TextColor);
const auto Message = StringCast<ANSICHAR>(*Notification.Message);
const float WrapWidth = Config->TextWrapping * DpiScale;
ImGui::SetNextWindowViewport(Viewport->ID);
ImGui::SetNextWindowPos(WindowPos, ImGuiCond_Always, FCogImguiHelper::ToImVec2(Config->Alignment));
if (Config->UseFixedWidth)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(WrapWidth + WindowPadding.x * 2, 0), ImVec2(WrapWidth + WindowPadding.x * 2, MaxHeight));
}
if (ImGui::Begin(StringCast<ANSICHAR>(*Notification.Id).Get(), nullptr, Flags))
{
ImGui::PushTextWrapPos(WrapWidth);
ImGui::TextUnformatted(Message.Get());
ImGui::PopTextWrapPos();
}
ImGui::PopStyleColor(3);
//----------------------------------------------------------------------
// Compute ourself window height otherwise we get a one frame glitch,
// maybe because the real window size is computed the next frame.
//----------------------------------------------------------------------
const ImVec2 TextSize = ImGui::CalcTextSize(Message.Get(), nullptr, false, WrapWidth);
const float WindowHeight = FMath::Min(MaxHeight, TextSize.y + (WindowPadding.y * 2));
WindowPos.y += (WindowHeight + ItemSpacing.y) * (Config->Alignment.Y > 0.5f ? -1 : 1);
ImGui::End();
}
ImGui::PopStyleVar(2);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::RenderContent()
{
Super::RenderContent();
if (ImGui::Button("Clear Notifications", ImVec2(-1, 0)))
{
Notifications.Empty();
}
FCogWidgets::ThinSeparatorText("Notification Test");
if (ImGui::Button("Notify Normal", ImVec2(-1, 0)))
{
COG_NOTIFY(TEXT("A notification test. Frame:%llu"), GFrameCounter);
}
if (ImGui::Button("Notify Warning", ImVec2(-1, 0)))
{
COG_NOTIFY_WARNING(TEXT("A long long long long long long long long long long long long long long long long long long long long long warning notification test. Frame:%llu"), GFrameCounter);
}
if (ImGui::Button("Notify Error", ImVec2(-1, 0)))
{
COG_NOTIFY_ERROR(TEXT("An error notification test. Frame:%llu"), GFrameCounter);
}
RenderSettings();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Notifications::RenderSettings()
{
FCogWidgets::ThinSeparatorText("Filtering");
ImGui::Checkbox("Disable Notifications", &Config->DisableNotifications);
ImGui::Checkbox("Notify Console Commands", &Config->NotifyConsoleCommands);
ImGui::Checkbox("Notify All Warnings", &Config->NotifyAllWarnings);
ImGui::Checkbox("Notify All Errors", &Config->NotifyAllErrors);
FCogWidgets::ThinSeparatorText("Location & Size");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat2("Alignment", &Config->Alignment.X, 0, 1.0f, "%.2f");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt2("Padding", &Config->Padding.X, 0, 100);
ImGui::Checkbox("Use Fixed Width", &Config->UseFixedWidth);
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Text Wrapping", &Config->TextWrapping, 1, 500);
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Max Height", &Config->MaxHeight, 0, 500);
FCogWidgets::ThinSeparatorText("Display");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Duration", &Config->Duration, 1, 10, "%0.1f");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Fade Out", &Config->FadeOut, 0, 3, "%0.1f");
ImGui::Checkbox("Show Border", &Config->ShowBorder);
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Rounding", &Config->Rounding, 0, 12);
FCogWidgets::ThinSeparatorText("Colors");
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("##BackDef", Config->BackgroundDefaultColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Background Default");
FCogImguiHelper::ColorEdit4("##BackWarn", Config->BackgroundWarningColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Background Warning");
FCogImguiHelper::ColorEdit4("##BackError", Config->BackgroundErrorColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Background Error");
ImGui::TextUnformatted("Background Color");
FCogImguiHelper::ColorEdit4("##BorderDef", Config->BorderDefaultColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Border Default");
FCogImguiHelper::ColorEdit4("##BorderWarn", Config->BorderWarningColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Border Warning");
FCogImguiHelper::ColorEdit4("##BorderError", Config->BorderErrorColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Border Error");
ImGui::TextUnformatted("Border Color");
FCogImguiHelper::ColorEdit4("##TextDef", Config->TextDefaultColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Text Default");
FCogImguiHelper::ColorEdit4("##TextWarn", Config->TextWarningColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Text Warning");
FCogImguiHelper::ColorEdit4("##TextError", Config->TextErrorColor, ColorEditFlags);
ImGui::SameLine();
ImGui::SetItemTooltip("Text Error");
ImGui::TextUnformatted("Text Color");
ImGui::Separator();
if (ImGui::Button("Reset Settings", ImVec2(-1, 0)))
{
ResetConfig();
}
}
//--------------------------------------------------------------------------------------------------------------------------
// FCogNotificationOutputDevice
//--------------------------------------------------------------------------------------------------------------------------
FCogNotificationOutputDevice::FCogNotificationOutputDevice()
{
GLog->AddOutputDevice(this);
}
//--------------------------------------------------------------------------------------------------------------------------
FCogNotificationOutputDevice::~FCogNotificationOutputDevice()
{
if (GLog != nullptr)
{
GLog->RemoveOutputDevice(this);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogNotificationOutputDevice::Serialize(const TCHAR* Message, const ELogVerbosity::Type Verbosity, const FName& Category)
{
if (Notifications != nullptr)
{
Notifications->OnLogReceived(Message, Verbosity, Category);
}
}
@@ -1,8 +1,12 @@
#include "CogEngineWindow_OutputLog.h"
#include "CogCommon.h"
#include "CogCommonLogCategory.h"
#include "CogDebugHelper.h"
#include "CogWindowWidgets.h"
#include "CogImguiHelper.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "HAL/PlatformApplicationMisc.h"
#include "Misc/StringBuilder.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -25,137 +29,188 @@ void FCogEngineWindow_OutputLog::RenderHelp()
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::Clear()
{
TextBuffer.clear();
LineInfos.Empty();
LogInfos.Empty();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::AddLog(const TCHAR* Message, ELogVerbosity::Type Verbosity, const class FName& Category)
void FCogEngineWindow_OutputLog::AddLog(const TCHAR* InMessage, ELogVerbosity::Type InVerbosity, const class FName& InCategory)
{
static TAnsiStringBuilder<512> Format;
Format.Reset();
if (Message)
if (InMessage)
{
Format.Append(Message);
Format.Append(InMessage);
}
FLineInfo& LineInfo = LineInfos.AddDefaulted_GetRef();
LineInfo.Frame = GFrameCounter % 1000;
LineInfo.Verbosity = Verbosity;
LineInfo.Category = Category;
LineInfo.Start = TextBuffer.size();
FLogInfo& LogInfo = LogInfos.AddDefaulted_GetRef();
LogInfo.Frame = GFrameCounter;
LogInfo.Time = Config != nullptr && Config->UseUTCTime ? FDateTime::UtcNow() : FDateTime::Now();
LogInfo.Verbosity = InVerbosity;
LogInfo.Category = InCategory;
LogInfo.LineStart = TextBuffer.size();
TextBuffer.append(Format.GetData(), Format.GetData() + Format.Len());
LineInfo.End = TextBuffer.size();
LogInfo.LineEnd = TextBuffer.size();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::DrawRow(const char* BufferStart, const FLineInfo& LineInfo, bool IsTableShown) const
void FCogEngineWindow_OutputLog::DrawRow(const char* InBufferStart, const FLogInfo& InLogInfo, bool InShowAsTableRow) const
{
ImU32 Color;
switch (LineInfo.Verbosity)
switch (InLogInfo.Verbosity)
{
case ELogVerbosity::Error: Color = IM_COL32(255, 0, 0, 255); break;
case ELogVerbosity::Warning: Color = IM_COL32(255, 200, 0, 255); break;
default: Color = IM_COL32(200, 200, 200, 255); break;
case ELogVerbosity::Error: Color = FCogImguiHelper::ToImColor(Config->ErrorColor); break;
case ELogVerbosity::Warning: Color = FCogImguiHelper::ToImColor(Config->WarningColor); break;
default: Color = FCogImguiHelper::ToImColor(Config->DefaultColor); break;
}
ImGui::PushStyleColor(ImGuiCol_Text, Color);
if (IsTableShown)
if (InShowAsTableRow)
{
ImGui::TableNextRow();
if (Config->ShowFrame)
{
ImGui::TableNextColumn();
ImGui::Text("%3d", LineInfo.Frame);
}
if (Config->ShowCategory)
{
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*LineInfo.Category.ToString()));
}
if (Config->ShowVerbosity)
{
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(ToString(LineInfo.Verbosity)));
}
ImGui::TableNextColumn();
const char* LineStart = BufferStart + LineInfo.Start;
const char* LineEnd = BufferStart + LineInfo.End;
ImGui::TextUnformatted(LineStart, LineEnd);
}
else
if (Config->ShowFrame)
{
if (Config->ShowFrame)
if (InShowAsTableRow)
{
ImGui::TableNextColumn();
}
ImGui::Text("%3d", GetDisplayedFrame(InLogInfo));
if (InShowAsTableRow == false)
{
ImGui::Text("[%3d] ", LineInfo.Frame);
ImGui::SameLine();
}
if (Config->ShowCategory)
{
ImGui::Text("%s: ", TCHAR_TO_ANSI(*LineInfo.Category.ToString()));
ImGui::SameLine();
}
if (Config->ShowVerbosity)
{
ImGui::Text("%s: ", TCHAR_TO_ANSI(ToString(LineInfo.Verbosity)));
ImGui::SameLine();
}
const char* LineStart = BufferStart + LineInfo.Start;
const char* LineEnd = BufferStart + LineInfo.End;
ImGui::TextUnformatted(LineStart, LineEnd);
}
if (Config->ShowTime)
{
if (InShowAsTableRow)
{
ImGui::TableNextColumn();
}
ImGui::TextUnformatted(StringCast<ANSICHAR>(*InLogInfo.Time.ToString()).Get());
if (InShowAsTableRow == false)
{
ImGui::SameLine();
}
}
if (Config->ShowCategory)
{
if (InShowAsTableRow)
{
ImGui::TableNextColumn();
}
ImGui::TextUnformatted(StringCast<ANSICHAR>(*InLogInfo.Category.ToString()).Get());
if (InShowAsTableRow == false)
{
ImGui::SameLine();
}
}
if (Config->ShowVerbosity)
{
if (InShowAsTableRow)
{
ImGui::TableNextColumn();
}
ImGui::TextUnformatted(StringCast<ANSICHAR>(ToString(InLogInfo.Verbosity)).Get());
if (InShowAsTableRow == false)
{
ImGui::SameLine();
}
}
if (InShowAsTableRow)
{
ImGui::TableNextColumn();
}
const char* LineStart = InBufferStart + InLogInfo.LineStart;
const char* LineEnd = InBufferStart + InLogInfo.LineEnd;
ImGui::TextUnformatted(LineStart, LineEnd);
ImGui::PopStyleColor();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::Copy() const
{
const auto Buffer = StringCast<TCHAR>(TextBuffer.c_str());
const wchar_t* BufferData = Buffer.Get();
if (BufferData == nullptr)
{ return; }
FStringBuilderBase StringBuilder;
for (const FLogInfo& LogInfo : LogInfos)
{
StringBuilder.Append(FString::Printf(TEXT("[%3d] [%s] [%s] "), GetDisplayedFrame(LogInfo), *LogInfo.Category.ToString(), ToString(LogInfo.Verbosity)));
StringBuilder.Append(BufferData + LogInfo.LineStart, LogInfo.LineEnd - LogInfo.LineStart);
StringBuilder.Append("\n");
};
FPlatformApplicationMisc::ClipboardCopy(StringBuilder.ToString());
}
//--------------------------------------------------------------------------------------------------------------------------
int32 FCogEngineWindow_OutputLog::GetDisplayedFrame(const FCogEngineWindow_OutputLog::FLogInfo& InLogInfo) const
{
return Config->FrameCycle > 0 ? InLogInfo.Frame % Config->FrameCycle : InLogInfo.Frame;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_OutputLog::RenderContent()
{
Super::RenderContent();
bool ClearPressed = false;
bool CopyPressed = false;
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
if (ImGui::MenuItem("Copy"))
{
ImGui::LogToClipboard();
Copy();
}
ImGui::Separator();
ImGui::Checkbox("Auto Scroll", &Config->AutoScroll);
ImGui::Checkbox("Show Frame", &Config->ShowFrame);
ImGui::Checkbox("Show Time", &Config->ShowTime);
ImGui::Checkbox("Show Category", &Config->ShowCategory);
ImGui::Checkbox("Show Verbosity", &Config->ShowVerbosity);
ImGui::Checkbox("Show As Table", &Config->ShowAsTable);
ImGui::Separator();
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("Default Color", Config->DefaultColor, ColorEditFlags);
FCogImguiHelper::ColorEdit4("Warning Color", Config->WarningColor, ColorEditFlags);
FCogImguiHelper::ColorEdit4("Error Color", Config->ErrorColor, ColorEditFlags);
ImGui::Separator();
if (ImGui::Button("Reset Settings", ImVec2(-1, 0)))
{
ResetConfig();
}
ImGui::EndMenu();
}
@@ -169,12 +224,12 @@ void FCogEngineWindow_OutputLog::RenderContent()
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 9);
if (ImGui::BeginCombo("##Verbosity", FCogDebugHelper::VerbosityToString((ELogVerbosity::Type)Config->VerbosityFilter)))
if (ImGui::BeginCombo("##Verbosity", FCogDebugHelper::VerbosityToString(static_cast<ELogVerbosity::Type>(Config->VerbosityFilter))))
{
for (int32 i = ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
for (int32 i = ELogVerbosity::Error; i <= static_cast<int32>(ELogVerbosity::VeryVerbose); ++i)
{
const bool IsSelected = i == Config->VerbosityFilter;
const ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
const ELogVerbosity::Type Verbosity = static_cast<ELogVerbosity::Type>(i);
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
{
@@ -184,35 +239,36 @@ void FCogEngineWindow_OutputLog::RenderContent()
ImGui::EndCombo();
}
FCogWindowWidgets::SearchBar(Filter);
FCogWidgets::SearchBar("##Filter", Filter);
ImGui::EndMenuBar();
}
int32 ColumnCount = 1;
ColumnCount += (int32)Config->ShowFrame;
ColumnCount += (int32)Config->ShowCategory;
ColumnCount += (int32)Config->ShowVerbosity;
ColumnCount += Config->ShowFrame ? 1 : 0;
ColumnCount += Config->ShowTime ? 1 : 0;
ColumnCount += Config->ShowCategory ? 1 : 0;
ColumnCount += Config->ShowVerbosity ? 1 : 0;
bool IsTableShown = false;
if (Config->ShowAsTable)
{
if (ImGui::BeginTable("LogTable", ColumnCount, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollX))
if (ImGui::BeginTable("LogTable", ColumnCount, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ScrollX | ImGuiTableFlags_NoHostExtendX))
{
IsTableShown = true;
if (Config->ShowFrame)
{
ImGui::TableSetupColumn("Frame", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::GetFontWidth() * 4);
ImGui::TableSetupColumn("Frame", ImGuiTableColumnFlags_WidthFixed, FCogWidgets::GetFontWidth() * 4);
}
if (Config->ShowCategory)
{
ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::GetFontWidth() * 10);
ImGui::TableSetupColumn("Category", ImGuiTableColumnFlags_WidthFixed, FCogWidgets::GetFontWidth() * 10);
}
if (Config->ShowVerbosity)
{
ImGui::TableSetupColumn("Verbosity", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::GetFontWidth() * 10);
ImGui::TableSetupColumn("Verbosity", ImGuiTableColumnFlags_WidthFixed, FCogWidgets::GetFontWidth() * 10);
}
ImGui::TableSetupColumn("Message", ImGuiTableColumnFlags_WidthStretch);
@@ -228,11 +284,11 @@ void FCogEngineWindow_OutputLog::RenderContent()
if (Filter.IsActive())
{
for (int32 LineIndex = 0; LineIndex < LineInfos.Num(); LineIndex++)
for (int32 LineIndex = 0; LineIndex < LogInfos.Num(); LineIndex++)
{
const FLineInfo& LineInfo = LineInfos[LineIndex];
const char* LineStart = BufferStart + LineInfo.Start;
const char* LineEnd = BufferStart + LineInfo.End;
const FLogInfo& LineInfo = LogInfos[LineIndex];
const char* LineStart = BufferStart + LineInfo.LineStart;
const char* LineEnd = BufferStart + LineInfo.LineEnd;
if (Filter.PassFilter(LineStart, LineEnd))
{
DrawRow(BufferStart, LineInfo, IsTableShown);
@@ -241,14 +297,12 @@ void FCogEngineWindow_OutputLog::RenderContent()
}
else if (Config->VerbosityFilter != ELogVerbosity::VeryVerbose)
{
for (int32 LineIndex = 0; LineIndex < LineInfos.Num(); LineIndex++)
for (int32 LineIndex = 0; LineIndex < LogInfos.Num(); LineIndex++)
{
const FLineInfo& LineInfo = LineInfos[LineIndex];
const FLogInfo& LineInfo = LogInfos[LineIndex];
if (LineInfo.Verbosity <= (ELogVerbosity::Type)Config->VerbosityFilter)
if (LineInfo.Verbosity <= static_cast<ELogVerbosity::Type>(Config->VerbosityFilter))
{
const char* LineStart = BufferStart + LineInfo.Start;
const char* LineEnd = BufferStart + LineInfo.End;
DrawRow(BufferStart, LineInfo, IsTableShown);
}
}
@@ -256,14 +310,14 @@ void FCogEngineWindow_OutputLog::RenderContent()
else
{
ImGuiListClipper Clipper;
Clipper.Begin(LineInfos.Num());
Clipper.Begin(LogInfos.Num());
while (Clipper.Step())
{
for (int32 LineIndex = Clipper.DisplayStart; LineIndex < Clipper.DisplayEnd; LineIndex++)
{
if (LineInfos.IsValidIndex(LineIndex))
if (LogInfos.IsValidIndex(LineIndex))
{
const FLineInfo& LineInfo = LineInfos[LineIndex];
const FLogInfo& LineInfo = LogInfos[LineIndex];
DrawRow(BufferStart, LineInfo, IsTableShown);
}
}
@@ -292,6 +346,11 @@ void FCogEngineWindow_OutputLog::RenderContent()
Clear();
}
if (ImGui::MenuItem("Copy"))
{
Copy();
}
ImGui::EndPopup();
}
}
@@ -1,8 +1,10 @@
#include "CogEngineWindow_Plots.h"
#include "CogDebugPlot.h"
#include "CogDebug.h"
#include "CogDebugTracker.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "Engine/World.h"
#include "imgui.h"
#include "implot_internal.h"
@@ -13,11 +15,15 @@ void FCogEngineWindow_Plots::Initialize()
Super::Initialize();
bHasMenu = true;
bNoPadding = true;
auto& Tracker = FCogDebug::GetTracker();
Tracker.Clear();
Config = GetConfig<UCogEngineConfig_Plots>();
FCogDebugPlot::Clear();
if (Config != nullptr)
{
RefreshPlotSettings();
}
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -33,15 +39,28 @@ void FCogEngineWindow_Plots::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
RefreshPlotSettings();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderTick(float DeltaTime)
{
Super::RenderTick(DeltaTime);
FCogDebugPlot::IsVisible = GetIsVisible();
FCogDebugTracker& Tracker = FCogDebug::GetTracker();
Tracker.IsVisible = GetIsVisible();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::PreBegin(ImGuiWindowFlags& WindowFlags)
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::PostBegin()
{
ImGui::PopStyleVar();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -49,24 +68,9 @@ void FCogEngineWindow_Plots::RenderContent()
{
Super::RenderContent();
TArray<FCogDebugPlotEntry*> VisiblePlots;
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
{
if (Plot.YAxis != ImAxis_COUNT && Plot.GraphIndex != INDEX_NONE)
{
VisiblePlots.Add(&Plot);
}
}
FCogDebugTracker& Tracker = FCogDebug::GetTracker();
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
{
if (Event.YAxis != ImAxis_COUNT && Event.GraphIndex != INDEX_NONE)
{
VisiblePlots.Add(&Event);
}
}
RenderMenu();
RenderMenu(Tracker);
if (Config->DockEntries)
{
@@ -77,16 +81,16 @@ void FCogEngineWindow_Plots::RenderContent()
| ImGuiTableFlags_NoPadOuterX))
{
ImGui::TableSetupColumn("PlotsList", ImGuiTableColumnFlags_WidthFixed, FCogWindowWidgets::GetFontWidth() * 20.0f);
ImGui::TableSetupColumn("PlotsList", ImGuiTableColumnFlags_WidthFixed, FCogWidgets::GetFontWidth() * 20.0f);
ImGui::TableSetupColumn("Plots", ImGuiTableColumnFlags_WidthStretch, 0.0f);
ImGui::TableNextRow();
ImGui::TableNextColumn();
RenderAllEntriesNames(ImVec2(0, -1));
RenderAllEntriesNames(Tracker, ImVec2(0, -1));
ImGui::TableNextColumn();
RenderPlots(VisiblePlots);
RenderPlots(Tracker);
ImGui::EndTable();
}
@@ -94,14 +98,22 @@ void FCogEngineWindow_Plots::RenderContent()
}
else
{
RenderPlots(VisiblePlots);
RenderPlots(Tracker);
}
bApplyTimeScale = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderMenu()
void FCogEngineWindow_Plots::RefreshPlotSettings()
{
FCogDebugTracker& Tracker = FCogDebug::GetTracker();
Tracker.SetNumRecordedValues(Config->NumRecordedValues);
Tracker.RecordValuesWhenPause = Config->RecordValuesWhenPaused;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderMenu(FCogDebugTracker& InTracker)
{
if (ImGui::BeginMenuBar())
{
@@ -109,91 +121,120 @@ void FCogEngineWindow_Plots::RenderMenu()
{
if (ImGui::BeginMenu("Entries"))
{
RenderAllEntriesNames(ImVec2(ImGui::GetFontSize() * 15, ImGui::GetFontSize() * 20));
RenderAllEntriesNames(InTracker, ImVec2(ImGui::GetFontSize() * 15, ImGui::GetFontSize() * 20));
ImGui::EndMenu();
}
}
if (ImGui::BeginMenu("Options"))
{
if (ImGui::MenuItem("Reset"))
{
FCogDebugPlot::Pause = false;
FCogDebugPlot::Reset();
ResetConfig();
}
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Num graphs", &Config->NumGraphs, 1, UCogEngineConfig_Plots::MaxNumGraphs);
ImGui::Separator();
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Num Graphs", &Config->NumGraphs, 1, 5))
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Num Y axis", &Config->NumYAxis, 1, 3);
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 100.0f, "%0.0f"))
{
bApplyTimeScale = true;
}
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Num YAxis", &Config->NumYAxis, 0, 3);
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 100.0f, "%0.1f"))
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Num recorded values", &Config->NumRecordedValues, 100, 10000))
{
bApplyTimeScale = true;
Config->NumRecordedValues = (Config->NumRecordedValues / 100) * 100;
}
if (ImGui::IsItemDeactivatedAfterEdit())
{
RefreshPlotSettings();
}
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Auto-fit padding", &Config->AutoFitPadding, 0.0f, 0.2f, "%0.2f");
FCogWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Drag pause sensitivity", &Config->DragPauseSensitivity, 1.0f, 50.0f, "%0.0f");
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Record values when paused", &Config->RecordValuesWhenPaused);
if (ImGui::IsItemDeactivatedAfterEdit())
{
RefreshPlotSettings();
}
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Show time bar at game time", &Config->ShowTimeBarAtGameTime);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Show time bar at cursor", &Config->ShowTimeBarAtCursor);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Show value at cursor", &Config->ShowValueAtCursor);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Dock entries", &Config->DockEntries);
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("Pause background color", Config->PauseBackgroundColor, ColorEditFlags);
ImGui::SetItemTooltip("Background color of the plot when paused.");
ImGui::Separator();
if (ImGui::MenuItem("Reset Settings"))
{
InTracker.Pause = false;
InTracker.Reset();
ResetConfig();
bApplyTimeScale = true;
}
ImGui::EndMenu();
}
if (ImGui::MenuItem("Clear"))
{
FCogDebugPlot::Clear();
InTracker.Clear();
}
FCogWindowWidgets::ToggleMenuButton(&FCogDebugPlot::Pause, "Pause", ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
FCogWidgets::ToggleMenuButton(&InTracker.Pause, "Pause", ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
ImGui::EndMenuBar();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugPlotEntry& Entry)
void FCogEngineWindow_Plots::RenderEntryName(FCogDebugTracker& InTracker, const int Index, FCogDebugTrack& Entry)
{
ImGui::PushID(Index);
const bool IsAssignedToRow = Entry.GraphIndex != INDEX_NONE;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Name.ToString()), IsAssignedToRow, ImGuiSelectableFlags_AllowDoubleClick))
bool IsAssignedToGraph = false;
for (int32 i = 0; i < UCogEngineConfig_Plots::MaxNumGraphs; ++i)
{
if (IsAssignedToRow)
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[i];
if (GraphInfo.Entries.ContainsByPredicate([Entry](const auto& InEntry) { return InEntry.Name == Entry.Id; }))
{
Entry.ResetGraphAndAxis();
IsAssignedToGraph = true;
break;
}
}
if (ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Id.ToString()), IsAssignedToGraph, ImGuiSelectableFlags_AllowDoubleClick))
{
if (IsAssignedToGraph)
{
UnassignToGraphAndAxis(InTracker, Entry.Id);
}
else
{
Entry.AssignGraphAndAxis(0, ImAxis_Y1);
AssignToGraphAndAxis(InTracker, Entry.Id, 0, ImAxis_Y1);
}
}
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
{
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
const auto EntryName = StringCast<ANSICHAR>(*Entry.Id.ToString());
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
ImGui::Text("%s", EntryName.Get());
ImGui::EndDragDropSource();
@@ -203,52 +244,48 @@ void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugPlotEntry
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderAllEntriesNames(const ImVec2& InSize)
void FCogEngineWindow_Plots::RenderAllEntriesNames(FCogDebugTracker& InTracker, const ImVec2& InSize)
{
const int32 Indent = ImGui::GetFontSize() * 0.5f;
if (ImGui::BeginChild("Entries", InSize))
{
if (Config->DockEntries)
{
ImGui::Indent(6);
}
int Index = 0;
if (FCogWindowWidgets::DarkCollapsingHeader("Events", ImGuiTreeNodeFlags_DefaultOpen))
if (FCogWidgets::DarkCollapsingHeader("Events", ImGuiTreeNodeFlags_DefaultOpen))
{
if (FCogDebugPlot::Events.IsEmpty())
ImGui::Indent(Indent);
if (InTracker.Events.IsEmpty())
{
ImGui::TextDisabled("No event added yet");
}
else
{
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
for (auto& kv : InTracker.Events)
{
RenderEntryName(Index, Event);
RenderEntryName(InTracker, Index, kv.Value);
Index++;
}
}
ImGui::Unindent(Indent);
}
if (FCogWindowWidgets::DarkCollapsingHeader("Plots", ImGuiTreeNodeFlags_DefaultOpen))
if (FCogWidgets::DarkCollapsingHeader("Plots", ImGuiTreeNodeFlags_DefaultOpen))
{
if (FCogDebugPlot::Plots.IsEmpty())
ImGui::Indent(Indent);
if (InTracker.Values.IsEmpty())
{
ImGui::TextDisabled("No plot added yet");
}
else
{
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
for (auto& kv : InTracker.Values)
{
RenderEntryName(Index, Plot);
RenderEntryName(InTracker, Index, kv.Value);
Index++;
}
}
}
if (Config->DockEntries)
{
ImGui::Unindent();
ImGui::Unindent(Indent);
}
}
ImGui::EndChild();
@@ -257,17 +294,14 @@ void FCogEngineWindow_Plots::RenderAllEntriesNames(const ImVec2& InSize)
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->ResetGraphAndAxis();
}
UnassignToGraphAndAxis(InTracker, GetDroppedEntryName(Payload));
}
ImGui::EndDragDropTarget();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& VisiblePlots) const
void FCogEngineWindow_Plots::RenderPlots(FCogDebugTracker& InTracker)
{
if (ImGui::BeginChild("Graph", ImVec2(0, -1)))
{
@@ -275,51 +309,72 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
static float ColRatios[] = { 1 };
static ImPlotSubplotFlags SubplotsFlags = ImPlotSubplotFlags_LinkCols;
const bool PushPlotBgStyle = FCogDebugPlot::Pause;
const bool PushPlotBgStyle = InTracker.Pause;
if (PushPlotBgStyle)
{
ImPlot::PushStyleColor(ImPlotCol_PlotBg, FCogImguiHelper::ToImVec4(Config->PauseBackgroundColor));
}
ImPlot::PushStyleVar(ImPlotStyleVar_FitPadding, ImVec2(0.0f, Config->AutoFitPadding));
if (ImPlot::BeginSubplots("", Config->NumGraphs, 1, ImVec2(-1, -1), SubplotsFlags, RowRatios, ColRatios))
{
for (int PlotIndex = 0; PlotIndex < Config->NumGraphs; ++PlotIndex)
for (int32 GraphIndex = 0; GraphIndex < Config->NumGraphs && GraphIndex < UCogEngineConfig_Plots::MaxNumGraphs; ++GraphIndex)
{
ImGui::PushID(GraphIndex);
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[GraphIndex];
if (ImPlot::BeginPlot("##Plot", ImVec2(-1, 250)))
{
ImPlotAxisFlags HasPlotOnAxisY1 = false;
ImPlotAxisFlags HasPlotOnAxisY2 = false;
ImPlotAxisFlags HasPlotOnAxisY3 = false;
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
{
HasPlotOnAxisY1 |= PlotPtr->YAxis == ImAxis_Y1 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY2 |= PlotPtr->YAxis == ImAxis_Y2 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY3 |= PlotPtr->YAxis == ImAxis_Y3 && PlotPtr->GraphIndex == PlotIndex;
}
ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines);
if (Config->NumYAxis > 0)
{
ImPlot::SetupAxis(ImAxis_Y1, HasPlotOnAxisY1 ? "" : "[drop here]", (HasPlotOnAxisY1 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit);
}
if (Config->NumYAxis > 1)
{
ImPlot::SetupAxis(ImAxis_Y2, HasPlotOnAxisY2 ? "" : "[drop here]", (HasPlotOnAxisY2 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
}
if (Config->NumYAxis > 2)
{
ImPlot::SetupAxis(ImAxis_Y3, HasPlotOnAxisY3 ? "" : "[drop here]", (HasPlotOnAxisY3 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
}
//--------------------------------------------------------------------------------------------------
// Set the initial X axis range. After, it is automatically updated to move with the current time.
//--------------------------------------------------------------------------------------------------
ImPlot::SetupAxisLimits(ImAxis_X1, 0, Config->TimeRange, ImGuiCond_Appearing);
//--------------------------------------------------------------------------------------------------
// Setup the Y axis
//--------------------------------------------------------------------------------------------------
for (int32 YAxisIndex = 0; YAxisIndex <= (ImAxis_Y3 - ImAxis_Y1); ++YAxisIndex)
{
const ImAxis YAxis = ImAxis_Y1 + YAxisIndex;
bool IsAssigned = false;
int32 YMax = 0;
for (const FCogEngineConfig_Plots_GraphEntryInfo& GraphEntry : GraphInfo.Entries)
{
IsAssigned |= GraphEntry.YAxis == YAxis;
if (FCogDebugEventTrack* EventHistory = InTracker.Events.Find(GraphEntry.Name))
{
YMax = FMath::Max(FMath::Max(5, YMax), EventHistory->MaxRow);
}
}
const bool IsAxisVisible = IsAssigned || (YAxisIndex < Config->NumYAxis);
if (IsAxisVisible)
{
ImPlotAxisFlags Flags = IsAssigned ? ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_AutoFit
: ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_AutoFit;
if (YAxisIndex > 0)
{
Flags |= ImPlotAxisFlags_Opposite;
}
ImPlot::SetupAxis(YAxis, IsAssigned || (Config->NumYAxis == 1) ? "" : "[drop here]", Flags);
//--------------------------------------------------------------------------------
// Set the Y axis limit for Events.
//--------------------------------------------------------------------------------
if (YMax > 0)
{
ImPlot::SetupAxisLimits(YAxis, 0, YMax, ImGuiCond_Always);
}
}
}
const ImPlotRange& PlotRange = ImPlot::GetCurrentPlot()->Axes[ImAxis_X1].Range;
const float TimeRange = PlotRange.Max - PlotRange.Min;
@@ -328,17 +383,18 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
Config->TimeRange = TimeRange;
}
const float Time = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0;
const UWorld* World = GetWorld();
const float Time = World != nullptr ? World->GetTimeSeconds() : 0.0;
//------------------------------------------------------------------
// Setup all the Z and Y axis limits. Must be done before calling
// Setup all the X axis limits. Must be done before calling
// ImPlot::GetPlotPos or ImPlot::GetPlotSize as it calls SetupLock()
//------------------------------------------------------------------
{
//--------------------------------------------------------------------------------
// Make the time axis move forward automatically, unless the user pauses or zoom.
//--------------------------------------------------------------------------------
if (FCogDebugPlot::Pause == false && ImGui::GetIO().MouseWheel == 0)
if (InTracker.Pause == false && ImGui::GetIO().MouseWheel == 0)
{
ImPlot::SetupAxisLimits(ImAxis_X1, Time - TimeRange, Time, ImGuiCond_Always);
}
@@ -347,23 +403,6 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
ImPlot::SetupAxisLimits(ImAxis_X1, Time - Config->TimeRange, Time, ImGuiCond_Always);
}
//--------------------------------------------------------------------------------
// Set the Y axis limit for Events.
//--------------------------------------------------------------------------------
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
{
if (PlotPtr == nullptr)
{ continue; }
if (PlotPtr->GraphIndex != PlotIndex)
{ continue; }
if (PlotPtr->IsEventPlot)
{
ImPlot::SetupAxisLimits(PlotPtr->YAxis, 0, PlotPtr->MaxRow + 2, ImGuiCond_Always);
}
}
}
const ImVec2 PlotMin = ImPlot::GetPlotPos();
@@ -373,23 +412,27 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
//----------------------------------------------------------------
// Pause the scrolling if the user drag inside
//----------------------------------------------------------------
const ImVec2 Mouse = ImGui::GetMousePos();
if (Mouse.x > PlotMin.x
&& Mouse.y > PlotMin.y
&& Mouse.x < PlotMax.x
&& Mouse.y < PlotMax.y
&& ImGui::GetDragDropPayload() == nullptr)
if (ImGui::IsWindowFocused())
{
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
if (FMath::Abs(Drag.x) > Config->DragPauseSensitivity)
const ImVec2 Mouse = ImGui::GetMousePos();
if (Mouse.x > PlotMin.x
&& Mouse.y > PlotMin.y
&& Mouse.x < PlotMax.x
&& Mouse.y < PlotMax.y
&& ImGui::GetDragDropPayload() == nullptr)
{
FCogDebugPlot::Pause = true;
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
if (FMath::Abs(Drag.x) > Config->DragPauseSensitivity)
{
InTracker.Pause = true;
}
}
}
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
FCogDebugPlot::Pause = false;
InTracker.Pause = false;
}
//---------------------------------------------------------------------------
@@ -408,7 +451,7 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
PlotDrawList->AddLine(ImVec2(ImGui::GetMousePos().x, PlotTop), ImVec2(ImGui::GetMousePos().x, TimeBarBottom), IM_COL32(128, 128, 128, 64));
}
if (Config->ShowTimeBarAtGameTime && FCogDebugPlot::Pause)
if (Config->ShowTimeBarAtGameTime && InTracker.Pause)
{
const float TimeBarX = ImPlot::PlotToPixels(Time, 0.0f).x;
PlotDrawList->AddLine(ImVec2(TimeBarX, PlotTop), ImVec2(TimeBarX, TimeBarBottom), IM_COL32(255, 255, 255, 64));
@@ -417,43 +460,46 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
}
//-----------------------------------------------------------
// Draw all the plots assigned to this row
// Draw all the plots assigned to this graph
//-----------------------------------------------------------
for (FCogDebugPlotEntry* PlotPtr : VisiblePlots)
for (FCogEngineConfig_Plots_GraphEntryInfo& Entry : GraphInfo.Entries)
{
if (PlotPtr == nullptr)
{ continue; }
FCogDebugTrack* Track = InTracker.FindTrack(Entry.Name);
if (Track == nullptr)
{
continue;
}
FCogDebugPlotEntry& Plot = *PlotPtr;
if (Plot.GraphIndex != PlotIndex)
{ continue; }
ImPlot::SetAxis(Plot.YAxis);
ImPlot::SetAxis(Entry.YAxis);
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString());
const auto Label = StringCast<ANSICHAR>(*Entry.Name.ToString());
//-------------------------------------------------------
// Plot Events
//-------------------------------------------------------
if (Plot.IsEventPlot)
switch (Track->Type)
{
RenderEvents(Plot, Label.Get(), PlotMin, PlotMax);
}
//-------------------------------------------------------
// Plot Values
//-------------------------------------------------------
else if (Plot.Values.empty() == false)
{
RenderValues(Plot, Label.Get());
case ECogDebugTrackType::Event:
{
RenderEvents(*static_cast<FCogDebugEventTrack*>(Track), Label.Get(), PlotMin, PlotMax);
break;
}
case ECogDebugTrackType::Value:
{
RenderValues(*static_cast<FCogDebugPlotTrack*>(Track), Label.Get());
break;
}
}
//-------------------------------------------------------
// Allow legend item labels to be drag and drop sources
//-------------------------------------------------------
if (ImPlot::BeginDragDropSourceItem(Label.Get()))
{
const auto EntryName = StringCast<ANSICHAR>(*Plot.Name.ToString());
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
ImGui::TextUnformatted(EntryName.Get());
ImPlot::EndDragDropSource();
@@ -467,10 +513,7 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
}
AssignToGraphAndAxis(InTracker, GetDroppedEntryName(Payload), GraphIndex, ImAxis_Y1);
}
ImPlot::EndDragDropTarget();
}
@@ -478,16 +521,14 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
//-------------------------------------------------------
// Allow each y-axis to be a drag and drop target
//-------------------------------------------------------
for (int y = ImAxis_Y1; y <= ImAxis_Y3; ++y)
for (int32 YAxisIndex = 0; YAxisIndex < Config->NumYAxis; ++YAxisIndex)
{
if (ImPlot::BeginDragDropTargetAxis(y))
const ImAxis YAxis = ImAxis_Y1 + YAxisIndex;
if (ImPlot::BeginDragDropTargetAxis(YAxis))
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, y);
}
AssignToGraphAndAxis(InTracker, GetDroppedEntryName(Payload), GraphIndex, YAxis);
}
ImPlot::EndDragDropTarget();
}
@@ -500,20 +541,21 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
}
AssignToGraphAndAxis(InTracker, GetDroppedEntryName(Payload), GraphIndex, ImAxis_Y1);
}
ImPlot::EndDragDropTarget();
}
ImPlot::EndPlot();
}
ImGui::PopID();
}
ImPlot::EndSubplots();
}
ImPlot::PopStyleVar();
if (PushPlotBgStyle)
{
ImPlot::PopStyleColor();
@@ -523,17 +565,22 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const
void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotTrack& Timeline, const char* Label) const
{
if (Timeline.Values.empty())
{
return;
}
//----------------------------------------------------------------
// Value at cursor tooltip
//----------------------------------------------------------------
if (Config->ShowValueAtCursor && ImPlot::IsPlotHovered())
{
float Value;
if (Entry.FindValue(ImPlot::GetPlotMousePos().x, Value))
if (Timeline.FindValue(ImPlot::GetPlotMousePos().x, Value))
{
if (FCogWindowWidgets::BeginTableTooltip())
if (FCogWidgets::BeginTableTooltip())
{
if (ImGui::BeginTable("Params", 2, ImGuiTableFlags_Borders))
{
@@ -544,31 +591,31 @@ void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char*
ImGui::Text("%0.2f", Value);
ImGui::EndTable();
}
FCogWindowWidgets::EndTableTooltip();
FCogWidgets::EndTableTooltip();
}
}
}
if (Entry.ShowValuesMarkers)
if (Timeline.ShowValuesMarkers)
{
ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);
}
ImPlot::PlotLine(Label, &Entry.Values[0].x, &Entry.Values[0].y, Entry.Values.size(), ImPlotLineFlags_None, Entry.ValueOffset, 2 * sizeof(float));
ImPlot::PlotLine(Label, &Timeline.Values[0].x, &Timeline.Values[0].y, Timeline.Values.size(), ImPlotLineFlags_None, Timeline.ValueOffset, 2 * sizeof(float));
if (ImPlot::BeginLegendPopup(Label))
{
if (ImGui::Button("Clear"))
{
Entry.Clear();
Timeline.Clear();
}
ImGui::Checkbox("Show Markers", &Entry.ShowValuesMarkers);
ImGui::Checkbox("Show Markers", &Timeline.ShowValuesMarkers);
ImPlot::EndLegendPopup();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const
void FCogEngineWindow_Plots::RenderEvents(FCogDebugEventTrack& InTrack, const char* InLabel, const ImVec2& InPlotMin, const ImVec2& InPlotMax) const
{
const ImVec2 Mouse = ImGui::GetMousePos();
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
@@ -581,15 +628,20 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
ImVector<ImVec2> DummyData;
DummyData.push_back(ImVec2(0, 0));
DummyData.push_back(ImVec2(0, 8));
ImPlot::PlotLine(Label, &DummyData[0].x, &DummyData[0].y, DummyData.size(), Entry.ValueOffset, 2 * sizeof(float));
ImPlot::PlotLine(InLabel, &DummyData[0].x, &DummyData[0].y, DummyData.size(), InTrack.EventOffset, 2 * sizeof(float));
const FCogDebugPlotEvent* HoveredEvent = nullptr;
const FCogDebugEvent* HoveredEvent = nullptr;
for (const FCogDebugPlotEvent& Event : Entry.Events)
for (const FCogDebugEvent& Event : InTrack.Events)
{
const ImVec2 PosBot = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.8f));
const ImVec2 PosTop = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.2f));
const ImVec2 PosMid(PosBot.x, PosBot.y + (PosTop.y - PosBot.y) * 0.5f);
const ImVec2 PosStartBot = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.8f));
const ImVec2 PosStartTop = ImPlot::PlotToPixels(ImPlotPoint(Event.StartTime, Event.Row + 0.2f));
const ImVec2 PosMid(PosStartBot.x, PosStartBot.y + (PosStartTop.y - PosStartBot.y) * 0.5f);
const ImVec2 PosEnd = ImPlot::PlotToPixels(ImPlotPoint(Event.GetActualEndTime(*GetWorld()), 0));
// Clipping
if (PosStartBot.x > InPlotMax.x || PosEnd.x < InPlotMin.x)
{ continue; }
const bool IsInstant = Event.StartTime == Event.EndTime;
if (IsInstant)
@@ -606,15 +658,13 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
}
else
{
const float ActualEndTime = Event.GetActualEndTime(Entry);
const ImVec2 PosEnd = ImPlot::PlotToPixels(ImPlotPoint(ActualEndTime, 0));
const ImVec2 Min = ImVec2(PosBot.x, PosBot.y);
const ImVec2 Max = ImVec2(PosEnd.x, PosTop.y);
const ImVec2 Min = ImVec2(PosStartBot.x, PosStartBot.y);
const ImVec2 Max = ImVec2(PosEnd.x, PosStartTop.y);
const ImDrawFlags Flags = Event.EndTime == 0.0f ? ImDrawFlags_RoundCornersLeft : ImDrawFlags_RoundCornersAll;
PlotDrawList->AddRect(Min, Max, Event.BorderColor, 6.0f, Flags);
PlotDrawList->AddRectFilled(Min, Max, Event.FillColor, 6.0f, Flags);
PlotDrawList->PushClipRect(ImMax(Min, PlotMin), ImMin(Max, PlotMax));
PlotDrawList->PushClipRect(ImMax(Min, InPlotMin), ImMin(Max, InPlotMax));
PlotDrawList->AddText(ImVec2(PosMid.x + 5, PosMid.y - 7), IM_COL32(255, 255, 255, 255), TCHAR_TO_ANSI(*Event.DisplayName));
PlotDrawList->PopClipRect();
@@ -630,22 +680,22 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
//-------------------------------------------------------
//char Buffer[64];
//ImFormatString(Buffer, 64, "%0.1f %0.1f", Mouse.x, Mouse.y);
//PlotDrawList->AddText(ImVec2(PlotMin.x + 50, PlotMin.y + 100), IM_COL32(255, 255, 255, 255), Buffer);
//PlotDrawList->AddText(ImVec2(InPlotMin.x + 50, InPlotMin.y + 100), IM_COL32(255, 255, 255, 255), Buffer);
//-------------------------------------------------------
// Hovered event tooltip
//-------------------------------------------------------
RenderEventTooltip(HoveredEvent, Entry);
RenderEventTooltip(HoveredEvent, InTrack);
ImPlot::PopPlotClipRect();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry)
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugEvent* HoveredEvent, const FCogDebugTrack& Entry) const
{
if (ImPlot::IsPlotHovered() && HoveredEvent != nullptr)
{
if (FCogWindowWidgets::BeginTableTooltip())
if (FCogWidgets::BeginTableTooltip())
{
if (ImGui::BeginTable("Params", 2, ImGuiTableFlags_Borders))
{
@@ -672,8 +722,8 @@ void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* Hovere
//------------------------
if (HoveredEvent->EndTime != HoveredEvent->StartTime)
{
const float ActualEndTime = HoveredEvent->GetActualEndTime(Entry);
const uint64 ActualEndFrame = HoveredEvent->GetActualEndFrame(Entry);
const float ActualEndTime = HoveredEvent->GetActualEndTime(*GetWorld());
const uint64 ActualEndFrame = HoveredEvent->GetActualEndFrame();
ImGui::TableNextRow();
ImGui::TableNextColumn();
@@ -686,9 +736,9 @@ void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* Hovere
ImGui::Text("Frames");
ImGui::TableNextColumn();
ImGui::Text("%d [%d-%d]",
(int32)(ActualEndFrame - HoveredEvent->StartFrame),
(int32)(HoveredEvent->StartFrame % 1000),
(int32)(ActualEndFrame % 1000));
static_cast<int32>(ActualEndFrame - HoveredEvent->StartFrame),
static_cast<int32>(HoveredEvent->StartFrame % 1000),
static_cast<int32>(ActualEndFrame % 1000));
}
else
{
@@ -696,13 +746,13 @@ void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* Hovere
ImGui::TableNextColumn();
ImGui::Text("Frame");
ImGui::TableNextColumn();
ImGui::Text("%d", (int32)(HoveredEvent->StartFrame % 1000));
ImGui::Text("%d", static_cast<int32>(HoveredEvent->StartFrame % 1000));
}
//------------------------
// Params
//------------------------
for (FCogDebugPlotEventParams Param : HoveredEvent->Params)
for (FCogDebugEventParams Param : HoveredEvent->Params)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
@@ -712,7 +762,58 @@ void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* Hovere
}
ImGui::EndTable();
}
FCogWindowWidgets::EndTableTooltip();
FCogWidgets::EndTableTooltip();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
FName FCogEngineWindow_Plots::GetDroppedEntryName(const ImGuiPayload* Payload)
{
return FName(static_cast<const char*>(Payload->Data));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::AssignToGraphAndAxis(FCogDebugTracker& InTracker, const FName InName, const int32 InGraphIndex, const ImAxis InYAxis)
{
UnassignToGraphAndAxis(InTracker, InName);
FCogDebugTrack* History = InTracker.FindTrack(InName);
if (History == nullptr)
{ return; }
History->GraphIndex = InGraphIndex;
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[InGraphIndex];
FCogEngineConfig_Plots_GraphEntryInfo* CorrespondingEntry = GraphInfo.Entries.FindByPredicate(
[InName](const auto& InEntry) { return InEntry.Name == InName; });
if (CorrespondingEntry == nullptr)
{
GraphInfo.Entries.Add({InName, InYAxis});
}
else
{
CorrespondingEntry->YAxis = InYAxis;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::UnassignToGraphAndAxis(FCogDebugTracker& InTracker, const FName InName)
{
const FCogDebugTrack* History = InTracker.FindTrack(InName);
if (History == nullptr)
{ return; }
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[History->GraphIndex];
const int32 Index = GraphInfo.Entries.IndexOfByPredicate([InName](const auto& InEntry) { return InEntry.Name == InName; });
if (Index != INDEX_NONE)
{
GraphInfo.Entries.RemoveAt(Index);
}
}
@@ -1,7 +1,7 @@
#include "CogEngineWindow_Scalability.h"
#include "imgui.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "Scalability.h"
@@ -22,7 +22,7 @@ void FCogEngineWindow_Scalability::RenderContent()
Scalability::FQualityLevels Levels = Scalability::GetQualityLevels();
const FString CurrentQualityName = Scalability::GetQualityLevelText(Levels.GetMinQualityLevel(), SCALABILITY_NUM_LEVELS).ToString();
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("Scalability", TCHAR_TO_ANSI(*CurrentQualityName)))
{
for (int32 i = 0; i < SCALABILITY_NUM_LEVELS; ++i)
@@ -45,37 +45,37 @@ void FCogEngineWindow_Scalability::RenderContent()
bool Modified = false;
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderFloat("Resolution", &Levels.ResolutionQuality, 10.0f, 100.0f, "%0.f");
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("View Distance", &Levels.ViewDistanceQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Anti Aliasing", &Levels.AntiAliasingQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Shadow", &Levels.ShadowQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Global Illumination", &Levels.GlobalIlluminationQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Reflection", &Levels.ReflectionQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Post Process", &Levels.PostProcessQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Texture", &Levels.TextureQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Effects", &Levels.EffectsQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Foliage", &Levels.FoliageQuality, 0, SCALABILITY_NUM_LEVELS - 1);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
Modified |= ImGui::SliderInt("Shading", &Levels.ShadingQuality, 0, SCALABILITY_NUM_LEVELS - 1);
if (Modified)
@@ -6,9 +6,10 @@
#include "CogEngineWindow_ImGui.h"
#include "CogImguiHelper.h"
#include "CogImguiInputHelper.h"
#include "CogWindowConsoleCommandManager.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "CogConsoleCommandManager.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "CogWindow_Settings.h"
#include "Components/PrimitiveComponent.h"
#include "EngineUtils.h"
#include "GameFramework/Character.h"
@@ -25,17 +26,21 @@ void FCogEngineWindow_Selection::Initialize()
bHasMenu = true;
bHasWidget = true;
ActorClasses = { AActor::StaticClass(), ACharacter::StaticClass() };
bIsWidgetVisible = true;
Config = GetConfig<UCogEngineConfig_Selection>();
FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand(
GetOwner()->AddShortcut(Config.Get(), &UCogEngineConfig_Selection::Shortcut_ToggleSelection).BindLambda([this] (){ GetOwner()->SetActivateSelectionMode(!GetOwner()->GetActivateSelectionMode()); });
Asset = GetAsset<UCogEngineDataAsset>();
FCogConsoleCommandManager::RegisterWorldConsoleCommand(
*ToggleSelectionModeCommand,
TEXT("Toggle the actor selection mode"),
GetWorld(),
FCogWindowConsoleCommandDelegate::CreateLambda([this](const TArray<FString>& InArgs, UWorld* InWorld)
{
ToggleSelectionMode();
GetOwner()->SetActivateSelectionMode(!GetOwner()->GetActivateSelectionMode());
}));
TryReapplySelection();
@@ -57,19 +62,14 @@ void FCogEngineWindow_Selection::Shutdown()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::ResetConfig()
{
Super::ResetConfig();
Config->Reset();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::PreSaveConfig()
{
Super::PreSaveConfig();
if (Config == nullptr)
{ return; }
Config->SelectionName = GetNameSafe(GetSelection());
}
@@ -113,78 +113,44 @@ void FCogEngineWindow_Selection::TryReapplySelection() const
TSubclassOf<AActor> FCogEngineWindow_Selection::GetSelectedActorClass() const
{
TSubclassOf<AActor> SelectedClass = AActor::StaticClass();
if (ActorClasses.IsValidIndex(Config->SelectedClassIndex))
const TArray<TSubclassOf<AActor>>& SelectionFilters = GetSelectionFilters();
if (SelectionFilters.IsValidIndex(Config->SelectedClassIndex))
{
SelectedClass = ActorClasses[Config->SelectedClassIndex];
SelectedClass = SelectionFilters[Config->SelectedClassIndex];
}
return SelectedClass;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::ToggleSelectionMode()
{
if (bSelectionModeActive)
{
DeactivateSelectionMode();
}
else
{
ActivateSelectionMode();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::ActivateSelectionMode()
{
bSelectionModeActive = true;
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetContext().GetEnableInput();
GetOwner()->GetContext().SetEnableInput(true);
GetOwner()->SetActivateSelectionMode(true);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::HackWaitInputRelease()
{
WaitInputReleased = 1;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::DeactivateSelectionMode()
{
bSelectionModeActive = false;
//--------------------------------------------------------------------------------------------
// We can enter selection mode by a command, and ImGui might not have the input focus
// When in selection mode we need ImGui to have the input focus
// When leaving selection mode we want to leave it as it was before
//--------------------------------------------------------------------------------------------
GetOwner()->GetContext().SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
GetOwner()->SetActivateSelectionMode(false);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::RenderTick(float DeltaTime)
{
Super::RenderTick(DeltaTime);
if (FCogDebug::GetSelection() == nullptr)
if (GetSelection() == nullptr)
{
SetGlobalSelection(GetLocalPlayerPawn());
}
if (bSelectionModeActive)
if (GetOwner()->GetActivateSelectionMode())
{
TickSelectionMode();
if (TickSelectionMode() == false)
{
GetOwner()->SetActivateSelectionMode(false);
}
}
if (const AActor* Actor = GetSelection())
{
if (Actor != GetLocalPlayerPawn())
{
FCogWindowWidgets::ActorFrame(*Actor);
FCogWidgets::ActorFrame(*Actor);
}
}
}
@@ -198,7 +164,7 @@ void FCogEngineWindow_Selection::RenderContent()
{
if (ImGui::MenuItem("Pick"))
{
ActivateSelectionMode();
GetOwner()->SetActivateSelectionMode(true);
//HackWaitInputRelease();
}
@@ -228,7 +194,7 @@ void FCogEngineWindow_Selection::RenderContent()
bool FCogEngineWindow_Selection::DrawSelectionCombo()
{
AActor* NewSelection = nullptr;
const bool result = FCogWindowWidgets::ActorsListWithFilters(NewSelection, *GetWorld(), ActorClasses, Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn());
const bool result = FCogWidgets::ActorsListWithFilters(NewSelection, *GetWorld(), GetSelectionFilters(), Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn());
if (result)
{
SetGlobalSelection(NewSelection);
@@ -238,32 +204,24 @@ bool FCogEngineWindow_Selection::DrawSelectionCombo()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::TickSelectionMode()
bool FCogEngineWindow_Selection::TickSelectionMode()
{
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
{
DeactivateSelectionMode();
return;
}
{ return false; }
APlayerController* PlayerController = GetLocalPlayerController();
if (PlayerController == nullptr)
{
DeactivateSelectionMode();
return;
}
{ return false; }
ImGuiViewport* Viewport = ImGui::GetMainViewport();
if (Viewport == nullptr)
{
return;
}
{ return false; }
const ImVec2 ViewportPos = Viewport->Pos;
const ImVec2 ViewportSize = Viewport->Size;
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
DrawList->AddRect(ViewportPos, ViewportPos + ViewportSize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
FCogWindowWidgets::AddTextWithShadow(DrawList, ViewportPos + ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
FCogWidgets::AddTextWithShadow(DrawList, ViewportPos + ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
TSubclassOf<AActor> SelectedActorClass = GetSelectedActorClass();
@@ -283,12 +241,12 @@ void FCogEngineWindow_Selection::TickSelectionMode()
// Prioritize another actor than the selected actor unless we only touch the selected actor.
//--------------------------------------------------------------------------------------------------------
TArray<AActor*> IgnoreList;
IgnoreList.Add(FCogDebug::GetSelection());
IgnoreList.Add(GetSelection());
FHitResult HitResult;
for (int i = 0; i < 2; ++i)
{
if (UKismetSystemLibrary::LineTraceSingle(GetWorld(), WorldOrigin, WorldOrigin + WorldDirection * 10000, TraceType, false, IgnoreList, EDrawDebugTrace::None, HitResult, true))
if (UKismetSystemLibrary::LineTraceSingle(GetWorld(), WorldOrigin, WorldOrigin + WorldDirection * 10000, GetSelectionTraceChannel(), false, IgnoreList, EDrawDebugTrace::None, HitResult, true))
{
if (SelectedActorClass == nullptr || HitResult.GetActor()->GetClass()->IsChildOf(SelectedActorClass))
{
@@ -306,10 +264,10 @@ void FCogEngineWindow_Selection::TickSelectionMode()
if (HoveredActor != nullptr)
{
FCogWindowWidgets::ActorFrame(*HoveredActor);
FCogWidgets::ActorFrame(*HoveredActor);
}
if (bSelectionModeActive)
if (GetOwner()->GetActivateSelectionMode())
{
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
@@ -320,7 +278,7 @@ void FCogEngineWindow_Selection::TickSelectionMode()
SetGlobalSelection(HoveredActor);
}
DeactivateSelectionMode();
GetOwner()->SetActivateSelectionMode(false);
}
else
{
@@ -328,80 +286,41 @@ void FCogEngineWindow_Selection::TickSelectionMode()
}
}
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth)
void FCogEngineWindow_Selection::RenderMainMenuWidget()
{
switch (SubWidgetIndex)
ImGui::PushStyleVarX(ImGuiStyleVar_ItemSpacing, 0);
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
if (FCogWidgets::PickButton("##Pick", ImVec2(ImGui::GetFrameHeight(), ImGui::GetFrameHeight())))
{
case 0: return FCogWindowWidgets::GetFontWidth() * 6;
case 1: return FMath::Min(FMath::Max(MaxWidth, FCogWindowWidgets::GetFontWidth() * 10), FCogWindowWidgets::GetFontWidth() * 30);
case 2: return FCogWindowWidgets::GetFontWidth() * 3;
GetOwner()->SetActivateSelectionMode(true);
HackWaitInputRelease();
}
return -1.0f;
}
ImGui::PopStyleColor();
ImGui::PopStyleVar();
RenderPickButtonTooltip();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
AActor* NewSelection = nullptr;
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, float Width)
{
//-----------------------------------
// Pick Button
//-----------------------------------
if (SubWidgetIndex == 0)
//TODO: Could be replaced by a BeginMenu
if (FCogWidgets::MenuActorsCombo(
"MenuActorSelection",
NewSelection,
*GetWorld(),
GetSelectionFilters(),
Config->SelectedClassIndex,
&Filter,
GetLocalPlayerPawn(),
[this](AActor& Actor) { RenderActorContextMenu(Actor); }))
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
if (ImGui::Button("Pick", ImVec2(Width, 0)))
{
ActivateSelectionMode();
HackWaitInputRelease();
}
RenderPickButtonTooltip();
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(2);
}
else if (SubWidgetIndex == 1)
{
ImGui::SetNextItemWidth(Width);
AActor* NewSelection = nullptr;
if (FCogWindowWidgets::MenuActorsCombo(
"MenuActorSelection",
NewSelection,
*GetWorld(),
ActorClasses,
Config->SelectedClassIndex,
&Filter,
GetLocalPlayerPawn(),
[this](AActor& Actor) { RenderActorContextMenu(Actor); }))
{
SetGlobalSelection(NewSelection);
}
}
else if (SubWidgetIndex == 2)
{
//-----------------------------------
// Reset Button
//-----------------------------------
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
if (ImGui::Button("X", ImVec2(Width, 0)))
{
SetGlobalSelection(nullptr);
ImGui::CloseCurrentPopup();
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Reset the selection to the controlled actor.");
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(1);
}
SetGlobalSelection(NewSelection);
}
}
@@ -414,15 +333,38 @@ void FCogEngineWindow_Selection::RenderActorContextMenu(AActor& Actor)
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::SetGlobalSelection(AActor* Value) const
{
FCogDebug::SetSelection(GetWorld(), Value);
FCogDebug::SetSelection(Value);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::RenderPickButtonTooltip()
{
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
if (FCogWidgets::BeginItemTooltipWrappedText())
{
const FString Shortcut = FCogImguiInputHelper::CommandToString(*GetWorld(), ToggleSelectionModeCommand);
ImGui::SetTooltip("Enter picking mode to pick an actor on screen. %s", TCHAR_TO_ANSI(*Shortcut));
ImGui::Text("Enter selection mode to select an actor on screen. Change which actor type is selectable by clicking the selection combobox\n");
ImGui::Spacing();
ImGui::Separator();
FCogWidgets::TextOfAllInputChordsOfConfig(*Config.Get());
FCogWidgets::EndItemTooltipWrappedText();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
const TArray<TSubclassOf<AActor>>& FCogEngineWindow_Selection::GetSelectionFilters() const
{
if (Asset != nullptr)
{ return Asset->SelectionFilters; }
static TArray<TSubclassOf<AActor>> SelectionFilters = { ACharacter::StaticClass(), AActor::StaticClass(), AGameModeBase::StaticClass(), AGameStateBase::StaticClass() };
return SelectionFilters;
}
//--------------------------------------------------------------------------------------------------------------------------
ETraceTypeQuery FCogEngineWindow_Selection::GetSelectionTraceChannel() const
{
if (Asset != nullptr)
{ return Asset->SelectionTraceChannel; }
return UEngineTypes::ConvertToTraceType(ECC_Pawn);
}
@@ -1,7 +1,7 @@
#include "CogEngineWindow_Skeleton.h"
#include "CogDebug.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "Components/SkeletalMeshComponent.h"
#include "DrawDebugHelpers.h"
#include "Engine/SkeletalMesh.h"
@@ -111,12 +111,12 @@ void FCogEngineWindow_Skeleton::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::SearchBar(Filter);
FCogWidgets::SearchBar("##Filter", Filter);
ImGui::EndMenuBar();
}
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, FCogWindowWidgets::GetFontWidth());
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, FCogWidgets::GetFontWidth());
HoveredBoneIndex = INDEX_NONE;
RenderBoneEntry(0, false);
@@ -207,7 +207,7 @@ void FCogEngineWindow_Skeleton::RenderBoneEntry(int32 BoneIndex, bool OpenAllChi
// Checkbox
//------------------------
ImGui::SameLine();
FCogWindowWidgets::PushStyleCompact();
FCogWidgets::PushStyleCompact();
if (ImGui::Checkbox("##Visible", &BoneInfo.ShowBone))
{
if (IsControlDown)
@@ -223,10 +223,10 @@ void FCogEngineWindow_Skeleton::RenderBoneEntry(int32 BoneIndex, bool OpenAllChi
BoneInfo.ShowTrajectory = false;
}
}
FCogWindowWidgets::PopStyleCompact();
FCogWidgets::PopStyleCompact();
const bool HasCustomVisiblity = BoneInfo.ShowName || BoneInfo.ShowAxes || BoneInfo.ShowLocalVelocity || BoneInfo.ShowTrajectory;
if (HasCustomVisiblity)
const bool HasCustomVisibility = BoneInfo.ShowName || BoneInfo.ShowAxes || BoneInfo.ShowLocalVelocity || BoneInfo.ShowTrajectory;
if (HasCustomVisibility)
{
BoneInfo.ShowBone = true;
}
@@ -235,7 +235,7 @@ void FCogEngineWindow_Skeleton::RenderBoneEntry(int32 BoneIndex, bool OpenAllChi
// Name
//------------------------
ImGui::SameLine();
ImVec4 NameColor = HasCustomVisiblity ? ImVec4(1.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
ImVec4 NameColor = HasCustomVisibility ? ImVec4(1.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
ImGui::TextColored(NameColor, "%s", BoneName.Get());
}
@@ -52,7 +52,7 @@ void FCogEngineWindow_Slate::RenderContent()
void FCogEngineWindow_Slate::RenderUser(FSlateUser& User)
{
if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders))
if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable))
{
constexpr ImVec4 LabelColor(1.0f, 1.0f, 1.0f, 0.5f);
@@ -3,15 +3,7 @@
#include "CogEngineDataAsset.h"
#include "CogEngineReplicator.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Spawns::Initialize()
{
Super::Initialize();
Asset = GetAsset<UCogEngineDataAsset>();
}
#include "CogWidgets.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Spawns::RenderHelp()
@@ -23,6 +15,14 @@ void FCogEngineWindow_Spawns::RenderHelp()
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Spawns::Initialize()
{
Super::Initialize();
Asset = GetAsset<UCogEngineDataAsset>();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Spawns::RenderContent()
{
@@ -47,24 +47,25 @@ void FCogEngineWindow_Spawns::RenderContent()
return;
}
int32 GroupIndex = 0;
for (const FCogEngineSpawnGroup& SpawnGroup : Asset->SpawnGroups)
{
RenderSpawnGroup(*Replicator, SpawnGroup);
RenderSpawnGroup(*Replicator, SpawnGroup, GroupIndex);
GroupIndex++;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Spawns::RenderSpawnGroup(ACogEngineReplicator& Replicator, const FCogEngineSpawnGroup& SpawnGroup)
void FCogEngineWindow_Spawns::RenderSpawnGroup(ACogEngineReplicator& Replicator, const FCogEngineSpawnGroup& SpawnGroup, int32 GroupIndex)
{
if (FCogWindowWidgets::DarkCollapsingHeader(TCHAR_TO_ANSI(*SpawnGroup.Name), ImGuiTreeNodeFlags_DefaultOpen))
if (FCogWidgets::DarkCollapsingHeader(TCHAR_TO_ANSI(*SpawnGroup.Name), ImGuiTreeNodeFlags_DefaultOpen))
{
int32 GroupIndex = 0;
ImGui::PushID(GroupIndex);
const bool PushColor = (SpawnGroup.Color != FColor::Transparent);
if (PushColor)
{
FCogWindowWidgets::PushBackColor(FCogImguiHelper::ToImVec4(SpawnGroup.Color));
FCogWidgets::PushBackColor(FCogImguiHelper::ToImVec4(SpawnGroup.Color));
}
static int32 SelectedAssetIndex = -1;
@@ -82,11 +83,10 @@ void FCogEngineWindow_Spawns::RenderSpawnGroup(ACogEngineReplicator& Replicator,
if (PushColor)
{
FCogWindowWidgets::PopBackColor();
FCogWidgets::PopBackColor();
}
ImGui::PopID();
GroupIndex++;
}
}
@@ -95,7 +95,7 @@ bool FCogEngineWindow_Spawns::RenderSpawnAsset(ACogEngineReplicator& Replicator,
{
bool IsPressed = false;
ImGui::PushStyleColor(ImGuiCol_Button, IsLastSelected ? ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive) : ImGui::GetStyleColorVec4(ImGuiCol_Button));
//ImGui::PushStyleColor(ImGuiCol_Button, IsLastSelected ? ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive) : ImGui::GetStyleColorVec4(ImGuiCol_Button));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
FString EntryName;
@@ -115,7 +115,7 @@ bool FCogEngineWindow_Spawns::RenderSpawnAsset(ACogEngineReplicator& Replicator,
}
ImGui::PopStyleVar(1);
ImGui::PopStyleColor(1);
//ImGui::PopStyleColor(1);
return IsPressed;
}
@@ -1,6 +1,7 @@
#include "CogEngineWindow_Stats.h"
#include "CogWindowWidgets.h"
#include "CogImguiHelper.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "Engine/NetConnection.h"
#include "Engine/NetDriver.h"
@@ -8,9 +9,7 @@
#include "GameFramework/PlayerController.h"
#include "GameFramework/PlayerState.h"
ImVec4 StatRedColor(1.0f, 0.4f, 0.3f, 1.0f);
ImVec4 StatOrangeColor(1.0f, 0.7f, 0.4f, 1.0f);
ImVec4 StatGreenColor(0.5f, 1.0f, 0.6f, 1.0f);
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::Initialize()
@@ -18,6 +17,9 @@ void FCogEngineWindow_Stats::Initialize()
Super::Initialize();
bHasWidget = true;
bIsWidgetVisible = true;
Config = GetConfig<UCogEngineWindowConfig_Stats>();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -28,6 +30,15 @@ void FCogEngineWindow_Stats::RenderHelp()
);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderContextMenu()
{
Config->RenderAllConfigs();
ImGui::Separator();
FCogWindow::RenderContextMenu();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderContent()
{
@@ -36,7 +47,7 @@ void FCogEngineWindow_Stats::RenderContent()
extern ENGINE_API float GAverageFPS;
ImGui::Text("FPS ");
ImGui::SameLine();
ImGui::TextColored(GetFpsColor(GAverageFPS), "%0.0f", GAverageFPS);
ImGui::TextColored(Config->GetFpsColor(GAverageFPS), "%0.0f", GAverageFPS);
if (const APlayerController* PlayerController = GetLocalPlayerController())
{
@@ -45,7 +56,7 @@ void FCogEngineWindow_Stats::RenderContent()
const float Ping = PlayerState->GetPingInMilliseconds();
ImGui::Text("Ping ");
ImGui::SameLine();
ImGui::TextColored(GetPingColor(Ping), "%0.0fms", Ping);
ImGui::TextColored(Config->GetPingColor(Ping), "%0.0fms", Ping);
}
if (const UNetConnection* Connection = PlayerController->GetNetConnection())
@@ -53,176 +64,183 @@ void FCogEngineWindow_Stats::RenderContent()
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
ImGui::Text("Packet Loss Out ");
ImGui::SameLine();
ImGui::TextColored(GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
ImGui::TextColored(Config->GetPacketLossColor(OutPacketLost), "%0.0f%%", OutPacketLost);
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
ImGui::Text("Packet Loss In ");
ImGui::SameLine();
ImGui::TextColored(GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
ImGui::TextColored(Config->GetPacketLossColor(InPacketLost), "%0.0f%%", InPacketLost);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogEngineWindow_Stats::GetMainMenuWidgetWidth(const int32 SubWidgetIndex, float MaxWidth)
void FCogEngineWindow_Stats::RenderMainMenuWidget()
{
const APlayerController* PlayerController = GetLocalPlayerController();
RenderMainMenuWidgetFrameRate();
const UNetConnection* Connection = PlayerController != nullptr ? PlayerController->GetNetConnection() : nullptr;
switch (SubWidgetIndex)
if (Connection != nullptr)
{
case 0: return FCogWindowWidgets::GetFontWidth() * 8;
case 1: return Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f;
case 2: return Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f;
}
return -1;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderMainMenuWidget(const int32 SubWidgetIndex, const float Width)
{
switch (SubWidgetIndex)
{
case 0: RenderMainMenuWidgetFramerate(Width); break;
case 1: RenderMainMenuWidgetPing(Width); break;
case 2: RenderMainMenuWidgetPacketLoss(Width); break;
RenderMainMenuWidgetPing();
RenderMainMenuWidgetPacketLoss();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderMainMenuWidgetFramerate(const float Width)
void FCogEngineWindow_Stats::RenderMainMenuWidgetFrameRate()
{
extern ENGINE_API float GAverageFPS;
const int32 Fps = (int32)GAverageFPS;
const int32 Fps = static_cast<int32>(GAverageFPS);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::PushStyleColor(ImGuiCol_Text, GetFpsColor(Fps));
ImGui::PushStyleColor(ImGuiCol_Text, Config->GetFpsColor(Fps));
const bool Open = ImGui::BeginMenu(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dfps###FrameRateButton"), Fps)));
const float Width = ImGui::GetItemRectSize().x;
ImGui::PopStyleColor(1);
if (ImGui::Button(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dfps###FramerateButton"), Fps)), ImVec2(Width, 0.0f)))
if (ImGui::BeginPopupContextItem())
{
ImGui::OpenPopup("FrameratePopup");
Config->RenderColorConfig();
Config->RenderFrameRateConfig();
Super::RenderContextMenu();
ImGui::EndPopup();
}
ImGui::PopStyleColor(2);
ImGui::PopStyleVar(2);
ImGui::SetItemTooltip("Framerate");
if (ImGui::BeginPopup("FrameratePopup"))
if (Open == false)
{
ImGui::Text("Fps");
ImGui::SameLine();
int32 MaxFps = GEngine->GetMaxFPS();
TArray<int32> Values{ 0, 10, 20, 30, 60, 120 };
if (FCogWindowWidgets::MultiChoiceButtonsInt(Values, MaxFps, ImVec2(3.5f * FCogWindowWidgets::GetFontWidth(), 0)))
ImGui::SetItemTooltip("Frame Rate");
}
if (Open)
{
const int32 MaxFps = GEngine->GetMaxFPS();
for (int32 i = 0; i < Config->FrameRates.Num(); ++i)
{
GEngine->SetMaxFPS(MaxFps);
ImGui::PushID(i);
const float Value = Config->FrameRates[i];
const auto ValueText = StringCast<ANSICHAR>(*FCogWidgets::FormatSmallFloat(Value));
if (ImGui::Selectable(ValueText.Get(), Value == MaxFps, ImGuiSelectableFlags_None, ImVec2(Width, 0)))
{
GEngine->SetMaxFPS(Value);
}
ImGui::PopID();
}
ImGui::EndPopup();
ImGui::EndMenu();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderMainMenuWidgetPing(const float Width)
void FCogEngineWindow_Stats::RenderMainMenuWidgetPing()
{
const APlayerController* PlayerController = GetLocalPlayerController();
const APlayerState* PlayerState = PlayerController != nullptr ? PlayerController->GetPlayerState<APlayerState>() : nullptr;
if (PlayerState == nullptr)
{ return; }
const int32 Ping = static_cast<int32>(PlayerState->GetPingInMilliseconds());
ImGui::PushStyleColor(ImGuiCol_Text, Config->GetPingColor(Ping));
const bool Open = ImGui::BeginMenu(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dms###PingButton"), Ping)));
const float Width = ImGui::GetItemRectSize().x;
ImGui::PopStyleColor(1);
if (ImGui::BeginPopupContextItem())
{
return;
Config->RenderColorConfig();
Config->RenderPingConfig();
Super::RenderContextMenu();
ImGui::EndPopup();
}
const float Ping = PlayerState->GetPingInMilliseconds();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::PushStyleColor(ImGuiCol_Text, GetPingColor(Ping));
if (ImGui::Button(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dms###PingButton"), (int32)Ping)), ImVec2(Width, 0.0f)))
if (Open == false)
{
ImGui::OpenPopup("PingPopup");
ImGui::SetItemTooltip("Ping");
}
ImGui::PopStyleColor(2);
ImGui::PopStyleVar(2);
ImGui::SetItemTooltip("Ping");
#if DO_ENABLE_NET_TEST
if (ImGui::BeginPopup("PingPopup"))
if (Open)
{
FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(GetWorld());
if (WorldContext.ActiveNetDrivers.Num() > 0)
{
ImGui::Text("Ping");
ImGui::SameLine();
const FNamedNetDriver* SelectedNetDriver = &WorldContext.ActiveNetDrivers[0];
FPacketSimulationSettings Settings = SelectedNetDriver->NetDriver->PacketSimulationSettings;
TArray<int32> Values{ 0, 50, 100, 200, 500, 1000 };
if (FCogWindowWidgets::MultiChoiceButtonsInt(Values, Settings.PktIncomingLagMin, ImVec2(4.5f * FCogWindowWidgets::GetFontWidth(), 0)))
for (int32 i = 0; i < Config->Pings.Num(); ++i)
{
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
ImGui::PushID(i);
const float Value = Config->Pings[i];
const auto ValueText = StringCast<ANSICHAR>(*FCogWidgets::FormatSmallFloat(Value));
if (ImGui::Selectable(ValueText.Get(), Value == Settings.PktIncomingLagMin, ImGuiSelectableFlags_None, ImVec2(Width, 0)))
{
Settings.PktIncomingLagMin = Value;
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
}
ImGui::PopID();
}
}
ImGui::EndPopup();
ImGui::EndMenu();
}
#endif //DO_ENABLE_NET_TEST
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Stats::RenderMainMenuWidgetPacketLoss(const float Width)
void FCogEngineWindow_Stats::RenderMainMenuWidgetPacketLoss()
{
const APlayerController* PlayerController = GetLocalPlayerController();
const UNetConnection* Connection = PlayerController != nullptr ? PlayerController->GetNetConnection() : nullptr;
if (Connection == nullptr)
{
return;
}
{ return; }
const float OutPacketLost = Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f;
const float InPacketLost = Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f;
const float TotalPacketLost = (OutPacketLost + InPacketLost) / 2;
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::PushStyleColor(ImGuiCol_Text, GetPacketLossColor(TotalPacketLost));
ImGui::PushStyleColor(ImGuiCol_Text, Config->GetPacketLossColor(TotalPacketLost));
const bool Open = ImGui::BeginMenu(TCHAR_TO_ANSI(*FString::Printf(TEXT("%2d%% ###PacketLossButton"), static_cast<int32>(TotalPacketLost))));
const float Width = ImGui::GetItemRectSize().x;
ImGui::PopStyleColor(1);
if (ImGui::Button(TCHAR_TO_ANSI(*FString::Printf(TEXT("%2d%%###PacketLossButton"), (int32)TotalPacketLost)), ImVec2(Width, 0.0f)))
if (ImGui::BeginPopupContextItem())
{
ImGui::OpenPopup("PacketLossPopup");
Config->RenderColorConfig();
Config->RenderPacketLossConfig();
Super::RenderContextMenu();
ImGui::EndPopup();
}
ImGui::PopStyleColor(2);
ImGui::PopStyleVar(2);
ImGui::SetItemTooltip("Packet Loss");
if (Open == false)
{
ImGui::SetItemTooltip("Packet Loss");
}
#if DO_ENABLE_NET_TEST
if (ImGui::BeginPopup("PacketLossPopup"))
if (Open)
{
FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(GetWorld());
if (WorldContext.ActiveNetDrivers.Num() > 0)
{
ImGui::Text("Packet Loss");
ImGui::SameLine();
const FNamedNetDriver* SelectedNetDriver = &WorldContext.ActiveNetDrivers[0];
FPacketSimulationSettings Settings = SelectedNetDriver->NetDriver->PacketSimulationSettings;
TArray<int32> Values{ 0, 5, 10, 20, 30, 40, 50 };
if (FCogWindowWidgets::MultiChoiceButtonsInt(Values, Settings.PktIncomingLoss, ImVec2(3.5f * FCogWindowWidgets::GetFontWidth(), 0)))
for (int32 i = 0; i < Config->PacketLosses.Num(); ++i)
{
Settings.PktLoss = Settings.PktIncomingLoss;
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
ImGui::PushID(i);
const float Value = Config->PacketLosses[i];
const auto ValueText = StringCast<ANSICHAR>(*FCogWidgets::FormatSmallFloat(Value));
if (ImGui::Selectable(ValueText.Get(), Value == Settings.PktIncomingLagMin, ImGuiSelectableFlags_None, ImVec2(Width, 0)))
{
Settings.PktIncomingLoss = Value;
Settings.PktLoss = Settings.PktIncomingLoss;
SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings);
}
ImGui::PopID();
}
}
ImGui::EndPopup();
@@ -230,50 +248,98 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetPacketLoss(const float Width)
#endif //DO_ENABLE_NET_TEST
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogEngineWindow_Stats::GetFpsColor(const float Value, const float Good /*= 50.0f*/, const float Medium /*= 30.0f*/)
ImVec4 UCogEngineWindowConfig_Stats::GetFpsColor(const float Value) const
{
if (Value > Good)
{
return StatGreenColor;
}
if (Value > GoodFrameRate)
{ return FCogImguiHelper::ToImVec4(GoodColor); }
if (Value > Medium)
{
return StatOrangeColor;
}
if (Value > MediumFrameRate)
{ return FCogImguiHelper::ToImVec4(MediumColor); }
return StatRedColor;
return FCogImguiHelper::ToImVec4(BadColor);
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogEngineWindow_Stats::GetPingColor(const float Value, const float Good /*= 100.0f*/, const float Medium /*= 200.0f*/)
ImVec4 UCogEngineWindowConfig_Stats::GetPingColor(const float Value) const
{
if (Value > Medium)
{
return StatRedColor;
}
if (Value > MediumPing)
{ return FCogImguiHelper::ToImVec4(BadColor); }
if (Value > Good)
{
return StatOrangeColor;
}
if (Value > GoodPing)
{ return FCogImguiHelper::ToImVec4(MediumColor); }
return StatGreenColor;
return FCogImguiHelper::ToImVec4(GoodColor);
}
//--------------------------------------------------------------------------------------------------------------------------
ImVec4 FCogEngineWindow_Stats::GetPacketLossColor(const float Value, const float Good /*= 10.0f*/, const float Medium /*= 20.0f*/)
ImVec4 UCogEngineWindowConfig_Stats::GetPacketLossColor(const float Value) const
{
if (Value > Medium)
{
return StatRedColor;
}
if (Value > MediumPacketLoss)
{ return FCogImguiHelper::ToImVec4(BadColor); }
if (Value > Good)
{
return StatOrangeColor;
}
if (Value > GoodPacketLoss)
{ return FCogImguiHelper::ToImVec4(MediumColor); }
return StatGreenColor;
}
return FCogImguiHelper::ToImVec4(GoodColor);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindowConfig_Stats::RenderAllConfigs()
{
RenderColorConfig();
RenderFrameRateConfig();
RenderPingConfig();
RenderPacketLossConfig();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindowConfig_Stats::RenderColorConfig()
{
if (ImGui::CollapsingHeader("Display", ImGuiTreeNodeFlags_DefaultOpen))
{
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
FCogImguiHelper::ColorEdit4("Good Color", GoodColor, ColorEditFlags);
ImGui::SetItemTooltip("Color of a stat with a good value.");
FCogImguiHelper::ColorEdit4("Medium Color", MediumColor, ColorEditFlags);
ImGui::SetItemTooltip("Color of a stat with a medium value.");
FCogImguiHelper::ColorEdit4("Bad Color", BadColor, ColorEditFlags);
ImGui::SetItemTooltip("Color of a stat with a bad value.");
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindowConfig_Stats::RenderFrameRateConfig()
{
if (ImGui::CollapsingHeader("Frame Rate", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::InputInt("Good Frame Rate", &GoodFrameRate);
ImGui::InputInt("Medium Frame Rate", &MediumFrameRate);
FCogWidgets::IntArray("Max Frame Rate", FrameRates, 10, ImVec2(0, ImGui::GetFontSize() * 10));
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindowConfig_Stats::RenderPingConfig()
{
if (ImGui::CollapsingHeader("Ping", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::InputInt("Good Ping", &GoodPing);
ImGui::InputInt("Medium Ping", &MediumPing);
FCogWidgets::IntArray("Ping Emulation", Pings, 10, ImVec2(0, ImGui::GetFontSize() * 10));
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindowConfig_Stats::RenderPacketLossConfig()
{
if (ImGui::CollapsingHeader("Packet Loss", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::InputInt("Good Packet Loss", &GoodPacketLoss);
ImGui::InputInt("Medium Packet Loss", &MediumPacketLoss);
FCogWidgets::IntArray("Packet Loss Emulation", PacketLosses, 10, ImVec2(0, ImGui::GetFontSize() * 10));
}
}
@@ -1,23 +1,30 @@
#include "CogEngineWindow_TimeScale.h"
#include "CogEngineReplicator.h"
#include "CogWindowWidgets.h"
#include "CogImguiHelper.h"
#include "CogImguiInputHelper.h"
#include "CogSubsystem.h"
#include "CogWidgets.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::Initialize()
{
Super::Initialize();
TimingScales.Add(0.00f);
TimingScales.Add(0.01f);
TimingScales.Add(0.10f);
TimingScales.Add(0.50f);
TimingScales.Add(1.00f);
TimingScales.Add(2.00f);
TimingScales.Add(5.00f);
TimingScales.Add(10.0f);
bHasWidget = true;
bIsWidgetVisible = true;
Config = GetConfig<UCogEngineWindowConfig_TimeScale>();
UCogEngineWindowConfig_TimeScale* ConfigPtr = Config.Get();
GetOwner()->AddShortcut(ConfigPtr, &UCogEngineWindowConfig_TimeScale::Shortcut_FasterTimeScale).BindRaw(this, &FCogEngineWindow_TimeScale::FasterTimeScale);
GetOwner()->AddShortcut(ConfigPtr, &UCogEngineWindowConfig_TimeScale::Shortcut_SlowerTimeScale).BindRaw(this, &FCogEngineWindow_TimeScale::SlowerTimeScale);
GetOwner()->AddShortcut(ConfigPtr, &UCogEngineWindowConfig_TimeScale::Shortcut_ResetTimeScale).BindRaw(this, &FCogEngineWindow_TimeScale::ResetTimeScale);
GetOwner()->AddShortcut(ConfigPtr, &UCogEngineWindowConfig_TimeScale::Shortcut_ZeroTimeScale).BindRaw(this, &FCogEngineWindow_TimeScale::ZeroTimeScale);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -41,10 +48,206 @@ void FCogEngineWindow_TimeScale::RenderContent()
return;
}
float Value = Replicator->GetTimeDilation();
if (FCogWindowWidgets::MultiChoiceButtonsFloat(TimingScales, Value, ImVec2(3.5f * FCogWindowWidgets::GetFontWidth(), 0)))
RenderTimeScaleChoices(Replicator);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::RenderContextMenu()
{
UCogEngineWindowConfig_TimeScale* ConfigPtr = Config.Get();
if (IsWindowRenderedInMainMenu() == false)
{
Replicator->SetTimeDilation(Value);
ImGui::Checkbox("Inline", &ConfigPtr->Inline);
}
FCogImguiHelper::ColorEdit4("Time Scale Modified Color", ConfigPtr->TimeScaleModifiedColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::SetItemTooltip("Color of the current time scale, in widget mode, when the time scale in not 1.");
FCogWidgets::FloatArray("Time Scales", ConfigPtr->TimeScales, 10, ImVec2(0, ImGui::GetFontSize() * 10));
if (ImGui::CollapsingHeader("Shortcuts", ImGuiTreeNodeFlags_DefaultOpen))
{
RenderConfigShortcuts(*ConfigPtr);
}
ImGui::Separator();
FCogWindow::RenderContextMenu();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::RenderMainMenuWidget()
{
Super::RenderMainMenuWidget();
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{
ImGui::TextDisabled("x?");
ImGui::SetItemTooltip("Invalid Replicator");
return;
}
float TimeDilation = GetTimeDilation();
if (TimeDilation != 1.0f)
{
ImGui::PushStyleColor(ImGuiCol_Text, FCogImguiHelper::ToImVec4(Config->TimeScaleModifiedColor));
}
if (FMath::IsNearlyZero(TimeDilation, 0.0001f))
{
TimeDilation = 0.0f;
}
const auto Text = StringCast<ANSICHAR>(*FString::Printf(TEXT("x%g"), TimeDilation));
const bool Open = ImGui::BeginMenu(Text.Get());
if (TimeDilation != 1)
{
ImGui::PopStyleColor();
}
if (ImGui::BeginPopupContextItem())
{
RenderContextMenu();
ImGui::EndPopup();
}
if (Open)
{
for (int32 i = 0; i < Config->TimeScales.Num(); ++i)
{
const float Value = Config->TimeScales[i];
const auto ValueText = StringCast<ANSICHAR>(*FString::Printf(TEXT("%g"), Value));
if (ImGui::Selectable(ValueText.Get(), Value == TimeDilation))
{
SetCurrentTimeScale(*Replicator, Value);
}
}
ImGui::EndMenu();
}
else
{
if (FCogWidgets::BeginItemTooltipWrappedText())
{
ImGui::Text("Time Scale: x%g", TimeDilation);
ImGui::Spacing();
ImGui::Separator();
FCogWidgets::TextOfAllInputChordsOfConfig(*Config.Get());
FCogWidgets::EndItemTooltipWrappedText();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
int32 FCogEngineWindow_TimeScale::GetCurrentTimeScaleIndex(const ACogEngineReplicator& Replicator) const
{
return GetTimeScaleIndex(Replicator.GetTimeDilation());
}
//--------------------------------------------------------------------------------------------------------------------------
int32 FCogEngineWindow_TimeScale::GetTimeScaleIndex(float InTimeScale) const
{
for (int32 i = 0; i < Config->TimeScales.Num(); ++i)
{
const float Value = Config->TimeScales[i];
if (FMath::IsNearlyEqual(Value, InTimeScale))
{ return i; }
}
return INDEX_NONE;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::SetCurrentTimeScale(ACogEngineReplicator& Replicator, const float Value) const
{
Replicator.SetTimeDilation(Value);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::SetCurrentTimeScaleIndex(ACogEngineReplicator& Replicator, int32 InTimeScaleIndex) const
{
if (Config->TimeScales.IsValidIndex(InTimeScaleIndex) == false)
{ return; }
const float Value = Config->TimeScales[InTimeScaleIndex];
SetCurrentTimeScale(Replicator, Value);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::FasterTimeScale()
{
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{ return; }
const int32 TimeScaleIndex = GetCurrentTimeScaleIndex(*Replicator);
if (TimeScaleIndex == INDEX_NONE)
{ return; }
SetCurrentTimeScaleIndex(*Replicator, TimeScaleIndex + 1);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::SlowerTimeScale()
{
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{ return; }
const int32 TimeScaleIndex = GetCurrentTimeScaleIndex(*Replicator);
if (TimeScaleIndex == INDEX_NONE)
{ return; }
SetCurrentTimeScaleIndex(*Replicator, TimeScaleIndex - 1);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::ResetTimeScale()
{
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{ return; }
SetCurrentTimeScale(*Replicator, 1.0f);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::ZeroTimeScale()
{
ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld());
if (Replicator == nullptr)
{ return; }
SetCurrentTimeScale(*Replicator, 0.0f);
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogEngineWindow_TimeScale::GetTimeDilation() const
{
const UWorld* World = GetWorld();
if (World == nullptr)
{
return 1.0f;
}
AWorldSettings* WorldSettings = World->GetWorldSettings();
if (WorldSettings == nullptr)
{
return 1.0f;
}
return WorldSettings->GetEffectiveTimeDilation();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_TimeScale::RenderTimeScaleChoices(ACogEngineReplicator* Replicator)
{
float TimeDilation = GetTimeDilation();
if (FCogWidgets::MultiChoiceButtonsFloat(Config->TimeScales, TimeDilation, ImVec2(3.5f * FCogWidgets::GetFontWidth(), 0), Config->Inline, 0.0001f))
{
Replicator->SetTimeDilation(TimeDilation);
}
}
@@ -2,7 +2,7 @@
#include "CogDebug.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "CogWidgets.h"
#include "GameFramework/Actor.h"
#include "imgui.h"
#include "imgui_internal.h"
@@ -39,13 +39,13 @@ void FCogEngineWindow_Transform::RenderContent()
{
if (ImGui::BeginMenu("Options"))
{
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Location", &Config->LocationSpeed, 0.1f, 0.1f, 100.0f);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Rotation", &Config->RotationSpeed, 0.1f, 0.1f, 100.0f);
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat("Drag Speed Scale", &Config->ScaleSpeed, 0.1f, 0.1f, 100.0f);
ImGui::SeparatorText("Gizmo");
@@ -113,7 +113,7 @@ void FCogEngineWindow_Transform::RenderSnap(const char* CheckboxLabel, const cha
ImGui::Checkbox(CheckboxLabel, SnapEnable);
ImGui::SameLine();
FCogWindowWidgets::SetNextItemToShortWidth();
FCogWidgets::SetNextItemToShortWidth();
ImGui::DragFloat(InputLabel, Snap, 0.1f, 0.1f, 1000.0f, "%.1f");
}
@@ -17,13 +17,22 @@ enum class ECogEngine_CollisionQueryType : uint8
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryMode : uint8
enum class ECogEngine_CollisionQueryTraceMode : uint8
{
Single,
Multi,
Test,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryOverlapMode : uint8
{
AnyTest,
BlockingTest,
Multi,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogEngine_CollisionQueryBy : uint8
@@ -49,7 +58,6 @@ class COGENGINE_API ACogEngineCollisionTester : public AActor
GENERATED_BODY()
public:
ACogEngineCollisionTester(const FObjectInitializer& ObjectInitializer);
virtual void Tick(float DeltaSeconds) override;
@@ -65,7 +73,10 @@ public:
ECogEngine_CollisionQueryType Type = ECogEngine_CollisionQueryType::LineTrace;
UPROPERTY(EditAnywhere, Category="Cog")
ECogEngine_CollisionQueryMode Mode = ECogEngine_CollisionQueryMode::Multi;
ECogEngine_CollisionQueryTraceMode TraceMode = ECogEngine_CollisionQueryTraceMode::Multi;
UPROPERTY(EditAnywhere, Category="Cog")
ECogEngine_CollisionQueryOverlapMode OverlapMode = ECogEngine_CollisionQueryOverlapMode::Multi;
UPROPERTY(EditAnywhere, Category="Cog")
ECogEngine_CollisionQueryBy By = ECogEngine_CollisionQueryBy::Channel;
@@ -80,7 +91,7 @@ public:
int32 ObjectTypesToQuery = 0;
UPROPERTY(EditAnywhere, Category="Cog")
TEnumAsByte<ECollisionChannel> Channel = ECC_WorldStatic;
TEnumAsByte<ECollisionChannel> TraceChannel = ECC_Visibility;
UPROPERTY()
int32 ProfileIndex = 0;
@@ -125,8 +136,8 @@ public:
FColor ImpactNormalColor = FColor::Cyan;
UPROPERTY(EditAnywhere, Category="Cog")
USceneComponent* StartComponent = nullptr;
TObjectPtr<USceneComponent> StartComponent;
UPROPERTY(EditAnywhere, Category="Cog")
USceneComponent* EndComponent = nullptr;
TObjectPtr<USceneComponent> EndComponent;
};
@@ -3,6 +3,9 @@
#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "Engine/EngineTypes.h"
#include "GameFramework/Character.h"
#include "GameFramework/GameModeBase.h"
#include "GameFramework/GameStateBase.h"
#include "CogEngineDataAsset.generated.h"
class FCogWindow;
@@ -16,7 +19,7 @@ enum class ECogEngineCheat_ActiveState : uint8
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(BlueprintType, Abstract, Const, DefaultToInstanced, EditInlineNew, CollapseCategories)
UCLASS(BlueprintType, Blueprintable, Abstract, Const, DefaultToInstanced, EditInlineNew, CollapseCategories, Meta = (ShowWorldContextPin))
class COGENGINE_API UCogEngineCheat_Execution
: public UObject
{
@@ -24,11 +27,11 @@ class COGENGINE_API UCogEngineCheat_Execution
public:
UFUNCTION(BlueprintNativeEvent)
void Execute(const AActor* Instigator, const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent, meta = (DevelopmentOnly, WorldContext = "WorldContextObject"))
void Execute(const UObject* WorldContextObject, const AActor* Instigator, const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent)
ECogEngineCheat_ActiveState IsActiveOnTargets(const TArray<AActor*>& Targets) const;
UFUNCTION(BlueprintNativeEvent, meta = (DevelopmentOnly, WorldContext = "WorldContextObject"))
ECogEngineCheat_ActiveState IsActiveOnTargets(const UObject* WorldContextObject, const TArray<AActor*>& Targets) const;
virtual bool GetColor(const FCogWindow& InCallingWindow, FLinearColor& OutColor) const;
};
@@ -61,10 +64,10 @@ struct COGENGINE_API FCogEngineCheatCategory
FString Name;
UPROPERTY(Category = "Cheats", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineCheat> PersistentEffects;
TArray<FCogEngineCheat> PersistentCheats;
UPROPERTY(Category = "Cheats", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineCheat> InstantEffects;
TArray<FCogEngineCheat> InstantCheats;
};
//--------------------------------------------------------------------------------------------------------------------------
@@ -111,4 +114,10 @@ public:
UPROPERTY(Category = "Spawns", EditAnywhere, meta = (TitleProperty = "Name"))
TArray<FCogEngineSpawnGroup> SpawnGroups;
UPROPERTY(Category = "Selection", EditAnywhere)
TArray<TSubclassOf<AActor>> SelectionFilters = { ACharacter::StaticClass(), AActor::StaticClass(), AGameModeBase::StaticClass(), AGameStateBase::StaticClass() };
UPROPERTY(Category = "Selection", EditAnywhere)
TEnumAsByte<ETraceTypeQuery> SelectionTraceChannel = UEngineTypes::ConvertToTraceType(ECC_Pawn);
};
@@ -1,6 +1,7 @@
#pragma once
#include "CoreMinimal.h"
#include "CogEngineDataAsset.h"
class AActor;
@@ -10,4 +11,5 @@ public:
static void ActorContextMenu(AActor& Actor);
static void RenderConfigureMessage(TWeakObjectPtr<const UCogEngineDataAsset> InAsset);
};
@@ -33,7 +33,7 @@ public:
FCogEngineSpawnFunction GetSpawnFunction() const { return SpawnFunction; }
void SetSpawnFunction(FCogEngineSpawnFunction Value) { SpawnFunction = Value; }
void SetSpawnFunction(const FCogEngineSpawnFunction& Value) { SpawnFunction = Value; }
UFUNCTION(Server, Reliable)
void Server_Spawn(const FCogEngineSpawnEntry& SpawnEntry);
@@ -54,7 +54,7 @@ public:
UFUNCTION(Reliable, Server)
void Server_ApplyCheat(const AActor* CheatInstigator, const TArray<AActor*>& TargetActors, const FCogEngineCheat& Cheat) const;
static ECogEngineCheat_ActiveState IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat);
ECogEngineCheat_ActiveState IsCheatActiveOnTargets(const TArray<AActor*>& Targets, const FCogEngineCheat& Cheat) const;
protected:
@@ -64,7 +64,7 @@ protected:
UFUNCTION()
void OnRep_TimeDilation() const;
TObjectPtr<APlayerController> OwnerPlayerController;
TWeakObjectPtr<APlayerController> OwnerPlayerController;
uint32 bHasAuthority : 1;
uint32 bIsLocal : 1;
@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "CogEngineReplicator.h"
#include "CogDebugPluginSubsystem.h"
#include "CogEngineSubsystem.generated.h"
UCLASS()
class COGENGINE_API UCogEngineSubsystem : public UCogDebugPluginSubsystem
{
GENERATED_BODY()
public:
virtual void OnPlayerControllerReady(APlayerController* InController) override
{
if (InController != nullptr)
{
ACogEngineReplicator::Spawn(InController);
}
}
};
@@ -0,0 +1,118 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogWidgets.h"
#include "CogEngineWindow_BuildInfo.generated.h"
class UCogEngineConfig_BuildInfo;
class COGENGINE_API FCogEngineWindow_BuildInfo : public FCogWindow
{
typedef FCogWindow Super;
public:
virtual void Initialize() override;
virtual void RenderHelp() override;
virtual void RenderTick(float DeltaTime) override;
virtual void RenderContent() override;
protected:
void BuildText();
TWeakObjectPtr<UCogEngineConfig_BuildInfo> Config;
FString Text;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(Config = Cog)
class UCogEngineConfig_BuildInfo : public UCogCommonConfig
{
GENERATED_BODY()
public:
UPROPERTY(Config)
bool ShowInEditor = false;
UPROPERTY(Config)
bool ShowInPackage = true;
UPROPERTY(Config)
bool ShowBranchName = false;
UPROPERTY(Config)
bool ShowBuildDate = true;
UPROPERTY(Config)
bool ShowCurrentChangelist = true;
UPROPERTY(Config)
bool ShowCompatibleChangelist = false;
UPROPERTY(Config)
bool ShowBuildConfiguration = true;
UPROPERTY(Config)
bool ShowBuildUser = false;
UPROPERTY(Config)
bool ShowBuildMachine = false;
UPROPERTY(Config)
bool ShowBuildTargetType = true;
UPROPERTY(Config)
bool ShowInForeground = true;
UPROPERTY(Config)
FVector2f Alignment = { 0, 1 };
UPROPERTY(Config)
FIntVector2 Padding = { 10, 10 };
UPROPERTY(Config)
int32 Rounding = 6;
UPROPERTY(Config)
FString Separator = "|";
UPROPERTY(Config)
FColor BackgroundColor = FColor(0, 0, 0, 80);
UPROPERTY(Config)
FColor BorderColor = FColor(255, 255, 255, 50);
UPROPERTY(Config)
FColor TextColor = FColor(255, 255, 255, 100);
virtual void Reset() override
{
Super::Reset();
ShowInEditor = false;
ShowInPackage = true;
ShowInForeground = true;
ShowBranchName = false;
ShowBuildDate = true;
ShowCurrentChangelist = true;
ShowCompatibleChangelist = false;
ShowBuildConfiguration = true;
ShowBuildUser = false;
ShowBuildMachine = false;
ShowBuildTargetType = true;
Alignment = { 0, 1 };
Padding = { 10, 10 };
Rounding = 6;
Separator = " | ";
BackgroundColor = FColor(0, 0, 0, 80);
BorderColor = FColor(255, 255, 255, 50);
TextColor = FColor(255, 255, 255, 100);
}
};

Some files were not shown because too many files have changed in this diff Show More