diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebug.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebug.cpp index 034e08a..a77f1fa 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebug.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebug.cpp @@ -19,7 +19,7 @@ void FCogDebug::Reset() //-------------------------------------------------------------------------------------------------------------------------- bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject) { - UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); if (World == nullptr) { return true; @@ -30,7 +30,7 @@ bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject) return true; } - bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection.Get(), Settings.bIsFilteringBySelection); + const bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection.Get(), Settings.bIsFilteringBySelection); return Result; } @@ -92,7 +92,7 @@ AActor* FCogDebug::GetSelection() } //-------------------------------------------------------------------------------------------------------------------------- -void FCogDebug::SetSelection(UWorld* World, AActor* Value) +void FCogDebug::SetSelection(const UWorld* World, AActor* Value) { Selection = Value; diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugDrawHelper.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugDrawHelper.cpp index 0422f47..b57651c 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugDrawHelper.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugDrawHelper.cpp @@ -2,7 +2,6 @@ #include "CogDebug.h" #include "Components/LineBatchComponent.h" -#include "Kismet/KismetSystemLibrary.h" #include "Engine/Engine.h" #include "DrawDebugHelpers.h" #include "Components/BoxComponent.h" diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp index 8a1f4cd..8dacbb6 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugGizmo.cpp @@ -423,7 +423,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont InOutTransform.SetLocation(NewLocation); Result = true; - const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta); + const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta); DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast(*Text).Get()); //DrawDebugPoint(World, InitialTransform.GetTranslation(), 5.0f, FColor::White); @@ -453,7 +453,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont InOutTransform.SetLocation(NewLocation); Result = true; - const FString Text = FString::Printf(TEXT("%0.1f %0.1f"), SnappedDeltaU, SnappedDeltaV); + const FString Text = FString::Printf(TEXT("%+0.1f %+0.1f"), SnappedDeltaU, SnappedDeltaV); DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast(*Text).Get()); //DrawDebugPoint(World, InitialTransform.GetTranslation(), 5.0f, FColor::White); @@ -474,7 +474,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont InOutTransform.SetRotation(NewRot); Result = true; - const FString Text = FString::Printf(TEXT("%0.1f"), SnappedAngle); + const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedAngle); DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast(*Text).Get()); break; @@ -490,7 +490,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont InOutTransform.SetScale3D(NewScale); Result = true; - const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta); + const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta); DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast(*Text).Get()); break; @@ -505,7 +505,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont InOutTransform.SetScale3D(NewScale); Result = true; - const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta); + const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta); DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast(*Text).Get()); break; diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp index e5f909e..538840c 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp @@ -24,9 +24,9 @@ ACogDebugReplicator* ACogDebugReplicator::Spawn(APlayerController* Controller) } //-------------------------------------------------------------------------------------------------------------------------- -ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(UWorld& World) +ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(const UWorld& World) { - for (TActorIterator It(&World, ACogDebugReplicator::StaticClass()); It; ++It) + for (TActorIterator It(&World, StaticClass()); It; ++It) { ACogDebugReplicator* Replicator = *It; return Replicator; diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h index e61f8e9..b0b4741 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebug.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebug.h @@ -61,6 +61,9 @@ struct FCogDebugSettings UPROPERTY(Config) float TextSize = 1.0f; + UPROPERTY(Config) + bool ActorNameUseLabel = true; + UPROPERTY(Config) float GizmoScale = 1.0f; @@ -363,7 +366,7 @@ public: static AActor* GetSelection(); - static void SetSelection(UWorld* World, AActor* Value); + static void SetSelection(const UWorld* World, AActor* Value); static bool GetIsFilteringBySelection(); diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h b/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h index d59fbf2..3d15b07 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h @@ -61,7 +61,7 @@ public: static ACogDebugReplicator* Spawn(APlayerController* Controller); - static ACogDebugReplicator* GetLocalReplicator(UWorld& World); + static ACogDebugReplicator* GetLocalReplicator(const UWorld& World); static void GetRemoteReplicators(UWorld& World, TArray& Replicators); diff --git a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs index 9fc456b..360db8c 100644 --- a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs +++ b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs @@ -4,32 +4,16 @@ public class CogEngine : ModuleRules { public CogEngine(ReadOnlyTargetRules Target) : base(Target) { - PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; - - PublicIncludePaths.AddRange( - new string[] - { - } - ); - - - PrivateIncludePaths.AddRange( - new string[] - { - } - ); - + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange( - new string[] + new [] { "CogDebug", - } - ); - + }); PrivateDependencyModuleNames.AddRange( - new string[] + new [] { "CogCommon", "CogImgui", @@ -41,14 +25,16 @@ public class CogEngine : ModuleRules "NetCore", "Slate", "SlateCore", - } - ); + }); - - DynamicallyLoadedModuleNames.AddRange( - new string[] + if (Target.bBuildEditor) + { + PrivateDependencyModuleNames.AddRange( + new [] { - } - ); + "AssetTools" + }); + } + } } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineHelper.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineHelper.cpp new file mode 100644 index 0000000..f6bd313 --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineHelper.cpp @@ -0,0 +1,68 @@ +#include "CogEngineHelper.h" + +#include "CogEngineReplicator.h" +#include "CogWindowHelper.h" +#include "CogWindowWidgets.h" +#include "imgui.h" + +#if WITH_EDITOR +#include "IAssetTools.h" +#endif + + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogEngineHelper::ActorContextMenu(AActor& Actor) +{ + FCogWindowWidgets::ThinSeparatorText("Object"); + +#if WITH_EDITOR + const UObject* DefaultObject = Actor.GetClass()->GetDefaultObject(); + if (DefaultObject == nullptr) + { + ImGui::BeginDisabled(); + } + if (ImGui::Button("Browse To Asset", ImVec2(-1, 0))) + { + IAssetTools::Get().SyncBrowserToAssets({ DefaultObject }); + } + if (DefaultObject == nullptr) + { + ImGui::EndDisabled(); + } +#endif + + if (ImGui::Button("Delete", ImVec2(-1, 0))) + { + if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld())) + { + Replicator->Server_DeleteActor(&Actor); + } + } + + if (APawn* Pawn = Cast(&Actor)) + { + FCogWindowWidgets::ThinSeparatorText("Pawn"); + + if (ImGui::Button("Possess", ImVec2(-1, 0))) + { + if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld())) + { + Replicator->Server_Possess(Pawn); + } + + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("Possess this pawn."); + } + + if (ImGui::Button("Reset Possession", ImVec2(-1, 0))) + { + if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld())) + { + Replicator->Server_ResetPossession(); + } + + } + } +} \ No newline at end of file diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp index 59b95e0..ef20cb5 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp @@ -207,3 +207,16 @@ void ACogEngineReplicator::Server_ResetPossession_Implementation() #endif // !UE_BUILD_SHIPPING } + +//-------------------------------------------------------------------------------------------------------------------------- +void ACogEngineReplicator::Server_DeleteActor_Implementation(AActor* Actor) +{ +#if !UE_BUILD_SHIPPING + + if (Actor != nullptr) + { + GetWorld()->DestroyActor(Actor); + } + +#endif // !UE_BUILD_SHIPPING +} diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp index 12c2579..214bae0 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CollisionTester.cpp @@ -43,38 +43,17 @@ void FCogEngineWindow_CollisionTester::RenderContent() //------------------------------------------------- if (ImGui::BeginMenuBar()) { - ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - - if (ImGui::ArrowButton("SelectPrev", ImGuiDir_Left)) - { - } - if (ImGui::BeginItemTooltip()) - { - ImGui::SetTooltip("Select previous collision tester"); - ImGui::EndTooltip(); - } - - ImGui::SameLine(); - if (ImGui::ArrowButton("SelectNext", ImGuiDir_Right)) - { - } - if (ImGui::BeginItemTooltip()) - { - ImGui::SetTooltip("Select next collision tester"); - ImGui::EndTooltip(); - } - - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(1); - - if (ImGui::MenuItem("Spawn")) { const FActorSpawnParameters SpawnInfo; const FTransform Transform = GetSelection() ? GetSelection()->GetActorTransform() : FTransform::Identity; - ACogEngineCollisionTester* Actor = GetWorld()->SpawnActor(ACogEngineCollisionTester::StaticClass(), Transform, SpawnInfo); - FCogDebug::SetSelection(GetWorld(), Actor); + ACogEngineCollisionTester* NewActor = GetWorld()->SpawnActor(ACogEngineCollisionTester::StaticClass(), Transform, SpawnInfo); + +#if WITH_EDITOR + NewActor->SetActorLabel(NewActor->GetName().Replace(TEXT("CogEngine"), TEXT(""))); +#endif + + FCogDebug::SetSelection(GetWorld(), NewActor); } if (ImGui::BeginItemTooltip()) { @@ -102,12 +81,17 @@ void FCogEngineWindow_CollisionTester::RenderContent() ImGui::EndDisabled(); } + ImGui::SetNextItemWidth(-1); + FCogWindowWidgets::MenuActorsCombo("CollisionTesters", *GetWorld(), ACogEngineCollisionTester::StaticClass()); + ImGui::EndMenuBar(); } if (CollisionTester == nullptr) { - ImGui::TextDisabled("Spawn or select a Collision Tester actor"); + ImGui::PushTextWrapPos(0.0f); + ImGui::TextDisabled("Select or spawn a Collision Tester actor"); + ImGui::PopTextWrapPos(); return; } @@ -224,19 +208,19 @@ void FCogEngineWindow_CollisionTester::RenderContent() } } - ImGui::Separator(); - //------------------------------------------------- // Channels //------------------------------------------------- if (CollisionTester->By == ECogEngine_CollisionQueryBy::Profile) { + ImGui::Separator(); ImGui::BeginDisabled(); FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery); ImGui::EndDisabled(); } else if (CollisionTester->By == ECogEngine_CollisionQueryBy::ObjectType) { + ImGui::Separator(); FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery); } } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp index 636f691..c3d7179 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp @@ -91,6 +91,12 @@ void FCogEngineWindow_DebugSettings::RenderContent() ImGui::SetTooltip("Make debug draw always persist"); } + ImGui::Checkbox("Actor Name Use Label", &Settings.ActorNameUseLabel); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + { + ImGui::SetTooltip("Use the actor label when displaying the actor name."); + } + ImGui::Checkbox("Text Shadow", &Settings.TextShadow); if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) { diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp index 88a9c83..4844206 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp @@ -250,7 +250,7 @@ void FCogEngineWindow_Inspector::RenderMenu() //----------------------------------- // Search //----------------------------------- - FCogWindowWidgets::MenuSearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9); + FCogWindowWidgets::SearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9); //----------------------------------- // Options diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp index c4df778..219c087 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp @@ -171,7 +171,7 @@ void FCogEngineWindow_OutputLog::RenderContent() ImGui::SetNextItemWidth(ImGui::GetFontSize() * 9); if (ImGui::BeginCombo("##Verbosity", FCogDebugHelper::VerbosityToString((ELogVerbosity::Type)Config->VerbosityFilter))) { - for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i) + for (int32 i = ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i) { const bool IsSelected = i == Config->VerbosityFilter; const ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i; @@ -184,7 +184,7 @@ void FCogEngineWindow_OutputLog::RenderContent() ImGui::EndCombo(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp index d42e881..dbe97d1 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp @@ -1,8 +1,8 @@ #include "CogEngineWindow_Selection.h" -#include "CogDebugDraw.h" #include "CogDebug.h" -#include "CogEngineReplicator.h" +#include "CogEngineHelper.h" +#include "CogEngineWindow_ImGui.h" #include "CogImguiHelper.h" #include "CogImguiInputHelper.h" #include "CogWindowManager.h" @@ -75,7 +75,7 @@ void FCogEngineWindow_Selection::PreSaveConfig() //-------------------------------------------------------------------------------------------------------------------------- void FCogEngineWindow_Selection::TryReapplySelection() const { - UWorld* World = GetWorld(); + const UWorld* World = GetWorld(); if (World == nullptr) { return; @@ -91,14 +91,14 @@ void FCogEngineWindow_Selection::TryReapplySelection() const return; } - TSubclassOf SelectedClass = GetSelectedActorClass(); + const TSubclassOf SelectedClass = GetSelectedActorClass(); if (SelectedClass == nullptr) { return; } TArray Actors; - for (TActorIterator It(World, SelectedClass); It; ++It) + for (TActorIterator It(World, SelectedClass); It; ++It) { AActor* Actor = *It; if (GetNameSafe(Actor) == Config->SelectionName) @@ -155,9 +155,9 @@ 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 is was before + // 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); @@ -179,11 +179,11 @@ void FCogEngineWindow_Selection::RenderTick(float DeltaTime) TickSelectionMode(); } - if (AActor* Actor = GetSelection()) + if (const AActor* Actor = GetSelection()) { if (Actor != GetLocalPlayerPawn()) { - DrawActorFrame(*Actor); + FCogWindowWidgets::ActorFrame(*Actor); } } } @@ -198,8 +198,16 @@ void FCogEngineWindow_Selection::RenderContent() if (ImGui::MenuItem("Pick")) { ActivateSelectionMode(); - HackWaitInputRelease(); + //HackWaitInputRelease(); } + + if (ImGui::BeginMenu("Options")) + { + ImGui::Checkbox("Save selection", &Config->bReapplySelection); + ImGui::Checkbox("Actor Name Use Label", &FCogDebug::Settings.ActorNameUseLabel); + ImGui::EndMenu(); + } + RenderPickButtonTooltip(); ImGui::EndMenuBar(); @@ -211,171 +219,7 @@ void FCogEngineWindow_Selection::RenderContent() //-------------------------------------------------------------------------------------------------------------------------- bool FCogEngineWindow_Selection::DrawSelectionCombo() { - bool SelectionChanged = false; - - APawn* LocalPlayerPawn = GetLocalPlayerPawn(); - - //------------------------ - // Actor Class Combo - //------------------------ - - TSubclassOf SelectedClass = GetSelectedActorClass(); - - ImGui::SetNextItemWidth(-1); - if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedClass)))) - { - for (int32 i = 0; i < ActorClasses.Num(); ++i) - { - TSubclassOf SubClass = ActorClasses[i]; - if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(SubClass)), false)) - { - Config->SelectedClassIndex = i; - SelectedClass = SubClass; - } - } - ImGui::EndCombo(); - } - - ImGui::Separator(); - - //------------------------ - // Actor List - //------------------------ - ImGui::BeginChild("ActorList", ImVec2(-1, -1), false); - - TArray Actors; - for (TActorIterator It(GetWorld(), SelectedClass); It; ++It) - { - AActor* Actor = *It; - Actors.Add(Actor); - } - - ImGuiListClipper Clipper; - Clipper.Begin(Actors.Num()); - while (Clipper.Step()) - { - for (int32 i = Clipper.DisplayStart; i < Clipper.DisplayEnd; i++) - { - AActor* Actor = Actors[i]; - if (Actor == nullptr) - { - continue; - } - - ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255)); - - bool bIsSelected = Actor == FCogDebug::GetSelection(); - if (ImGui::Selectable(TCHAR_TO_ANSI(*GetActorName(*Actor)), bIsSelected)) - { - SetGlobalSelection(Actor); - SelectionChanged = true; - } - - ImGui::PopStyleColor(1); - - DrawActorContextMenu(Actor); - - //------------------------ - // Draw Frame - //------------------------ - if (ImGui::IsItemHovered()) - { - DrawActorFrame(*Actor); - } - - if (bIsSelected) - { - ImGui::SetItemDefaultFocus(); - } - } - } - Clipper.End(); - ImGui::EndChild(); - - return SelectionChanged; -} - -//-------------------------------------------------------------------------------------------------------------------------- -FString FCogEngineWindow_Selection::GetActorName(const AActor* Actor) const -{ - if (Actor == nullptr) - { - return FString("none"); - } - - return GetActorName(*Actor); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FString FCogEngineWindow_Selection::GetActorName(const AActor& Actor) const -{ -#if WITH_EDITOR - - return Config->bDisplayActorLabel ? Actor.GetActorLabel() : Actor.GetName(); - -#else //WITH_EDITOR - - return Actor.GetName(); - -#endif //WITH_EDITOR -} - -//-------------------------------------------------------------------------------------------------------------------------- -void FCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor) -{ - //------------------------ - // ContextMenu - //------------------------ - ImGui::SetNextWindowSize(ImVec2(FCogWindowWidgets::GetFontWidth() * 30, 0)); - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::Button("Reset Selection", ImVec2(-1, 0))) - { - ImGui::CloseCurrentPopup(); - SetGlobalSelection(GetLocalPlayerPawn()); - } - - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Reset the selection to the controlled actor."); - } - - if (APawn* Pawn = Cast(Actor)) - { - if (ImGui::Button("Possess", ImVec2(-1, 0))) - { - if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld())) - { - Replicator->Server_Possess(Pawn); - } - - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Possess this pawn."); - } - - if (ImGui::Button("Reset Possession", ImVec2(-1, 0))) - { - if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld())) - { - Replicator->Server_ResetPossession(); - } - - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Reset pawn."); - } - } - - ImGui::Separator(); - - ImGui::Checkbox("Save selection", &Config->bReapplySelection); - ImGui::Checkbox("Display Actor Label", &Config->bDisplayActorLabel); - - ImGui::EndPopup(); - } + return FCogWindowWidgets::ActorsListWithFilters(*GetWorld(), ActorClasses, Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn()); } //-------------------------------------------------------------------------------------------------------------------------- @@ -439,7 +283,7 @@ void FCogEngineWindow_Selection::TickSelectionMode() if (HoveredActor != nullptr) { - DrawActorFrame(*HoveredActor); + FCogWindowWidgets::ActorFrame(*HoveredActor); } if (bSelectionModeActive) @@ -463,107 +307,6 @@ void FCogEngineWindow_Selection::TickSelectionMode() } } -//-------------------------------------------------------------------------------------------------------------------------- -void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor) -{ - APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); - if (PlayerController == nullptr) - { - return; - } - - ImGuiViewport* Viewport = ImGui::GetMainViewport(); - if (Viewport == nullptr) - { - return; - } - - ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport); - - FVector BoxOrigin, BoxExtent; - - bool PrimitiveFound = false; - FBox Bounds(ForceInit); - - if (const UPrimitiveComponent* PrimitiveComponent = Cast(Actor.GetRootComponent())) - { - PrimitiveFound = true; - - Bounds += PrimitiveComponent->Bounds.GetBox(); - } - else - { - Actor.ForEachComponent(true, [&](const UPrimitiveComponent* InPrimComp) - { - if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled()) - { - Bounds += InPrimComp->Bounds.GetBox(); - PrimitiveFound = true; - } - }); - } - - if (PrimitiveFound) - { - Bounds.GetCenterAndExtents(BoxOrigin, BoxExtent); - } - else - { - BoxOrigin = Actor.GetActorLocation(); - BoxExtent = FVector(50.f, 50.f, 50.f); - } - - FVector2D ScreenPosMin, ScreenPosMax; - if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax)) - { - const ImU32 Color = (&Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128); - DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin) + Viewport->Pos, FCogImguiHelper::ToImVec2(ScreenPosMax) + Viewport->Pos, Color, 0.0f, 0, 1.0f); - FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)) + Viewport->Pos, Color, TCHAR_TO_ANSI(*GetActorName(Actor))); - } -} - -//----------------------------------------------------------------------------------------- -bool FCogEngineWindow_Selection::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); // - - - - Corners[1].Set(Extent.X, -Extent.Y, -Extent.Z); // + - - - Corners[2].Set(-Extent.X, Extent.Y, -Extent.Z); // - + - - Corners[3].Set(-Extent.X, -Extent.Y, Extent.Z); // - - + - Corners[4].Set(Extent.X, Extent.Y, -Extent.Z); // + + - - Corners[5].Set(Extent.X, -Extent.Y, Extent.Z); // + - + - Corners[6].Set(-Extent.X, Extent.Y, Extent.Z); // - + + - Corners[7].Set(Extent.X, Extent.Y, Extent.Z); // + + + - - Min.X = FLT_MAX; - Min.Y = FLT_MAX; - Max.X = -FLT_MAX; - Max.Y = -FLT_MAX; - - for (int i = 0; i < 8; ++i) - { - FVector2D ScreenLocation; - if (PlayerController->ProjectWorldLocationToScreen(Origin + Corners[i], ScreenLocation, false) == false) - { - return false; - } - - Min.X = FMath::Min(ScreenLocation.X, Min.X); - Min.Y = FMath::Min(ScreenLocation.Y, Min.Y); - Max.X = FMath::Max(ScreenLocation.X, Max.X); - Max.Y = FMath::Max(ScreenLocation.Y, Max.Y); - } - - // Prevent getting large values when the camera get close to the target - ImVec2 DisplaySize = ImGui::GetIO().DisplaySize; - Min.X = FMath::Max(-DisplaySize.x, Min.X); - Min.Y = FMath::Max(-DisplaySize.y, Min.Y); - Max.X = FMath::Min(DisplaySize.x * 2, Max.X); - Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y); - - return true; -} - //-------------------------------------------------------------------------------------------------------------------------- float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) { @@ -577,7 +320,6 @@ float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, f return -1.0f; } - //-------------------------------------------------------------------------------------------------------------------------- void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, float Width) { @@ -602,44 +344,8 @@ void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, floa } else if (SubWidgetIndex == 1) { - if (ImGui::BeginPopup("SelectionPopup")) - { - ImGui::BeginChild("Popup", ImVec2(Width, FCogWindowWidgets::GetFontWidth() * 40), false); - - if (DrawSelectionCombo()) - { - ImGui::CloseCurrentPopup(); - } - - ImGui::EndChild(); - ImGui::EndPopup(); - } - - AActor* GlobalSelection = FCogDebug::GetSelection(); - - //----------------------------------- - // Selection - //----------------------------------- - { - 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)); - FString CurrentSelectionName = GetActorName(GlobalSelection); - - if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(Width, 0.0f))) - { - ImGui::OpenPopup("SelectionPopup"); - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*CurrentSelectionName)); - } - - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(2); - - DrawActorContextMenu(GlobalSelection); - } + ImGui::SetNextItemWidth(Width); + FCogWindowWidgets::MenuActorsCombo("MenuActorSelection", *GetWorld(), ActorClasses, Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn(), [this](AActor& Actor) { RenderActorContextMenu(Actor); }); } else if (SubWidgetIndex == 2) { @@ -664,6 +370,12 @@ void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, floa } } +//-------------------------------------------------------------------------------------------------------------------------- +void FCogEngineWindow_Selection::RenderActorContextMenu(AActor& Actor) +{ + FCogEngineHelper::ActorContextMenu(Actor); +} + //-------------------------------------------------------------------------------------------------------------------------- void FCogEngineWindow_Selection::SetGlobalSelection(AActor* Value) const { diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp index 4f0b37f..83341bd 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp @@ -111,7 +111,7 @@ void FCogEngineWindow_Skeleton::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineHelper.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineHelper.h new file mode 100644 index 0000000..945f1fb --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineHelper.h @@ -0,0 +1,11 @@ +#pragma once + +#include "CoreMinimal.h" + +class COGENGINE_API FCogEngineHelper +{ +public: + + static void ActorContextMenu(AActor& Actor); + +}; diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineReplicator.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineReplicator.h index 45ef082..953712a 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineReplicator.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineReplicator.h @@ -10,7 +10,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogCogEngine, Verbose, All); class APlayerController; -using FCogEnineSpawnFunction = TFunction; +using FCogEngineSpawnFunction = TFunction; //-------------------------------------------------------------------------------------------------------------------------- UCLASS(NotBlueprintable, NotBlueprintType, notplaceable, noteditinlinenew, hidedropdown, Transient) @@ -30,9 +30,9 @@ public: APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); } - FCogEnineSpawnFunction GetSpawnFunction() const { return SpawnFunction; } + FCogEngineSpawnFunction GetSpawnFunction() const { return SpawnFunction; } - void SetSpawnFunction(FCogEnineSpawnFunction Value) { SpawnFunction = Value; } + void SetSpawnFunction(FCogEngineSpawnFunction Value) { SpawnFunction = Value; } UFUNCTION(Server, Reliable) void Server_Spawn(const FCogEngineSpawnEntry& SpawnEntry); @@ -47,6 +47,9 @@ public: UFUNCTION(Server, Reliable) void Server_ResetPossession(); + UFUNCTION(Server, Reliable) + void Server_DeleteActor(AActor* Actor); + protected: UFUNCTION(Server, Reliable) @@ -65,5 +68,5 @@ private: UPROPERTY(ReplicatedUsing = OnRep_TimeDilation) float TimeDilation = 1.0f; - FCogEnineSpawnFunction SpawnFunction; + FCogEngineSpawnFunction SpawnFunction; }; diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h index 807b0dd..a094896 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h @@ -59,26 +59,18 @@ protected: virtual bool DrawSelectionCombo(); - virtual void DrawActorContextMenu(AActor* Actor); - virtual void HackWaitInputRelease(); virtual void SetGlobalSelection(AActor* Value) const; virtual void RenderPickButtonTooltip(); + virtual void RenderActorContextMenu(AActor& Actor); + TSubclassOf GetSelectedActorClass() const; - FString GetActorName(const AActor* Actor) const; - - FString GetActorName(const AActor& Actor) const; - void TickSelectionMode(); - void DrawActorFrame(const AActor& Actor); - - bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max); - FVector LastSelectedActorLocation = FVector::ZeroVector; bool bSelectionModeActive = false; @@ -94,6 +86,8 @@ protected: TArray ConsoleCommands; TObjectPtr Config; + + ImGuiTextFilter Filter; }; //-------------------------------------------------------------------------------------------------------------------------- @@ -107,9 +101,6 @@ public: UPROPERTY(Config) bool bReapplySelection = true; - UPROPERTY(Config) - bool bDisplayActorLabel = true; - UPROPERTY(Config) FString SelectionName; @@ -121,7 +112,6 @@ public: Super::Reset(); bReapplySelection = true; - bDisplayActorLabel = true; SelectionName.Reset(); SelectedClassIndex = 0; } diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp index ef2ac81..25df74b 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp @@ -32,6 +32,25 @@ ImGuiWindow* FCogImguiHelper::GetCurrentWindow() return Context.CurrentWindow; } + +//-------------------------------------------------------------------------------------------------------------------------- +float FCogImguiHelper::GetNextItemWidth() +{ + float Width; + const ImGuiContext& g = *GImGui; + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth) + { + Width = g.NextItemData.Width; + } + else + { + const ImGuiWindow* Window = GetCurrentWindow(); + Width = Window->DC.ItemWidth; + } + + return Width; +} + //-------------------------------------------------------------------------------------------------------------------------- FColor FCogImguiHelper::ToFColor(ImU32 Color) { diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h index 8b7ac16..a40f9be 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h @@ -24,6 +24,8 @@ public: static ImGuiWindow* GetCurrentWindow(); + static float GetNextItemWidth(); + static FColor ToFColor(ImU32 Color); static FSlateRect ToSlateRect(const ImVec4& Value); diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowHelper.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowHelper.cpp new file mode 100644 index 0000000..f3678db --- /dev/null +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowHelper.cpp @@ -0,0 +1,90 @@ +#include "CogWindowHelper.h" + +#include "AssetRegistry/AssetRegistryModule.h" +#include "AssetRegistry/IAssetRegistry.h" +#include "CogDebug.h" + +//---------------------------------------------------------------------------------------------------------------------- +const UObject* FCogWindowHelper::GetFirstAssetByClass(const TSubclassOf AssetClass) +{ + const IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")).Get(); + + TArray Assets; + AssetRegistry.GetAssetsByClass(AssetClass->GetClassPathName(), Assets, true); + if (Assets.Num() == 0) + { + return nullptr; + } + + const UObject* Asset = Assets[0].GetAsset(); + return Asset; +} + +//-------------------------------------------------------------------------------------------------------------------------- +FString FCogWindowHelper::GetActorName(const AActor* Actor) +{ + if (Actor == nullptr) + { + return FString("none"); + } + + return GetActorName(*Actor); +} + +//-------------------------------------------------------------------------------------------------------------------------- +FString FCogWindowHelper::GetActorName(const AActor& Actor) +{ +#if WITH_EDITOR + + const FCogDebugSettings& Settings = FCogDebug::Settings; + return Settings.ActorNameUseLabel ? Actor.GetActorLabel() : Actor.GetName(); + +#else //WITH_EDITOR + + return Actor.GetName(); + +#endif //WITH_EDITOR +} + + +//----------------------------------------------------------------------------------------- +bool FCogWindowHelper::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); // - - - + Corners[1].Set(Extent.X, -Extent.Y, -Extent.Z); // + - - + Corners[2].Set(-Extent.X, Extent.Y, -Extent.Z); // - + - + Corners[3].Set(-Extent.X, -Extent.Y, Extent.Z); // - - + + Corners[4].Set(Extent.X, Extent.Y, -Extent.Z); // + + - + Corners[5].Set(Extent.X, -Extent.Y, Extent.Z); // + - + + Corners[6].Set(-Extent.X, Extent.Y, Extent.Z); // - + + + Corners[7].Set(Extent.X, Extent.Y, Extent.Z); // + + + + + Min.X = FLT_MAX; + Min.Y = FLT_MAX; + Max.X = -FLT_MAX; + Max.Y = -FLT_MAX; + + for (int i = 0; i < 8; ++i) + { + FVector2D ScreenLocation; + if (PlayerController->ProjectWorldLocationToScreen(Origin + Corners[i], ScreenLocation, false) == false) + { + return false; + } + + Min.X = FMath::Min(ScreenLocation.X, Min.X); + Min.Y = FMath::Min(ScreenLocation.Y, Min.Y); + Max.X = FMath::Max(ScreenLocation.X, Max.X); + Max.Y = FMath::Max(ScreenLocation.Y, Max.Y); + } + + // Prevent getting large values when the camera get close to the target + ImVec2 DisplaySize = ImGui::GetIO().DisplaySize; + Min.X = FMath::Max(-DisplaySize.x, Min.X); + Min.Y = FMath::Max(-DisplaySize.y, Min.Y); + Max.X = FMath::Min(DisplaySize.x * 2, Max.X); + Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y); + + return true; +} \ No newline at end of file diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp index d5b6619..70e1982 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp @@ -2,12 +2,14 @@ #include "CogDebug.h" #include "CogImguiHelper.h" -#include "CogImguiKeyInfo.h" #include "CogImguiInputHelper.h" +#include "CogImguiKeyInfo.h" +#include "CogWindowHelper.h" +#include "EngineUtils.h" +#include "GameFramework/PlayerInput.h" #include "imgui.h" #include "imgui_internal.h" #include "InputCoreTypes.h" -#include "GameFramework/PlayerInput.h" //-------------------------------------------------------------------------------------------------------------------------- void FCogWindowWidgets::BeginTableTooltip() @@ -26,6 +28,18 @@ void FCogWindowWidgets::EndTableTooltip() ImGui::PopStyleVar(2); } +//-------------------------------------------------------------------------------------------------------------------------- +void FCogWindowWidgets::ThinSeparatorText(const char* Label) +{ + ImGui::PushStyleVar(ImGuiStyleVar_SeparatorTextBorderSize, 2); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(100, 100, 100, 255)); + + ImGui::SeparatorText(Label); + + ImGui::PopStyleColor(); + ImGui::PopStyleVar(); +} + //-------------------------------------------------------------------------------------------------------------------------- void FCogWindowWidgets::ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay) { @@ -208,25 +222,24 @@ void FCogWindowWidgets::AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Po } //-------------------------------------------------------------------------------------------------------------------------- -void FCogWindowWidgets::MenuSearchBar(ImGuiTextFilter& Filter, float Width /*= -1*/) +void FCogWindowWidgets::SearchBar(ImGuiTextFilter& Filter, float Width /*= -1*/) { - ImGuiWindow* Window = FCogImguiHelper::GetCurrentWindow(); - ImGui::SameLine(); - ImVec2 Pos1 = Window->DC.CursorPos; - Filter.Draw("", Width); - ImVec2 Pos2 = Window->DC.CursorPos; + const ImGuiWindow* Window = FCogImguiHelper::GetCurrentWindow(); + const ImVec2 Pos1 = Window->DC.CursorPos; + Filter.Draw("##Filter", Width); + const ImVec2 Pos2 = Window->DC.CursorPosPrevLine; if (ImGui::IsItemActive() == false && Filter.Filters.empty()) { static const char* Text = "Search"; const float Height = ImGui::GetFrameHeight(); - ImGuiContext& g = *ImGui::GetCurrentContext(); - ImVec2 Min = Pos1 + ImVec2(g.Style.ItemSpacing.x, 0.0f); - ImVec2 Max = Pos2 + ImVec2(-g.Style.ItemSpacing.x, Height); - ImRect BB(Min, Max); - ImVec2 TextSize = ImGui::CalcTextSize(Text, NULL); + const ImGuiContext& g = *ImGui::GetCurrentContext(); + const ImVec2 Min = Pos1 + ImVec2(g.Style.ItemSpacing.x, 0.0f); + const ImVec2 Max = Pos2 + ImVec2(-g.Style.ItemSpacing.x, Height); + const ImRect BB(Min, Max); + const ImVec2 TextSize = ImGui::CalcTextSize(Text, nullptr); ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 128)); - ImGui::RenderTextClipped(Min, Max, Text, NULL, &TextSize, ImVec2(0.0f, 0.5f), &BB); + ImGui::RenderTextClipped(Min, Max, Text, nullptr, &TextSize, ImVec2(0.0f, 0.5f), &BB); ImGui::PopStyleColor(); } } @@ -716,4 +729,292 @@ bool FCogWindowWidgets::CollisionProfileChannels(int32& Channels) } return Result; -} \ No newline at end of file +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::ActorsListWithFilters(const UWorld& World, const TArray>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction) +{ + TSubclassOf SelectedClass = AActor::StaticClass(); + if (ActorClasses.IsValidIndex(SelectedActorClassIndex)) + { + SelectedClass = ActorClasses[SelectedActorClassIndex]; + } + + bool AddSeparator = false; + + //------------------------ + // Actor Class Combo + //------------------------ + if (ActorClasses.Num() > 1) + { + ImGui::SetNextItemWidth(18 * GetFontWidth()); + if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedClass)))) + { + for (int32 i = 0; i < ActorClasses.Num(); ++i) + { + TSubclassOf SubClass = ActorClasses[i]; + if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(SubClass)), false)) + { + SelectedActorClassIndex = i; + SelectedClass = SubClass; + } + } + ImGui::EndCombo(); + } + + AddSeparator = true; + } + + if (Filter != nullptr) + { + ImGui::SameLine(); + SearchBar(*Filter); + AddSeparator = true; + } + + if (AddSeparator) + { + ImGui::Separator(); + } + + //------------------------ + // Actor List + //------------------------ + ImGui::BeginChild("ActorsList", ImVec2(-1, -1), false); + const bool SelectionChanged = ActorsList(World, SelectedClass, Filter, LocalPlayerPawn, ContextMenuFunction); + ImGui::EndChild(); + + return SelectionChanged; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::ActorsList(const UWorld& World, const TSubclassOf ActorClass, const ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction) +{ + TArray Actors; + for (TActorIterator It(&World, ActorClass); It; ++It) + { + AActor* Actor = *It; + + bool AddActor = true; + if (Filter != nullptr && Filter->IsActive()) + { + const char* ActorName = TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(*Actor)); + if (Filter != nullptr && Filter->PassFilter(ActorName) == false) + { + AddActor = false; + } + } + + if (AddActor) + { + Actors.Add(Actor); + } + } + + const AActor* OldSelection = FCogDebug::GetSelection(); + const AActor* NewSelection = OldSelection; + + ImGuiListClipper Clipper; + Clipper.Begin(Actors.Num()); + while (Clipper.Step()) + { + for (int32 i = Clipper.DisplayStart; i < Clipper.DisplayEnd; i++) + { + AActor* Actor = Actors[i]; + if (Actor == nullptr) + { + continue; + } + + ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255)); + + const bool bIsSelected = Actor == FCogDebug::GetSelection(); + if (ImGui::Selectable(TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(*Actor)), bIsSelected)) + { + FCogDebug::SetSelection(&World, Actor); + NewSelection = Actor; + } + + ImGui::PopStyleColor(1); + + + ActorContextMenu(*Actor, ContextMenuFunction); + + //------------------------ + // Draw Frame + //------------------------ + if (ImGui::IsItemHovered()) + { + ActorFrame(*Actor); + } + + if (bIsSelected) + { + ImGui::SetItemDefaultFocus(); + } + } + } + Clipper.End(); + + return NewSelection != OldSelection; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::MenuActorsCombo(const char* StrID, const UWorld& World, TSubclassOf ActorClass, const FCogWindowActorContextMenuFunction& ContextMenuFunction) +{ + int32 SelectedActorClassIndex = 0; + const TArray ActorClasses = { ActorClass }; + + AActor* Actor = nullptr; + return MenuActorsCombo(StrID, World, ActorClasses, SelectedActorClassIndex, nullptr, nullptr, ContextMenuFunction); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::MenuActorsCombo(const char* StrID, const UWorld& World, const TArray>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction) +{ + bool Result = false; + ImGui::PushID(StrID); + + const ImVec2 Pos1 = ImGui::GetCursorScreenPos(); + const float Width = FCogImguiHelper::GetNextItemWidth(); + + //----------------------------------- + // Combo button + //----------------------------------- + { + 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)); + + TSubclassOf SelectedClass = AActor::StaticClass(); + if (ActorClasses.IsValidIndex(SelectedActorClassIndex)) + { + SelectedClass = ActorClasses[SelectedActorClassIndex]; + } + + AActor* Selection = FCogDebug::GetSelection(); + if (Selection != nullptr && Selection->IsA(SelectedClass) == false) + { + Selection = nullptr; + } + + const FString CurrentSelectionName = FCogWindowHelper::GetActorName(Selection); + if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(Width, 0.0f))) + { + ImGui::OpenPopup("ActorListPopup"); + } + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*CurrentSelectionName)); + } + + ImGui::PopStyleColor(1); + ImGui::PopStyleVar(2); + + if (Selection != nullptr) + { + ActorContextMenu(*Selection, ContextMenuFunction); + } + } + + //----------------------------------- + // Popup + //----------------------------------- + const ImVec2 Pos2 = ImGui::GetCursorScreenPos(); + ImGui::SetNextWindowPos(ImVec2(Pos1.x, Pos1.y + ImGui::GetFrameHeight())); + if (ImGui::BeginPopup("ActorListPopup")) + { + ImGui::BeginChild("Child", ImVec2(Pos2.x - Pos1.x, GetFontWidth() * 40), false); + + Result = ActorsListWithFilters(World, ActorClasses, SelectedActorClassIndex, Filter, LocalPlayerPawn, ContextMenuFunction); + if (Result) + { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndChild(); + ImGui::EndPopup(); + } + + ImGui::PopID(); + + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogWindowWidgets::ActorContextMenu(AActor& Selection, const FCogWindowActorContextMenuFunction& ContextMenuFunction) +{ + if (ContextMenuFunction == nullptr) + { + return; + } + + ImGui::SetNextWindowSize(ImVec2(GetFontWidth() * 30, 0)); + if (ImGui::BeginPopupContextItem()) + { + ContextMenuFunction(Selection); + ImGui::EndPopup(); + } +} + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogWindowWidgets::ActorFrame(const AActor& Actor) +{ + const APlayerController* PlayerController = Actor.GetWorld()->GetFirstPlayerController(); + if (PlayerController == nullptr) + { + return; + } + + ImGuiViewport* Viewport = ImGui::GetMainViewport(); + if (Viewport == nullptr) + { + return; + } + + ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport); + + FVector BoxOrigin, BoxExtent; + + bool PrimitiveFound = false; + FBox Bounds(ForceInit); + + if (const UPrimitiveComponent* PrimitiveComponent = Cast(Actor.GetRootComponent())) + { + PrimitiveFound = true; + + Bounds += PrimitiveComponent->Bounds.GetBox(); + } + else + { + Actor.ForEachComponent(true, [&](const UPrimitiveComponent* InPrimComp) + { + if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled()) + { + Bounds += InPrimComp->Bounds.GetBox(); + PrimitiveFound = true; + } + }); + } + + if (PrimitiveFound) + { + Bounds.GetCenterAndExtents(BoxOrigin, BoxExtent); + } + else + { + BoxOrigin = Actor.GetActorLocation(); + BoxExtent = FVector::ZeroVector; + } + + FVector2D ScreenPosMin, ScreenPosMax; + if (FCogWindowHelper::ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax)) + { + const ImU32 Color = (&Actor == FCogDebug::GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128); + if (ScreenPosMin != ScreenPosMax) + { + DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin) + Viewport->Pos, FCogImguiHelper::ToImVec2(ScreenPosMax) + Viewport->Pos, Color, 0.0f, 0, 1.0f); + } + AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)) + Viewport->Pos, Color, TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(Actor))); + } +} diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowHelper.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowHelper.h index 7b76f6a..ff7fa51 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowHelper.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowHelper.h @@ -1,8 +1,6 @@ #pragma once #include "AssetRegistry/AssetData.h" -#include "AssetRegistry/AssetRegistryModule.h" -#include "AssetRegistry/IAssetRegistry.h" #include "CoreMinimal.h" #include "Templates/SubclassOf.h" @@ -11,26 +9,21 @@ class COGWINDOW_API FCogWindowHelper { 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 - static const T* GetFirstAssetByClass() - { - return Cast(GetFirstAssetByClass(T::StaticClass())); - } + static const T* GetFirstAssetByClass(); - //---------------------------------------------------------------------------------------------------------------------- - static const UObject* GetFirstAssetByClass(const TSubclassOf AssetClass) - { - const IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")).Get(); - - TArray Assets; - AssetRegistry.GetAssetsByClass(AssetClass->GetClassPathName(), Assets, true); - if (Assets.Num() == 0) - { - return nullptr; - } - - const UObject* Asset = Assets[0].GetAsset(); - return Asset; - } + static const UObject* GetFirstAssetByClass(const TSubclassOf AssetClass); }; + +//---------------------------------------------------------------------------------------------------------------------- +template +const T* FCogWindowHelper::GetFirstAssetByClass() +{ + return Cast(GetFirstAssetByClass(T::StaticClass())); +} diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h index 29a333c..62bee17 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h @@ -12,6 +12,8 @@ struct FCogImGuiKeyInfo; struct FKeyBind; struct FKeyBind; +using FCogWindowActorContextMenuFunction = TFunction; + class COGWINDOW_API FCogWindowWidgets { public: @@ -20,6 +22,8 @@ public: static void EndTableTooltip(); + static void ThinSeparatorText(const char* Label); + static void ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay); static bool ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor); @@ -44,7 +48,7 @@ public: static void AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd = NULL); - static void MenuSearchBar(ImGuiTextFilter& Filter, float Width = -1.0f); + static void SearchBar(ImGuiTextFilter& Filter, float Width = -1.0f); static void PushBackColor(const ImVec4& Color); @@ -86,6 +90,17 @@ public: static bool CollisionProfileChannels(int32& Channels); + static bool MenuActorsCombo(const char* StrID, const UWorld& World, TSubclassOf ActorClass, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr); + + static bool MenuActorsCombo(const char* StrID, const UWorld& World, const TArray>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr); + + static bool ActorsListWithFilters(const UWorld& World, const TArray>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr); + + static bool ActorsList(const UWorld& World, const TSubclassOf 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); }; template diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp index f4f4688..4afbe36 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp @@ -140,7 +140,7 @@ void FCogAIWindow_BehaviorTree::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp index 428dba7..7453fa0 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp @@ -46,7 +46,7 @@ void FCogAIWindow_Blackboard::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp index 31088ce..c4f01ca 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp @@ -172,7 +172,7 @@ void FCogAbilityWindow_Abilities::RenderAbiltiesMenu(AActor* Selection) ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp index 4675ce7..7f7c6d7 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp @@ -73,7 +73,7 @@ void FCogAbilityWindow_Attributes::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp index fb30a44..846e31f 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp @@ -73,7 +73,7 @@ void FCogAbilityWindow_Effects::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp index 9729ae5..a700c09 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp @@ -67,7 +67,7 @@ void FCogAbilityWindow_Tags::RenderMenu() ImGui::EndMenu(); } - FCogWindowWidgets::MenuSearchBar(Filter); + FCogWindowWidgets::SearchBar(Filter); ImGui::EndMenuBar(); } diff --git a/Source/CogSample/CogSampleGameState.cpp b/Source/CogSample/CogSampleGameState.cpp index 41bfb4d..6b47f27 100644 --- a/Source/CogSample/CogSampleGameState.cpp +++ b/Source/CogSample/CogSampleGameState.cpp @@ -1,15 +1,12 @@ #include "CogSampleGameState.h" #include "CogSampleAbilitySystemComponent.h" -#include "CogSampleFunctionLibrary_Tag.h" #include "GameFramework/Character.h" #include "GameFramework/GameMode.h" #include "GameFramework/GameState.h" #include "Modules/ModuleManager.h" #if ENABLE_COG -#include "CogAbilityDataAsset.h" -#include "CogAbilityModule.h" #include "CogAbilityWindow_Abilities.h" #include "CogAbilityWindow_Attributes.h" #include "CogAbilityWindow_Cheats.h" @@ -19,10 +16,7 @@ #include "CogAbilityWindow_Tweaks.h" #include "CogAIWindow_BehaviorTree.h" #include "CogAIWindow_Blackboard.h" -#include "CogDebugDrawImGui.h" #include "CogDebugPlot.h" -#include "CogEngineDataAsset.h" -#include "CogEngineModule.h" #include "CogEngineWindow_CollisionTester.h" #include "CogEngineWindow_CollisionViewer.h" #include "CogEngineWindow_CommandBindings.h" @@ -42,11 +36,8 @@ #include "CogEngineWindow_Stats.h" #include "CogEngineWindow_TimeScale.h" #include "CogEngineWindow_Transform.h" -#include "CogImguiModule.h" -#include "CogInputDataAsset.h" #include "CogInputWindow_Actions.h" #include "CogInputWindow_Gamepad.h" -#include "CogSampleLogCategories.h" #include "CogSampleWindow_Team.h" #include "CogWindowManager.h"