Merge branch 'main' into pr/6

This commit is contained in:
Arnaud Jamin
2023-10-18 21:27:36 -04:00
68 changed files with 890 additions and 235 deletions
@@ -0,0 +1,3 @@
[/Script/GameplayDebugger.GameplayDebuggerUserSettings]
FontSize=15
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -514,18 +514,27 @@ void FCogDebugDraw::ReplicateShape(const UObject* WorldContextObject, const FCog
}
const ENetMode NetMode = World->GetNetMode();
if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer)
if (NetMode != NM_DedicatedServer && NetMode != NM_ListenServer)
{
TArray<ACogDebugReplicator*> Replicators;
ACogDebugReplicator::GetRemoteReplicators(*World, Replicators);
return;
}
for (ACogDebugReplicator* Replicator : Replicators)
TArray<ACogDebugReplicator*> Replicators;
ACogDebugReplicator::GetRemoteReplicators(*World, Replicators);
for (ACogDebugReplicator* Replicator : Replicators)
{
if (Replicator == nullptr)
{
if (Replicator != nullptr)
{
Replicator->ReplicatedShapes.Add(Shape);
}
continue;
}
if (FCogDebugSettings::IsReplicatedDebugActiveForObject(WorldContextObject, Replicator->GetServerSelection(), Replicator->IsServerFilteringBySelection()) == false)
{
continue;
}
Replicator->ReplicatedShapes.Add(Shape);
}
}
@@ -80,6 +80,8 @@ void ACogDebugReplicator::BeginPlay()
if (OwnerPlayerController->IsLocalController())
{
Server_RequestAllCategoriesVerbosity();
Server_SetSelection(FCogDebugSettings::GetSelection());
Server_SetIsFilteringBySelection(FCogDebugSettings::GetIsFilteringBySelection());
}
}
@@ -104,7 +106,7 @@ void ACogDebugReplicator::TickActor(float DeltaTime, enum ELevelTick TickType, F
{
if (GetWorld()->GetNetMode() == NM_Client)
{
for (FCogDebugShape ReplicatedShape : ReplicatedShapes)
for (const FCogDebugShape& ReplicatedShape : ReplicatedShapes)
{
ReplicatedShape.Draw(GetWorld());
}
@@ -195,6 +197,26 @@ void ACogDebugReplicator::Server_RequestAllCategoriesVerbosity_Implementation()
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogDebugReplicator::Server_SetIsFilteringBySelection_Implementation(bool Value)
{
#if !UE_BUILD_SHIPPING
bIsServerFilteringBySelection = Value;
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogDebugReplicator::Server_SetSelection_Implementation(AActor* Value)
{
#if !UE_BUILD_SHIPPING
ServerSelection = Value;
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
// FCogReplicatorNetPack
//--------------------------------------------------------------------------------------------------------------------------
@@ -277,4 +299,4 @@ bool FCogReplicatorNetPack::NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms
}
return true;
}
}
@@ -1,10 +1,11 @@
#include "CogDebugSettings.h"
#include "CogCommonDebugFilteredActorInterface.h"
#include "CogDebugReplicator.h"
//--------------------------------------------------------------------------------------------------------------------------
TWeakObjectPtr<AActor> FCogDebugSettings::Selection;
bool FCogDebugSettings::FilterBySelection = true;
bool FCogDebugSettings::bIsFilteringBySelection = true;
bool FCogDebugSettings::Persistent = false;
bool FCogDebugSettings::TextShadow = true;
bool FCogDebugSettings::Fade2D = true;
@@ -48,7 +49,7 @@ TArray<FString> FCogDebugSettings::SecondaryBoneWildcards =
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugSettings::Reset()
{
FilterBySelection = true;
bIsFilteringBySelection = true;
Persistent = false;
TextShadow = true;
Fade2D = true;
@@ -68,7 +69,32 @@ void FCogDebugSettings::Reset()
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugSettings::IsDebugActiveForObject(const UObject* WorldContextObject)
{
if (FilterBySelection == false)
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World == nullptr)
{
return true;
}
if (World->GetNetMode() == NM_DedicatedServer)
{
return true;
}
bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection.Get(), bIsFilteringBySelection);
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugSettings::IsReplicatedDebugActiveForObject(const UObject* WorldContextObject, const AActor* ServerSelection, bool IsServerFilteringBySelection)
{
return IsDebugActiveForObject_Internal(WorldContextObject, ServerSelection, IsServerFilteringBySelection);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugSettings::IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection)
{
if (InIsFilteringBySelection == false)
{
return true;
}
@@ -78,7 +104,7 @@ bool FCogDebugSettings::IsDebugActiveForObject(const UObject* WorldContextObject
return true;
}
const AActor* SelectionPtr = Selection.Get();
const AActor* SelectionPtr = InSelection;
if (SelectionPtr == nullptr)
{
return true;
@@ -116,9 +142,37 @@ AActor* FCogDebugSettings::GetSelection()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugSettings::SetSelection(AActor* Value)
void FCogDebugSettings::SetSelection(UWorld* World, AActor* Value)
{
Selection = Value;
if (World != nullptr && World->GetNetMode() == NM_Client)
{
if (ACogDebugReplicator* Replicator = ACogDebugReplicator::GetLocalReplicator(*World))
{
Replicator->Server_SetSelection(Value);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugSettings::GetIsFilteringBySelection()
{
return bIsFilteringBySelection;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugSettings::SetIsFilteringBySelection(UWorld* World, bool Value)
{
bIsFilteringBySelection = Value;
if (World != nullptr && World->GetNetMode() == NM_Client)
{
if (ACogDebugReplicator* Replicator = ACogDebugReplicator::GetLocalReplicator(*World))
{
Replicator->Server_SetIsFilteringBySelection(Value);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -22,7 +22,7 @@ FCogDebugShape FCogDebugShape::MakePoint(const FVector& Location, const float Si
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawPoint(UWorld* World)
void FCogDebugShape::DrawPoint(UWorld* World) const
{
#if ENABLE_COG
@@ -60,7 +60,7 @@ FCogDebugShape FCogDebugShape::MakeSegment(const FVector& StartLocation, const F
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawSegment(UWorld* World)
void FCogDebugShape::DrawSegment(UWorld* World) const
{
#if ENABLE_COG
@@ -100,7 +100,7 @@ FCogDebugShape FCogDebugShape::MakeArrow(const FVector& StartLocation, const FVe
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawArrow(UWorld* World)
void FCogDebugShape::DrawArrow(UWorld* World) const
{
#if ENABLE_COG
@@ -141,7 +141,7 @@ FCogDebugShape FCogDebugShape::MakeAxes(const FVector& Location, const FRotator&
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawAxes(UWorld* World)
void FCogDebugShape::DrawAxes(UWorld* World) const
{
#if ENABLE_COG
@@ -181,7 +181,7 @@ FCogDebugShape FCogDebugShape::MakeBox(const FVector& Center, const FRotator& Ro
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawBox(UWorld* World)
void FCogDebugShape::DrawBox(UWorld* World) const
{
#if ENABLE_COG
@@ -220,7 +220,7 @@ FCogDebugShape FCogDebugShape::MakeSolidBox(const FVector& Center, const FRotato
}
void FCogDebugShape::DrawSolidBox(UWorld* World)
void FCogDebugShape::DrawSolidBox(UWorld* World) const
{
#if ENABLE_COG
@@ -260,7 +260,7 @@ FCogDebugShape FCogDebugShape::MakeCone(const FVector& Location, const FVector&
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawCone(UWorld* World)
void FCogDebugShape::DrawCone(UWorld* World) const
{
#if ENABLE_COG
@@ -303,7 +303,7 @@ FCogDebugShape FCogDebugShape::MakeCylinder(const FVector& Center, const float R
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawCylinder(UWorld* World)
void FCogDebugShape::DrawCylinder(UWorld* World) const
{
#if ENABLE_COG
@@ -345,7 +345,7 @@ FCogDebugShape FCogDebugShape::MakeCircle(const FVector& Center, const FRotator&
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawCicle(UWorld* World)
void FCogDebugShape::DrawCicle(UWorld* World) const
{
#if ENABLE_COG
@@ -387,7 +387,7 @@ FCogDebugShape FCogDebugShape::MakeCircleArc(const FVector& Center, const FRotat
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawCicleArc(UWorld* World)
void FCogDebugShape::DrawCicleArc(UWorld* World) const
{
#if ENABLE_COG
@@ -430,7 +430,7 @@ FCogDebugShape FCogDebugShape::MakeCapsule(const FVector& Center, const FQuat& R
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawCapsule(UWorld* World)
void FCogDebugShape::DrawCapsule(UWorld* World) const
{
#if ENABLE_COG
@@ -472,7 +472,7 @@ FCogDebugShape FCogDebugShape::MakeFlatCapsule(const FVector2D& Start, const FVe
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawFlatCapsule(UWorld* World)
void FCogDebugShape::DrawFlatCapsule(UWorld* World) const
{
#if ENABLE_COG
@@ -514,7 +514,7 @@ FCogDebugShape FCogDebugShape::MakeBone(const FVector& BoneLocation, const FVect
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawBone(UWorld* World)
void FCogDebugShape::DrawBone(UWorld* World) const
{
#if ENABLE_COG
@@ -560,7 +560,7 @@ FCogDebugShape FCogDebugShape::MakePolygon(const TArray<FVector>& Verts, const F
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::DrawPolygon(UWorld* World)
void FCogDebugShape::DrawPolygon(UWorld* World) const
{
#if ENABLE_COG
@@ -590,7 +590,7 @@ void FCogDebugShape::DrawPolygon(UWorld* World)
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugShape::Draw(UWorld* World)
void FCogDebugShape::Draw(UWorld* World) const
{
switch (Type)
{
@@ -85,6 +85,16 @@ public:
UFUNCTION(Client, Reliable)
void Client_SendCategoriesVerbosity(const TArray<FCogServerCategoryData>& Categories);
AActor* GetServerSelection() const { return ServerSelection.Get(); }
UFUNCTION(Server, Reliable)
void Server_SetSelection(AActor* Value);
bool IsServerFilteringBySelection() const { return bIsServerFilteringBySelection; }
UFUNCTION(Server, Reliable)
void Server_SetIsFilteringBySelection(bool Value);
protected:
friend FCogReplicatorNetPack;
@@ -92,8 +102,10 @@ protected:
uint32 bHasAuthority : 1;
private:
UPROPERTY(Replicated)
FCogReplicatorNetPack ReplicatedData;
TWeakObjectPtr<AActor> ServerSelection = nullptr;
bool bIsServerFilteringBySelection = true;
};
@@ -9,10 +9,16 @@ public:
//----------------------------------------------------------------------------------------------------------------------
static bool IsDebugActiveForObject(const UObject* WorldContextObject);
static bool IsReplicatedDebugActiveForObject(const UObject* WorldContextObject, const AActor* ServerSelection, bool IsServerFilteringBySelection);
static AActor* GetSelection();
static void SetSelection(AActor* Value);
static void SetSelection(UWorld* World, AActor* Value);
static bool GetIsFilteringBySelection();
static void SetIsFilteringBySelection(UWorld* World, bool Value);
static bool GetDebugPersistent(bool bPersistent);
static float GetDebugDuration(bool bPersistent);
@@ -37,11 +43,6 @@ public:
static void Reset();
//----------------------------------------------------------------------------------------------------------------------
static TWeakObjectPtr<AActor> Selection;
static bool FilterBySelection;
static bool Persistent;
static bool TextShadow;
@@ -71,4 +72,12 @@ public:
static float TextSize;
static TArray<FString> SecondaryBoneWildcards;
private:
static bool IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection);
static TWeakObjectPtr<AActor> Selection;
static bool bIsFilteringBySelection;
};
@@ -58,22 +58,22 @@ struct COGDEBUG_API FCogDebugShape
static FCogDebugShape MakeFlatCapsule(const FVector2D& Start, const FVector2D& End, const float Radius, const float Z, const FColor& Color, const float Thickness, const bool bPersistent, const uint8 DepthPriority);
static FCogDebugShape MakePolygon(const TArray<FVector>& Verts, const FColor& Color, const bool bPersistent, const uint8 DepthPriority);
void DrawPoint(UWorld* World);
void DrawSegment(UWorld* World);
void DrawBone(UWorld* World);
void DrawArrow(UWorld* World);
void DrawAxes(UWorld* World);
void DrawBox(UWorld* World);
void DrawSolidBox(UWorld* World);
void DrawCone(UWorld* World);
void DrawCylinder(UWorld* World);
void DrawCicle(UWorld* World);
void DrawCicleArc(UWorld* World);
void DrawCapsule(UWorld* World);
void DrawFlatCapsule(UWorld* World);
void DrawPolygon(UWorld* World);
void DrawPoint(UWorld* World) const;
void DrawSegment(UWorld* World) const;
void DrawBone(UWorld* World) const;
void DrawArrow(UWorld* World) const;
void DrawAxes(UWorld* World) const;
void DrawBox(UWorld* World) const;
void DrawSolidBox(UWorld* World) const;
void DrawCone(UWorld* World) const;
void DrawCylinder(UWorld* World) const;
void DrawCicle(UWorld* World) const;
void DrawCicleArc(UWorld* World) const;
void DrawCapsule(UWorld* World) const;
void DrawFlatCapsule(UWorld* World) const;
void DrawPolygon(UWorld* World) const;
void Draw(UWorld* World);
void Draw(UWorld* World) const;
};
FArchive& operator<<(FArchive& Ar, FCogDebugShape& Shape);
@@ -178,4 +178,4 @@ void ACogEngineReplicator::Server_ResetPossession_Implementation()
}
#endif // !UE_BUILD_SHIPPING
}
}
@@ -17,7 +17,7 @@ void UCogEngineWindow_DebugSettings::ResetConfig()
{
Super::ResetConfig();
FilterBySelection = true;
bIsFilteringBySelection = true;
Persistent = false;
TextShadow = true;
Fade2D = true;
@@ -39,7 +39,6 @@ void UCogEngineWindow_DebugSettings::PostInitProperties()
{
Super::PostInitProperties();
FCogDebugSettings::FilterBySelection = FilterBySelection;
FCogDebugSettings::Persistent = Persistent;
FCogDebugSettings::TextShadow = TextShadow;
FCogDebugSettings::Fade2D = Fade2D;
@@ -54,6 +53,8 @@ void UCogEngineWindow_DebugSettings::PostInitProperties()
FCogDebugSettings::GradientColorIntensity = GradientColorIntensity;
FCogDebugSettings::GradientColorSpeed = GradientColorSpeed;
FCogDebugSettings::TextSize = TextSize;
FCogDebugSettings::SetIsFilteringBySelection(GetWorld(), bIsFilteringBySelection);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -61,7 +62,6 @@ void UCogEngineWindow_DebugSettings::PreSaveConfig()
{
Super::PreSaveConfig();
FilterBySelection = FCogDebugSettings::FilterBySelection;
Persistent = FCogDebugSettings::Persistent;
TextShadow = FCogDebugSettings::TextShadow;
Fade2D = FCogDebugSettings::Fade2D;
@@ -76,6 +76,8 @@ void UCogEngineWindow_DebugSettings::PreSaveConfig()
GradientColorIntensity = FCogDebugSettings::GradientColorIntensity;
GradientColorSpeed = FCogDebugSettings::GradientColorSpeed;
TextSize = FCogDebugSettings::TextSize;
bIsFilteringBySelection = FCogDebugSettings::GetIsFilteringBySelection();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -99,7 +101,11 @@ void UCogEngineWindow_DebugSettings::RenderContent()
ImGui::EndMenuBar();
}
ImGui::Checkbox("Filter by selection", &FCogDebugSettings::FilterBySelection);
if (ImGui::Checkbox("Filter by selection", &bIsFilteringBySelection))
{
FCogDebugSettings::SetIsFilteringBySelection(GetWorld(), bIsFilteringBySelection);
}
ImGui::SameLine();
FCogWindowWidgets::HelpMarker("If checked, only show the debug of the currently selected actor. Otherwise show the debug of all actors.");
@@ -1,6 +1,7 @@
#include "CogEngineWindow_LogCategories.h"
#include "CogDebugHelper.h"
#include "CogDebugSettings.h"
#include "CogWindowWidgets.h"
#include "CogDebugLog.h"
@@ -48,6 +49,8 @@ void UCogEngineWindow_LogCategories::RenderContent()
{
if (ImGui::BeginMenu("Options"))
{
FCogWindowWidgets::HelpMarker("If checked, only show the debug of the currently selected actor. Otherwise show the debug of all actors.");
ImGui::Checkbox("Show detailed verbosity", &bShowAllVerbosity);
ImGui::SameLine();
FCogWindowWidgets::HelpMarker("Show the verbosity level of each log category.");
@@ -25,7 +25,82 @@ void UCogEngineWindow_Selection::RenderHelp()
UCogEngineWindow_Selection::UCogEngineWindow_Selection()
{
bHasMenu = true;
SubClasses = { AActor::StaticClass(), ACharacter::StaticClass() };
ActorClasses = { AActor::StaticClass(), ACharacter::StaticClass() };
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Selection::ResetConfig()
{
Super::ResetConfig();
SelectedClassIndex = 0;
SelectionName = FString();
bReapplySelection = true;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Selection::PreSaveConfig()
{
Super::PreSaveConfig();
SelectionName = GetNameSafe(GetSelection());
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Selection::PostInitProperties()
{
Super::PostInitProperties();
TryReapplySelection();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Selection::TryReapplySelection() const
{
UWorld* World = GetWorld();
if (World == nullptr)
{
return;
}
if (bReapplySelection == false)
{
return;
}
if (SelectionName.IsEmpty())
{
return;
}
TSubclassOf<AActor> SelectedClass = GetSelectedActorClass();
if (SelectedClass == nullptr)
{
return;
}
TArray<AActor*> Actors;
for (TActorIterator<AActor> It(World, SelectedClass); It; ++It)
{
AActor* Actor = *It;
if (GetNameSafe(Actor) == SelectionName)
{
SetGlobalSelection(Actor);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
TSubclassOf<AActor> UCogEngineWindow_Selection::GetSelectedActorClass() const
{
TSubclassOf<AActor> SelectedClass = AActor::StaticClass();
if (ActorClasses.IsValidIndex(SelectedClassIndex))
{
SelectedClass = ActorClasses[SelectedClassIndex];
}
return SelectedClass;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -82,7 +157,7 @@ void UCogEngineWindow_Selection::RenderTick(float DeltaTime)
if (FCogDebugSettings::GetSelection() == nullptr)
{
FCogDebugSettings::SetSelection(GetLocalPlayerPawn());
SetGlobalSelection(GetLocalPlayerPawn());
}
if (bSelectionModeActive)
@@ -129,14 +204,18 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo()
// Actor Class Combo
//------------------------
TSubclassOf<AActor> SelectedClass = GetSelectedActorClass();
ImGui::SetNextItemWidth(-1);
if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedSubClass))))
if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedClass))))
{
for (TSubclassOf<AActor> ItSubClass : SubClasses)
for (int32 i = 0; i < ActorClasses.Num(); ++i)
{
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(ItSubClass)), false))
TSubclassOf<AActor> SubClass = ActorClasses[i];
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(SubClass)), false))
{
SelectedSubClass = ItSubClass;
SelectedClassIndex = i;
SelectedClass = SubClass;
}
}
ImGui::EndCombo();
@@ -150,7 +229,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo()
ImGui::BeginChild("ActorList", ImVec2(-1, -1), false);
TArray<AActor*> Actors;
for (TActorIterator<AActor> It(GetWorld(), SelectedSubClass); It; ++It)
for (TActorIterator<AActor> It(GetWorld(), SelectedClass); It; ++It)
{
AActor* Actor = *It;
Actors.Add(Actor);
@@ -174,7 +253,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo()
const FString ActorName = GetNameSafe(Actor);
if (ImGui::Selectable(TCHAR_TO_ANSI(*ActorName), bIsSelected))
{
FCogDebugSettings::SetSelection(Actor);
SetGlobalSelection(Actor);
SelectionChanged = true;
}
@@ -208,13 +287,13 @@ void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor)
//------------------------
// ContextMenu
//------------------------
ImGui::SetNextWindowSize(ImVec2(FCogWindowWidgets::GetFontWidth() * 20, 0));
ImGui::SetNextWindowSize(ImVec2(FCogWindowWidgets::GetFontWidth() * 30, 0));
if (ImGui::BeginPopupContextItem())
{
if (ImGui::Button("Reset Selection", ImVec2(-1, 0)))
{
ImGui::CloseCurrentPopup();
FCogDebugSettings::SetSelection(GetLocalPlayerPawn());
SetGlobalSelection(GetLocalPlayerPawn());
}
if (ImGui::IsItemHovered())
@@ -251,6 +330,10 @@ void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor)
}
}
ImGui::Separator();
ImGui::Checkbox("Save selection", &bReapplySelection);
ImGui::EndPopup();
}
}
@@ -276,12 +359,14 @@ void UCogEngineWindow_Selection::TickSelectionMode()
return;
}
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
DrawList->AddRect(ImVec2(0, 0), ImGui::GetIO().DisplaySize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
FCogWindowWidgets::AddTextWithShadow(DrawList, ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
AActor* HoveredActor = nullptr;
TSubclassOf<AActor> SelectedActorClass = GetSelectedActorClass();
AActor* HoveredActor = nullptr;
FVector WorldOrigin, WorldDirection;
if (UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToVector2D(ImGui::GetMousePos()), WorldOrigin, WorldDirection))
{
@@ -292,7 +377,7 @@ void UCogEngineWindow_Selection::TickSelectionMode()
{
if (HitResult.GetActor() != nullptr)
{
if (HitResult.GetActor()->GetClass()->IsChildOf(SelectedSubClass))
if (SelectedActorClass == nullptr || HitResult.GetActor()->GetClass()->IsChildOf(SelectedActorClass))
{
HoveredActor = HitResult.GetActor();
}
@@ -313,7 +398,7 @@ void UCogEngineWindow_Selection::TickSelectionMode()
{
if (HoveredActor != nullptr)
{
FCogDebugSettings::SetSelection(HoveredActor);
SetGlobalSelection(HoveredActor);
}
DeactivateSelectionMode();
@@ -478,15 +563,15 @@ void UCogEngineWindow_Selection::RenderMainMenuWidget(bool Draw, float& Width)
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::SameLine();
FString SelectionName = GetNameSafe(GlobalSelection);
FString CurrentSelectionName = GetNameSafe(GlobalSelection);
if (ImGui::Button(TCHAR_TO_ANSI(*SelectionName), ImVec2(SelectionButtonWidth, 0)))
if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(SelectionButtonWidth, 0)))
{
ImGui::OpenPopup("SelectionPopup");
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*SelectionName));
ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*CurrentSelectionName));
}
ImGui::PopStyleColor(1);
@@ -504,7 +589,7 @@ void UCogEngineWindow_Selection::RenderMainMenuWidget(bool Draw, float& Width)
ImGui::SameLine();
if (ImGui::Button("X", ImVec2(ResetButtonWidth, 0)))
{
FCogDebugSettings::SetSelection(nullptr);
SetGlobalSelection(nullptr);
ImGui::CloseCurrentPopup();
}
if (ImGui::IsItemHovered())
@@ -514,4 +599,16 @@ void UCogEngineWindow_Selection::RenderMainMenuWidget(bool Draw, float& Width)
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(1);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_Selection::SetGlobalSelection(AActor* Value) const
{
FCogDebugSettings::SetSelection(GetWorld(), Value);
}
//--------------------------------------------------------------------------------------------------------------------------
AActor* UCogEngineWindow_Selection::GetGlobalSelection(AActor* Value) const
{
return FCogDebugSettings::GetSelection();
}
@@ -28,7 +28,7 @@ protected:
private:
UPROPERTY(Config)
bool FilterBySelection = true;
bool bIsFilteringBySelection = true;
UPROPERTY(Config)
bool Persistent = false;
@@ -5,7 +5,7 @@
#include "CogWindow.h"
#include "CogEngineWindow_Selection.generated.h"
UCLASS()
UCLASS(Config = Cog)
class COGENGINE_API UCogEngineWindow_Selection : public UCogWindow
{
GENERATED_BODY()
@@ -16,20 +16,24 @@ public:
bool GetIsSelecting() const { return bSelectionModeActive; }
void SetCurrentActorSubClass(TSubclassOf<AActor> Value) { SelectedSubClass = Value; }
const TArray<TSubclassOf<AActor>>& GetActorClasses() const { return ActorClasses; }
TSubclassOf<AActor> GetCurrentActorSubClass() const { return SelectedSubClass; }
const TArray<TSubclassOf<AActor>>& GetActorSubClasses() const { return SubClasses; }
void SetActorSubClasses(const TArray<TSubclassOf<AActor>>& Value) { SubClasses = Value; }
void SetActorClasses(const TArray<TSubclassOf<AActor>>& Value) { ActorClasses = Value; }
ETraceTypeQuery GetTraceType() const { return TraceType; }
void SetTraceType(ETraceTypeQuery Value) { TraceType = Value; }
void TryReapplySelection() const;
protected:
virtual void ResetConfig() override;
virtual void PreSaveConfig() override;
virtual void PostInitProperties() override;
virtual void RenderHelp() override;
virtual void RenderTick(float DeltaTime) override;
@@ -38,16 +42,22 @@ protected:
virtual void RenderMainMenuWidget(bool Draw, float& Width) override;
bool DrawSelectionCombo();
virtual bool DrawSelectionCombo();
void DrawActorContextMenu(AActor* Actor);
virtual void DrawActorContextMenu(AActor* Actor);
void ActivateSelectionMode();
virtual void ActivateSelectionMode();
void HackWaitInputRelease();
virtual void HackWaitInputRelease();
virtual void SetGlobalSelection(AActor* Value) const;
virtual AActor* GetGlobalSelection(AActor* Value) const;
private:
TSubclassOf<AActor> GetSelectedActorClass() const;
void TickSelectionMode();
void ToggleSelectionMode();
@@ -58,6 +68,15 @@ private:
bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max);
UPROPERTY(Config)
bool bReapplySelection = true;
UPROPERTY(Config)
FString SelectionName;
UPROPERTY(Config)
int32 SelectedClassIndex = 0;
FVector LastSelectedActorLocation = FVector::ZeroVector;
bool bSelectionModeActive = false;
@@ -66,9 +85,7 @@ private:
int32 WaitInputReleased = 0;
TSubclassOf<AActor> SelectedSubClass;
TArray<TSubclassOf<AActor>> SubClasses;
TArray<TSubclassOf<AActor>> ActorClasses;
ETraceTypeQuery TraceType = TraceTypeQuery1;
};
@@ -375,7 +375,8 @@ void UCogWindowManager::RenderMenuItem(UCogWindow& Window, const char* MenuItemN
{
if (bShowWindowsInMainMenu)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 1),
ImGui::SetNextWindowSizeConstraints(
ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 5),
ImVec2(FCogWindowWidgets::GetFontWidth() * 50, ImGui::GetTextLineHeightWithSpacing() * 60));
if (ImGui::BeginMenu(MenuItemName))
@@ -7,6 +7,7 @@
#include "BehaviorTree/Tasks/BTTask_BlueprintBase.h"
#include "BehaviorTree/Tasks/BTTask_Wait.h"
#include "BrainComponent.h"
#include "CogImguiHelper.h"
#include "CogWindowWidgets.h"
#include "GameFramework/Pawn.h"
#include "imgui_internal.h"
@@ -35,6 +36,8 @@ void UCogAIWindow_BehaviorTree::RenderContent()
{
if (ImGui::BeginMenu("Options"))
{
ImGui::ColorEdit4("Active Color", (float*)&ActiveColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Inactive Color", (float*)&InactiveColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::EndMenu();
}
@@ -78,6 +81,19 @@ void UCogAIWindow_BehaviorTree::RenderContent()
return;
}
UBehaviorTree* RootTree = BehaviorTreeComponent->GetRootTree();
if (CurrentTree != RootTree)
{
if (ImGui::CollapsingHeader(TCHAR_TO_ANSI(*GetNameSafe(RootTree)), nullptr, ImGuiTreeNodeFlags_DefaultOpen))
{
RenderNode(*BehaviorTreeComponent, RootTree->RootNode, false);
ImGui::Spacing();
ImGui::Spacing();
}
}
//----------------------------------------------------------------------------------------
// If we use the current tree root node it doesn't seem to be the one instanced.
// Not sure if there is a better way to access it, but we find the root node from
@@ -92,37 +108,22 @@ void UCogAIWindow_BehaviorTree::RenderContent()
if (RootNodeInstanced != nullptr)
{
RenderNode(BehaviorTreeComponent, RootNodeInstanced, false);
if (ImGui::CollapsingHeader(TCHAR_TO_ANSI(*GetNameSafe(CurrentTree)), nullptr, ImGuiTreeNodeFlags_DefaultOpen))
{
RenderNode(*BehaviorTreeComponent, const_cast<UBTNode*>(RootNodeInstanced), false);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren)
void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent& BehaviorTreeComponent, UBTNode* Node, bool OpenAllChildren)
{
FString NodeNameStr;
if (const UBTTask_BlueprintBase* Wait = Cast<UBTTask_BlueprintBase>(Node))
{
NodeNameStr = Node->GetNodeName();
}
else
{
NodeNameStr = Node->GetStaticDescription();
}
const char* NodeName = TCHAR_TO_ANSI(*NodeNameStr);
const char* NodeName = TCHAR_TO_ANSI(*Node->GetNodeName());
const bool ShowNode = Filter.PassFilter(NodeName);
const UBTCompositeNode* CompositeNode = Cast<UBTCompositeNode>(Node);
bool IsActive = false;
for (const UBTNode* ActiveParentNode = BehaviorTreeComponent->GetActiveNode(); ActiveParentNode != nullptr; ActiveParentNode = ActiveParentNode->GetParentNode())
{
if (Node == ActiveParentNode)
{
IsActive = true;
break;
}
}
const bool IsActive = BehaviorTreeComponent.IsExecutingBranch(Node);
bool OpenChildren = false;
@@ -171,11 +172,66 @@ void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeC
//------------------------
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::BeginDisabled();
ImGui::Text(NodeName);
ImGui::EndDisabled();
ImGui::EndTooltip();
FCogWindowWidgets::BeginTableTooltip();
if (ImGui::BeginTable("Effect", 2, ImGuiTableFlags_Borders))
{
ImGui::TableSetupColumn("Property");
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
const ImVec4 TextColor(1.0f, 1.0f, 1.0f, 0.5f);
//------------------------
// Name
//------------------------
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Name");
ImGui::TableNextColumn();
ImGui::Text("%s", NodeName);
//------------------------
// Static Description
//------------------------
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Description");
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*Node->GetStaticDescription()));
//------------------------
// Runtime Values
//------------------------
TArray<FString> RunTimeValues;
uint8* NodeMemory = BehaviorTreeComponent.GetNodeMemory(Node, BehaviorTreeComponent.GetActiveInstanceIdx());
Node->DescribeRuntimeValues(BehaviorTreeComponent, NodeMemory, EBTDescriptionVerbosity::Detailed, RunTimeValues);
for (const FString& RuntimeValue : RunTimeValues)
{
ImGui::TableNextRow();
FString Left, Right;
if (RuntimeValue.Split(TEXT(": "), &Left, &Right))
{
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, TCHAR_TO_ANSI(*Left));
ImGui::TableNextColumn();
ImGui::Text("%s", TCHAR_TO_ANSI(*Right));
}
else
{
ImGui::TableNextColumn();
ImGui::TextColored(TextColor, "Value");
ImGui::TableNextColumn();
ImGui::Text(TCHAR_TO_ANSI(*RuntimeValue));
}
}
ImGui::EndTable();
}
FCogWindowWidgets::EndTableTooltip();
}
//------------------------
@@ -200,7 +256,7 @@ void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeC
// Name
//------------------------
ImGui::SameLine();
ImVec4 NameColor = IsActive ? ImVec4(0.0f, 1.0f, 0.0f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 0.6f);
const ImVec4 NameColor = IsActive ? FCogImguiHelper::ToImVec4(ActiveColor) : FCogImguiHelper::ToImVec4(InactiveColor);
ImGui::TextColored(NameColor, "%s", NodeName);
}
@@ -213,7 +269,7 @@ void UCogAIWindow_BehaviorTree::RenderNode(UBehaviorTreeComponent* BehaviorTreeC
{
for (int32 i = 0; i < CompositeNode->GetChildrenNum(); ++i)
{
const UBTNode* ChildNode = CompositeNode->GetChildNode(i);
UBTNode* ChildNode = CompositeNode->GetChildNode(i);
RenderNode(BehaviorTreeComponent, ChildNode, OpenAllChildren);
}
}
@@ -82,6 +82,29 @@ void UCogAIWindow_Blackboard::RenderContent()
return;
}
TArray<const FBlackboardEntry*> Keys;
uint8 Offset = 0;
for (UBlackboardData* It = BlackboardAsset; It; It = It->Parent)
{
for (int32 KeyID = 0; KeyID < It->Keys.Num(); KeyID++)
{
if (const FBlackboardEntry* Key = BlackboardAsset->GetKey(KeyID))
{
Keys.Add(Key);
}
}
Offset += It->Keys.Num();
}
if (bSortByName)
{
Keys.Sort([](const FBlackboardEntry& Key1, const FBlackboardEntry& Key2)
{
return Key1.EntryName.Compare(Key1.EntryName) < 0;
});
}
if (ImGui::BeginTable("Blackboard", 3, ImGuiTableFlags_SizingFixedFit
| ImGuiTableFlags_Resizable
| ImGuiTableFlags_NoBordersInBodyUntilResize
@@ -101,39 +124,43 @@ void UCogAIWindow_Blackboard::RenderContent()
const FString CommonTypePrefix = UBlackboardKeyType::StaticClass()->GetName().AppendChar(TEXT('_'));
uint8 Offset = 0;
for (UBlackboardData* It = BlackboardAsset; It; It = It->Parent)
for (int32 KeyID = 0; KeyID < Keys.Num(); ++KeyID)
{
for (int32 KeyID = 0; KeyID < It->Keys.Num(); KeyID++)
const FBlackboardEntry* Key = Keys[KeyID];
if (Key == nullptr)
{
const FBlackboardEntry* Key = BlackboardAsset->GetKey(KeyID);
if (Key == nullptr)
{
continue;
}
const char* KeyName = TCHAR_TO_ANSI(*Key->EntryName.ToString());
if (Filter.PassFilter(KeyName) == false)
{
continue;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
const FString FullKeyType = Key->KeyType ? GetNameSafe(Key->KeyType->GetClass()) : FString();
const FString DescKeyType = FullKeyType.StartsWith(CommonTypePrefix) ? FullKeyType.RightChop(CommonTypePrefix.Len()) : FullKeyType;
ImGui::Text("%s", TCHAR_TO_ANSI(*DescKeyType));
ImGui::TableNextColumn();
ImGui::Text("%s", KeyName);
ImGui::TableNextColumn();
const uint8* ValueData = Blackboard->GetKeyRawData(KeyID);
FString ValueDesc = Key->KeyType && ValueData ? *(Key->KeyType->WrappedDescribeValue(*Blackboard, ValueData)) : TEXT("Empty");
ImGui::Text("%s", TCHAR_TO_ANSI(*ValueDesc));
continue;
}
Offset += It->Keys.Num();
const char* KeyName = TCHAR_TO_ANSI(*Key->EntryName.ToString());
if (Filter.PassFilter(KeyName) == false)
{
continue;
}
ImGui::TableNextRow();
//------------------------
// Type
//------------------------
ImGui::TableNextColumn();
const FString FullKeyType = Key->KeyType ? GetNameSafe(Key->KeyType->GetClass()) : FString();
const FString DescKeyType = FullKeyType.StartsWith(CommonTypePrefix) ? FullKeyType.RightChop(CommonTypePrefix.Len()) : FullKeyType;
ImGui::Text("%s", TCHAR_TO_ANSI(*DescKeyType));
//------------------------
// Name
//------------------------
ImGui::TableNextColumn();
ImGui::Text("%s", KeyName);
//------------------------
// Value
//------------------------
ImGui::TableNextColumn();
const uint8* ValueData = Blackboard->GetKeyRawData(KeyID);
FString ValueDesc = Key->KeyType && ValueData ? *(Key->KeyType->WrappedDescribeValue(*Blackboard, ValueData)) : TEXT("Empty");
ImGui::Text("%s", TCHAR_TO_ANSI(*ValueDesc));
}
ImGui::EndTable();
@@ -22,9 +22,15 @@ protected:
virtual void RenderContent() override;
virtual void RenderNode(UBehaviorTreeComponent* BehaviorTreeComponent, const UBTNode* Node, bool OpenAllChildren);
virtual void RenderNode(UBehaviorTreeComponent& BehaviorTreeComponent, UBTNode* Node, bool OpenAllChildren);
private:
UPROPERTY(Config)
FVector4f ActiveColor = FVector4f(1.0f, 1.0f, 1.0f, 1.0f);
UPROPERTY(Config)
FVector4f InactiveColor = FVector4f(1.0f, 1.0f, 1.0f, 0.2f);
ImGuiTextFilter Filter;
};
@@ -38,6 +38,7 @@ void UCogInputWindow_Gamepad::ResetConfig()
ButtonColor = FVector4f(0.2f, 0.2f, 0.2f, 1.0f);
BorderColor = FVector4f(0.03f, 0.03f, 0.03f, 1.0f);
PressedColor = FVector4f(0.6f, 0.6f, 0.6f, 1.0f);
HoveredColor = FVector4f(0.3f, 0.3f, 0.3f, 1.0f);
InjectColor = FVector4f(1.0f, 0.5f, 0.0f, 0.5f);
Border = 0.02f;
}
@@ -105,8 +106,7 @@ void UCogInputWindow_Gamepad::AddButton(const FKey& Key, const ImVec2& RelativeP
const ImVec2& Size = RelativeSize * CanvasSize.x;
const ImVec2 Position = (CanvasMin + CanvasSize * RelativePosition) - Alignment * Size;
ImU32 Color = ImGui::GetColorU32(ImLerp(FCogImguiHelper::ToImVec4(ButtonColor), FCogImguiHelper::ToImVec4(PressedColor), Value));
bool IsPressed = false;
FCogInjectActionInfo* ActionInfo = Actions.Find(Key);
if (ActionInfo != nullptr)
{
@@ -114,7 +114,7 @@ void UCogInputWindow_Gamepad::AddButton(const FKey& Key, const ImVec2& RelativeP
{
if (Input->GetActionValue(ActionInfo->Action).Get<bool>())
{
Color = FCogImguiHelper::ToImU32(PressedColor);
IsPressed = true;
}
}
}
@@ -125,6 +125,16 @@ void UCogInputWindow_Gamepad::AddButton(const FKey& Key, const ImVec2& RelativeP
OnButtonClicked(ActionInfo);
}
ImU32 Color = FCogImguiHelper::ToImU32(ButtonColor);
if (IsPressed)
{
Color = FCogImguiHelper::ToImU32(PressedColor);
}
else if (ImGui::IsItemHovered())
{
Color = FCogImguiHelper::ToImU32(HoveredColor);
}
InputContextMenu(Key, ActionInfo, nullptr);
if (Border > 0.0f)
@@ -144,8 +154,6 @@ void UCogInputWindow_Gamepad::AddStick(const FKey& Key2D, const FKey& KeyBool, b
{
ImGui::PushID((void*)(&Key2D));
ImU32 Color = Input->GetKeyValue(KeyBool) > 0.0f ? FCogImguiHelper::ToImU32(PressedColor) : FCogImguiHelper::ToImU32(ButtonColor);
FCogInjectActionInfo* ActionInfoBool = Actions.Find(KeyBool);
FCogInjectActionInfo* ActionInfo2D = Actions.Find(Key2D);
@@ -169,6 +177,16 @@ void UCogInputWindow_Gamepad::AddStick(const FKey& Key2D, const FKey& KeyBool, b
OnButtonClicked(ActionInfoBool);
}
ImU32 Color = FCogImguiHelper::ToImU32(ButtonColor);
if (Input->GetKeyValue(KeyBool) > 0.0f)
{
Color = FCogImguiHelper::ToImU32(PressedColor);
}
else if (ImGui::IsItemHovered())
{
Color = FCogImguiHelper::ToImU32(HoveredColor);
}
InputContextMenu(Key2D, ActionInfoBool, ActionInfo2D);
if (Border > 0.0f)
@@ -302,11 +320,12 @@ void UCogInputWindow_Gamepad::RenderContent()
ImGui::Checkbox("Invert Left Stick Y", &bInvertLeftStickY);
ImGui::Checkbox("Invert Right Stick Y", &bInvertRightStickY);
ImGui::Separator();
ImGui::ColorEdit4("Background Color", (float*)&BackgroundColor, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit4("Border Color", (float*)&BorderColor, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit4("Button Color", (float*)&ButtonColor, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit4("Pressed Color", (float*)&PressedColor, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit4("Inject Color", (float*)&InjectColor, ImGuiColorEditFlags_NoInputs);
ImGui::ColorEdit4("Background Color", (float*)&BackgroundColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Border Color", (float*)&BorderColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Button Color", (float*)&ButtonColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Pressed Color", (float*)&PressedColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Hovered Color", (float*)&HoveredColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
ImGui::ColorEdit4("Inject Color", (float*)&InjectColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf);
FCogWindowWidgets::SliderWithReset("Border", &Border, 0.0f, 0.1f, 0.02f, "%0.3f");
ImGui::EndPopup();
}
@@ -63,6 +63,9 @@ private:
UPROPERTY(Config)
FVector4f PressedColor = FVector4f(0.6f, 0.6f, 0.6f, 1.0f);
UPROPERTY(Config)
FVector4f HoveredColor = FVector4f(0.3f, 0.3f, 0.3f, 1.0f);
UPROPERTY(Config)
FVector4f InjectColor = FVector4f(1.0f, 0.5f, 0.0f, 0.5f);
+8 -5
View File
@@ -4,7 +4,7 @@ Cog is a set of debug tools for Unreal Engine built on top of [Dear ImGui](https
![Cog](https://github.com/arnaud-jamin/Cog/assets/13844285/21659aea-2cd8-4ef6-b3b0-5795f5f3246b)
- [Video](https://www.youtube.com/watch?v=ea5hz3cFcMM)
- [Sample Executable](https://drive.google.com/file/d/1T7jQFoZ5rd6goBtDH-FCbjn6Kr1RzUCE/view?usp=sharing) (300 MB)
- [Sample Executable (Windows)](https://drive.google.com/file/d/1T7jQFoZ5rd6goBtDH-FCbjn6Kr1RzUCE/view?usp=sharing) (300 MB)
Cog provides:
- ImGui windows to inspect and configure various Unreal systems (Core Engine, Enhanced Inputs, Gameplay Abilities, AI)
@@ -48,7 +48,7 @@ Displays the gameplay attributes of the selected actor.
### Behavior Tree
Displays the behavior tree of the selected actor.
![Behavior Tree](https://github.com/arnaud-jamin/Cog/assets/13844285/2e3ab30f-414a-497d-be08-605e1d299d23)
![Behavior Tree](https://github.com/arnaud-jamin/Cog/assets/13844285/c799e85f-b641-4d6f-9476-54a5cbd73c65)
### Blackboard
Displays the blackboard of the selected actor.
@@ -111,14 +111,15 @@ Can be used to activate and deactivate log categories
- The log categories are used to filter both the output log and the debug draw.
### Metric
Gather various values sent by the selected actor and compte their rate per second. This is typically useful to compute the damage dealt or received per second.
Gather various values sent by the selected actor and compte their rate per second. This is typically used to compute the damage dealt or received per second.
![Metric](https://github.com/arnaud-jamin/Cog/assets/13844285/64d3cb7c-8731-4897-9ef9-b0868148ebe2)
- The following code shows how to add a metric:
```cpp
// Adding a metric
FCogDebugMetric::AddMetric(this, "Damage Dealt", Params.MitigatedDamage, Params.UnmitigatedDamage, false);
FCogDebugMetric::AddMetric(this, "Damage Dealt", MitigatedDamage, UnmitigatedDamage, false);
```
![Metric](https://github.com/arnaud-jamin/Cog/assets/13844285/64d3cb7c-8731-4897-9ef9-b0868148ebe2)
### Net Emulation
Used to configure the network emulation
@@ -242,6 +243,7 @@ You must have Unreal 5.1 or greater and Visual Studio to launch the sample
The Cog repository has the following structure:
- `CogSample` - A Sample that demonstrate various Cog functionalities. The project was saved in Unreal 5.1
- `Plugins/CogAbility` - ImGui windows for the Gameplay Ability System (Abilities, Effects, Tags, ...)
- `Plugins/CogAI` - ImGui windows for AI (Behavior Tree, Blackboard)
- `Plugins/CogInput` - ImGui windows for the Enhanced Input library (Input action, Gamepad)
- `Plugins/Cog` - The main Cog plugin which contains the following modules
- `CogEngine` - ImGui windows for the core unreal engine functionalities (Log, Stats, Time, Collisions, Skeleton, ...)
@@ -265,6 +267,7 @@ public class CogSample : ModuleRules
PublicDependencyModuleNames.AddRange(new string[]
{
"CogCommon", // The CogCommon is required on all target configuration
"AIModule",
"Core",
"CoreUObject",
"Engine",
+1
View File
@@ -8,6 +8,7 @@ public class CogSample : ModuleRules
PublicDependencyModuleNames.AddRange(new string[]
{
"AIModule",
"CogCommon",
"Core",
"CoreUObject",
@@ -0,0 +1,33 @@
#include "CogSampleAbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "GameplayCueManager.h"
#include "GameplayEffectTypes.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleAbilitySystemComponent::ExecuteGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const
{
if (AActor* ActorAvatar = AbilityActorInfo->AvatarActor.Get())
{
UAbilitySystemGlobals::Get().GetGameplayCueManager()->HandleGameplayCue(ActorAvatar, GameplayCueTag, EGameplayCueEvent::Type::Executed, GameplayCueParameters);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleAbilitySystemComponent::AddGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const
{
if (AActor* ActorAvatar = AbilityActorInfo->AvatarActor.Get())
{
UAbilitySystemGlobals::Get().GetGameplayCueManager()->HandleGameplayCue(ActorAvatar, GameplayCueTag, EGameplayCueEvent::Type::OnActive, GameplayCueParameters);
UAbilitySystemGlobals::Get().GetGameplayCueManager()->HandleGameplayCue(ActorAvatar, GameplayCueTag, EGameplayCueEvent::Type::WhileActive, GameplayCueParameters);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleAbilitySystemComponent::RemoveGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const
{
if (AActor* ActorAvatar = AbilityActorInfo->AvatarActor.Get())
{
UAbilitySystemGlobals::Get().GetGameplayCueManager()->HandleGameplayCue(ActorAvatar, GameplayCueTag, EGameplayCueEvent::Type::Removed, GameplayCueParameters);
}
}
@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "CogSampleAbilitySystemComponent.generated.h"
UCLASS(BlueprintType)
class UCogSampleAbilitySystemComponent : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "GameplayCue", Meta = (AutoCreateRefTerm = "GameplayCueParameters", GameplayTagFilter = "GameplayCue"))
void ExecuteGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const;
UFUNCTION(BlueprintCallable, Category = "GameplayCue", Meta = (AutoCreateRefTerm = "GameplayCueParameters", GameplayTagFilter = "GameplayCue"))
void AddGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const;
UFUNCTION(BlueprintCallable, Category = "GameplayCue", Meta = (AutoCreateRefTerm = "GameplayCueParameters", GameplayTagFilter = "GameplayCue"))
void RemoveGameplayCueLocal(const FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters) const;
};
@@ -0,0 +1,14 @@
#include "CogSampleBTTask_BlueprintBase.h"
//--------------------------------------------------------------------------------------------------------------------------
FString UCogSampleBTTask_BlueprintBase::GetStaticDescription() const
{
FString CustomDescripton = GetCustomStaticDescription();
if (CustomDescripton.IsEmpty() == false)
{
return CustomDescripton;
}
return Super::GetStaticDescription();
}
@@ -0,0 +1,18 @@
#pragma once
#include "CoreMinimal.h"
#include "BehaviorTree/Tasks/BTTask_BlueprintBase.h"
#include "CogSampleBTTask_BlueprintBase.generated.h"
UCLASS(Abstract, Blueprintable)
class UCogSampleBTTask_BlueprintBase : public UBTTask_BlueprintBase
{
GENERATED_BODY()
public:
virtual FString GetStaticDescription() const override;
UFUNCTION(BlueprintImplementableEvent, Category = AI)
FString GetCustomStaticDescription() const;
};
+66 -11
View File
@@ -2,6 +2,7 @@
#include "Camera/CameraComponent.h"
#include "CogCommon.h"
#include "CogSampleAbilitySystemComponent.h"
#include "CogSampleAttributeSet_Health.h"
#include "CogSampleAttributeSet_Misc.h"
#include "CogSampleCharacterMovementComponent.h"
@@ -64,9 +65,9 @@ ACogSampleCharacter::ACogSampleCharacter(const FObjectInitializer& ObjectInitial
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));
AbilitySystem = CreateDefaultSubobject<UCogSampleAbilitySystemComponent>(TEXT("AbilitySystem"));
AbilitySystem->SetIsReplicated(true);
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
AbilitySystem->SetReplicationMode(EGameplayEffectReplicationMode::Full);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -108,6 +109,7 @@ void ACogSampleCharacter::BeginPlay()
}
TryFinishInitialize();
RefreshServerAnimTickOption();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -243,22 +245,31 @@ void ACogSampleCharacter::InitializeAbilitySystem()
AbilitySystem->GiveAbility(Spec);
}
int32 Index = 0;
for (FActiveAbilityInfo& AbilityInfo : ActiveAbilities)
for (int32 i = 0; i < ActiveAbilities.Num(); ++i)
{
const FActiveAbilityInfo& AbilityInfo = ActiveAbilities[i];
const FGameplayAbilitySpec Spec(AbilityInfo.Ability, 1, INDEX_NONE, this);
FGameplayAbilitySpecHandle Handle = AbilitySystem->GiveAbility(Spec);
const FGameplayAbilitySpecHandle Handle = AbilitySystem->GiveAbility(Spec);
ActiveAbilityHandles.Add(Handle);
if (FGameplayAbilitySpec* AddedSpec = AbilitySystem->FindAbilitySpecFromHandle(Handle))
const FGameplayAbilitySpec* AddedSpec = AbilitySystem->FindAbilitySpecFromHandle(Handle);
if (AddedSpec == nullptr)
{
if (UCogSampleGameplayAbility* Ab = Cast<UCogSampleGameplayAbility>(AddedSpec->GetPrimaryInstance()))
{
Ab->SetCooldownTag(UCogSampleFunctionLibrary_Tag::ActiveAbilityCooldownTags[Index]);
}
continue;
}
Index++;
UCogSampleGameplayAbility* Ability = Cast<UCogSampleGameplayAbility>(AddedSpec->GetPrimaryInstance());
if (Ability == nullptr)
{
continue;
}
if (UCogSampleFunctionLibrary_Tag::ActiveAbilityCooldownTags.IsValidIndex(i) == false)
{
continue;
}
Ability->SetCooldownTag(UCogSampleFunctionLibrary_Tag::ActiveAbilityCooldownTags[i]);
}
UpdateActiveAbilitySlots();
@@ -639,6 +650,29 @@ void ACogSampleCharacter::OnScaleAttributeChanged(const FOnAttributeChangeData&
MARK_PROPERTY_DIRTY_FROM_NAME(ACogSampleCharacter, Scale, this);
OnRep_Scale();
RefreshServerAnimTickOption();
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::RefreshServerAnimTickOption()
{
const UCapsuleComponent* Capsule = GetCapsuleComponent();
if (Capsule == nullptr)
{
return;
}
USkeletalMeshComponent* SkeletalMesh = GetMesh();
if (SkeletalMesh == nullptr)
{
return;
}
const float ScaledHalfHeight = Capsule->GetScaledCapsuleHalfHeight();
const bool IsBigEnoughToSimulateBonesOnServer = ScaledHalfHeight > 200;
SkeletalMesh->VisibilityBasedAnimTickOption = IsBigEnoughToSimulateBonesOnServer ? EVisibilityBasedAnimTickOption::AlwaysTickPoseAndRefreshBones
: EVisibilityBasedAnimTickOption::OnlyTickMontagesWhenNotRendered;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -765,3 +799,24 @@ void ACogSampleCharacter::GetTargetCapsules(TArray<const UCapsuleComponent*>& Ca
Capsules.Add(GetCapsuleComponent());
}
//--------------------------------------------------------------------------------------------------------------------------
bool ACogSampleCharacter::GetMontage(FName MontageName, UAnimMontage*& Montage, bool bPrintWarning) const
{
Montage = nullptr;
if (MontageTable == nullptr)
{
return false;
}
static FString ContextString(TEXT("GetMontage"));
FCogSampleMontageTableRow* Row = MontageTable->FindRow<FCogSampleMontageTableRow>(MontageName, ContextString, bPrintWarning);
if (Row == nullptr)
{
return false;
}
Montage = Row->Montage;
return Montage != nullptr;
}
+38 -10
View File
@@ -8,6 +8,7 @@
#include "CogCommonDebugFilteredActorInterface.h"
#include "CogSampleDamageEvent.h"
#include "CogSampleDefines.h"
#include "CogSampleDamageableInterface.h"
#include "CogSampleTargetableInterface.h"
#include "CogSampleTeamInterface.h"
#include "GameFramework/Character.h"
@@ -16,9 +17,9 @@
#include "InputActionValue.h"
#include "CogSampleCharacter.generated.h"
class UAbilitySystemComponent;
class UCogAbilitySystemComponent;
class UCameraComponent;
class UCogAbilitySystemComponent;
class UCogSampleAbilitySystemComponent;
class UGameplayAbility;
class UGameplayEffect;
class UInputAction;
@@ -58,6 +59,19 @@ public:
bool ActivateWhenGiven = false;
};
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FCogSampleMontageTableRow : public FTableRowBase
{
GENERATED_BODY()
public:
FCogSampleMontageTableRow() {}
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UAnimMontage* Montage = nullptr;
};
//--------------------------------------------------------------------------------------------------------------------------
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleCharacterEventDelegate, ACogSampleCharacter*, Character);
@@ -69,6 +83,7 @@ class ACogSampleCharacter : public ACharacter
, public ICogCommonAllegianceActorInterface
, public ICogSampleTeamInterface
, public ICogSampleTargetableInterface
, public ICogSampleDamageableInterface
{
GENERATED_BODY()
@@ -118,6 +133,14 @@ public:
virtual void GetTargetCapsules(TArray<const UCapsuleComponent*>& Capsules) const override;
//----------------------------------------------------------------------------------------------------------------------
// ICogSampleDamageableInterface overrides
//----------------------------------------------------------------------------------------------------------------------
virtual void HandleDamageReceived(const FCogSampleDamageEventParams& Params) override;
virtual void HandleDamageDealt(const FCogSampleDamageEventParams& Params) override;
//----------------------------------------------------------------------------------------------------------------------
// Team
//----------------------------------------------------------------------------------------------------------------------
@@ -182,16 +205,12 @@ public:
UFUNCTION(BlueprintPure)
bool IsInitialized() const { return bIsInitialized; }
void HandleDamageReceived(const FCogSampleDamageEventParams& Params);
void HandleDamageDealt(const FCogSampleDamageEventParams& Params);
void OnKilled(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
UPROPERTY(BlueprintReadOnly, Category = Ability, meta = (AllowPrivateAccess = "true"))
UAbilitySystemComponent* AbilitySystem = nullptr;
UCogSampleAbilitySystemComponent* AbilitySystem = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Ability)
TArray<TSubclassOf<UAttributeSet>> AttributeSets;
@@ -229,10 +248,21 @@ public:
UFUNCTION(BlueprintCallable)
int32 ApplyRootMotion(const FCogSampleRootMotionParams& Params);
//----------------------------------------------------------------------------------------------------------------------
// Montage
//----------------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Animation", meta = (RowType = "/Script/CogSample.FCogSampleMontageTableRow"))
UDataTable* MontageTable = nullptr;
UFUNCTION(BlueprintCallable, BlueprintPure=false)
bool GetMontage(FName MontageName, UAnimMontage*& Montage, bool bPrintWarning) const;
private:
friend class ACogSamplePlayerController;
void RefreshServerAnimTickOption();
UPROPERTY()
AController* InitialController = nullptr;
@@ -272,8 +302,6 @@ private:
void OnGameplayEffectRemoved(const FActiveGameplayEffect& RemovedGameplayEffect);
void OnCooldownEffectUpdated(const FActiveGameplayEffect& GameplayEffect, bool bIsEffectRemoved);
void OnGhostTagNewOrRemoved(const FGameplayTag InTag, int32 NewCount);
void OnScaleAttributeChanged(const FOnAttributeChangeData& Data);
-23
View File
@@ -1,26 +1,3 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleDamageEvent.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FCogSampleDamageEventParams
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
float MitigatedDamage = 0;
UPROPERTY(BlueprintReadWrite)
float UnmitigatedDamage = 0;
UPROPERTY(BlueprintReadWrite)
AActor* DamageDealer = nullptr;
UPROPERTY(BlueprintReadWrite)
AActor* DamageReceiver = nullptr;
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleDamageEventDelegate, const FCogSampleDamageEventParams&, Params);
@@ -0,0 +1,45 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleDamageableInterface.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FCogSampleDamageEventParams
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite)
float MitigatedDamage = 0;
UPROPERTY(BlueprintReadWrite)
float UnmitigatedDamage = 0;
UPROPERTY(BlueprintReadWrite)
AActor* DamageDealer = nullptr;
UPROPERTY(BlueprintReadWrite)
AActor* DamageReceiver = nullptr;
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleDamageEventDelegate, const FCogSampleDamageEventParams&, Params);
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogSampleDamageableInterface : public UInterface
{
GENERATED_BODY()
};
//--------------------------------------------------------------------------------------------------------------------------
class ICogSampleDamageableInterface
{
GENERATED_BODY()
public:
virtual void HandleDamageReceived(const FCogSampleDamageEventParams& Params) {}
virtual void HandleDamageDealt(const FCogSampleDamageEventParams& Params) {}
};
@@ -1,8 +1,11 @@
#include "CogSampleExecCalculation_Damage.h"
#include "CogSampleAbilitySystemComponent.h"
#include "CogSampleAttributeSet_Health.h"
#include "CogSampleCharacter.h"
#include "CogSampleDamageableInterface.h"
#include "CogSampleFunctionLibrary_Tag.h"
#include "CogSampleGameplayEffectContext.h"
//--------------------------------------------------------------------------------------------------------------------------
struct FCogSampleDamageStatics
@@ -37,22 +40,37 @@ UCogSampleExecCalculation_Damage::UCogSampleExecCalculation_Damage()
void UCogSampleExecCalculation_Damage::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams, OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
const FGameplayEffectSpec& EffectSpec = ExecutionParams.GetOwningSpec();
const FGameplayEffectContextHandle Context = EffectSpec.GetContext();
FGameplayEffectContextHandle EffectContext = EffectSpec.GetContext();
FAggregatorEvaluateParameters EvaluationParameters;
EvaluationParameters.SourceTags = EffectSpec.CapturedSourceTags.GetAggregatedTags();
EvaluationParameters.TargetTags = EffectSpec.CapturedTargetTags.GetAggregatedTags();
UAbilitySystemComponent* TargetAbilitySystem = ExecutionParams.GetTargetAbilitySystemComponent();
UAbilitySystemComponent* SourceAbilitySystem = ExecutionParams.GetSourceAbilitySystemComponent();
ACogSampleCharacter* TargetCharacter = (TargetAbilitySystem != nullptr) ? Cast<ACogSampleCharacter>(TargetAbilitySystem->AbilityActorInfo.IsValid() ? TargetAbilitySystem->GetAvatarActor() : nullptr) : nullptr;
ACogSampleCharacter* SourceCharacter = (SourceAbilitySystem != nullptr) ? Cast<ACogSampleCharacter>(SourceAbilitySystem->AbilityActorInfo.IsValid() ? SourceAbilitySystem->GetAvatarActor() : nullptr) : nullptr;
UCogSampleAbilitySystemComponent* TargetAbilitySystem = Cast<UCogSampleAbilitySystemComponent>(ExecutionParams.GetTargetAbilitySystemComponent());
AActor* TargetActor = (TargetAbilitySystem != nullptr) ? TargetAbilitySystem->GetAvatarActor() : nullptr;
if (TargetCharacter == nullptr)
UCogSampleAbilitySystemComponent* SourceAbilitySystem = Cast<UCogSampleAbilitySystemComponent>(ExecutionParams.GetSourceAbilitySystemComponent());
AActor* SourceActor = (SourceAbilitySystem != nullptr) ? SourceAbilitySystem->GetAvatarActor() : nullptr;
if (TargetActor == nullptr)
{
return;
}
FHitResult HitResult;
if (const FHitResult* HitResultPtr = EffectContext.GetHitResult())
{
HitResult = *HitResultPtr;
}
else
{
HitResult.Location = TargetActor->GetActorLocation();
HitResult.Normal = TargetActor->GetActorForwardVector();
HitResult.ImpactNormal = TargetActor->GetActorForwardVector();
EffectContext.AddHitResult(HitResult, true);
}
FGameplayTagContainer SpecAssetTags;
EffectSpec.GetAllAssetTags(SpecAssetTags);
@@ -88,16 +106,75 @@ void UCogSampleExecCalculation_Damage::Execute_Implementation(const FGameplayEff
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UCogSampleAttributeSet_Health::GetHealthAttribute(), EGameplayModOp::Additive, -MitigatedDamage));
FCogSampleDamageEventParams Params;
Params.DamageDealer = SourceCharacter;
Params.DamageReceiver = TargetCharacter;
Params.DamageDealer = SourceActor;
Params.DamageReceiver = TargetActor;
Params.MitigatedDamage = MitigatedDamage;
Params.UnmitigatedDamage = UnmitigatedDamage;
TargetCharacter->HandleDamageReceived(Params);
if (SourceCharacter != nullptr)
if (ICogSampleDamageableInterface* DamageReceiver = Cast<ICogSampleDamageableInterface>(TargetActor))
{
SourceCharacter->HandleDamageDealt(Params);
DamageReceiver->HandleDamageReceived(Params);
}
if (ICogSampleDamageableInterface* DamageDealer = Cast<ICogSampleDamageableInterface>(SourceActor))
{
DamageDealer->HandleDamageDealt(Params);
}
}
UCogSampleFunctionLibrary_Damage::ExecuteDamageGameplayCue(TargetAbilitySystem, HitResult, MitigatedDamage, EffectContext, false);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleFunctionLibrary_Damage::ExecuteDamageGameplayCue(
UCogSampleAbilitySystemComponent* TargetAbilitySystem,
const FHitResult& HitResult,
float Damage,
const FGameplayEffectContextHandle& EffectContext,
bool IsPredicted)
{
ensure(TargetAbilitySystem);
if (TargetAbilitySystem == nullptr)
{
return;
}
AActor* TargetActor = TargetAbilitySystem->GetAvatarActor();
if (TargetActor == nullptr)
{
return;
}
FCogSampleGameplayEffectContext* TypedContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext);
ensure(TypedContext);
if (TypedContext == nullptr)
{
return;
}
TypedContext->bGameplayCueIsPredicted = IsPredicted;
//-----------------------------------------------------------------------------------------------------
// We check for >= 1 instead of >= 0 because we can use damage values between 0 and 1.
//-----------------------------------------------------------------------------------------------------
if (Damage > 0.0f)
{
FGameplayCueParameters GameplayCueParameters;
GameplayCueParameters.RawMagnitude = Damage;
GameplayCueParameters.EffectContext = EffectContext;
GameplayCueParameters.Instigator = TypedContext->GetInstigator();
GameplayCueParameters.EffectCauser = TypedContext->GetEffectCauser();
GameplayCueParameters.PhysicalMaterial = HitResult.PhysMaterial;
GameplayCueParameters.Location = HitResult.Location;
GameplayCueParameters.Normal = HitResult.ImpactNormal;
if (IsPredicted)
{
TargetAbilitySystem->ExecuteGameplayCueLocal(Tag_GameplayCue_DamageReceived, GameplayCueParameters);
}
else
{
TargetAbilitySystem->ExecuteGameplayCue(Tag_GameplayCue_DamageReceived, GameplayCueParameters);
}
}
}
@@ -2,8 +2,13 @@
#include "CoreMinimal.h"
#include "GameplayEffectExecutionCalculation.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "CogSampleExecCalculation_Damage.generated.h"
class UCogSampleAbilitySystemComponent;
struct FHitResult;
struct FGameplayEffectContextHandle;
UCLASS()
class UCogSampleExecCalculation_Damage : public UGameplayEffectExecutionCalculation
{
@@ -14,3 +19,20 @@ public:
virtual void Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams, OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const override;
};
UCLASS(meta = (ScriptName = "CogSampleFunctionLibrary_Damage"))
class COGSAMPLE_API UCogSampleFunctionLibrary_Damage : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static void ExecuteDamageGameplayCue(
UCogSampleAbilitySystemComponent* TargetAbilitySystem,
const FHitResult& HitResult,
float HealthDamage,
const FGameplayEffectContextHandle& EffectContext,
bool IsPredicted);
};
@@ -34,6 +34,8 @@ UE_DEFINE_GAMEPLAY_TAG(Tag_Effect_Type_Heal_Full, "Effect.Type.Heal.Full");
UE_DEFINE_GAMEPLAY_TAG(Tag_Effect_Type_Heal_Revive, "Effect.Type.Heal.Revive");
UE_DEFINE_GAMEPLAY_TAG(Tag_Effect_Type_Hidden, "Effect.Type.Hidden");
UE_DEFINE_GAMEPLAY_TAG(Tag_GameplayCue_DamageReceived, "GameplayCue.DamageReceived");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Dead, "Status.Dead");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Ghost, "Status.Ghost");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Immobilized, "Status.Immobilized");
@@ -36,6 +36,8 @@ UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Effect_Type_Heal_Full);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Effect_Type_Heal_Revive);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Effect_Type_Hidden);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_GameplayCue_DamageReceived);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Dead);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Ghost);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Immobilized);
+1 -2
View File
@@ -164,8 +164,7 @@ void ACogSampleGameState::InitializeCog()
CogWindowManager->CreateWindow<UCogEngineWindow_Plots>("Engine.Plots");
UCogEngineWindow_Selection* SelectionWindow = CogWindowManager->CreateWindow<UCogEngineWindow_Selection>("Engine.Selection");
SelectionWindow->SetActorSubClasses({ AActor::StaticClass(), AGameModeBase::StaticClass(), AGameStateBase::StaticClass(), ACharacter::StaticClass() });
SelectionWindow->SetCurrentActorSubClass(ACharacter::StaticClass());
SelectionWindow->SetActorClasses({ ACharacter::StaticClass(), AActor::StaticClass(), AGameModeBase::StaticClass(), AGameStateBase::StaticClass() });
SelectionWindow->SetTraceType(UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Pawn));
CogWindowManager->CreateWindow<UCogEngineWindow_Scalability>("Engine.Scalability");
@@ -249,4 +249,15 @@ void UCogSampleEffectContextLibrary::EffectContextGetAllFloatValues(FGameplayEff
{
Entries = TypedEffectContext->FloatValues;
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleEffectContextLibrary::EffectContextGetGameplayCueIsPredicted(FGameplayEffectContextHandle EffectContext)
{
if (FCogSampleGameplayEffectContext* TypedEffectContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext))
{
return TypedEffectContext->bGameplayCueIsPredicted;
}
return false;
}
@@ -65,6 +65,11 @@ public:
bool CanGameplayCueBePredicted();
/* NOT REPLICATED - Is this effect context made for a local gameplay cue. Used to know if a remote gameplay cue
* created by the local player should be filtered when a local gameplay cue is played instead.
*/
bool bGameplayCueIsPredicted = false;
/* REPLICATED */
UPROPERTY()
TArray<FCogSampleGameplayEffectContextFloatValue> FloatValues;
@@ -91,6 +96,9 @@ class UCogSampleEffectContextLibrary : public UBlueprintFunctionLibrary
public:
UFUNCTION(BlueprintPure)
static bool EffectContextGetGameplayCueIsPredicted(FGameplayEffectContextHandle EffectContext);
UFUNCTION(BlueprintCallable)
static void EffectContextSetFloatValue(FGameplayEffectContextHandle EffectContext, FName Name, float Value);
@@ -1,4 +1,5 @@
#pragma once
#include "CoreMinimal.h"
DECLARE_LOG_CATEGORY_EXTERN(LogCogAlways, VeryVerbose, All);
+1 -10
View File
@@ -1,23 +1,14 @@
- CogImGui: Add a way to create and override CogImguiwidget
- CogImGui: Try to find a global solution to prevent crash when breaking in a blueprint from an imgui action (reset the stack)
- CogDebug: Add log category description
- CogWindow: Add reset window position menu item or reset layout (window can get far away)
- CogWindow: Try to remove CogWindow dependency to cogimgui. Should only depends on imgui (currently use setdpiscale of cogimgui)
- CogWindow: Add reset window position menu item or reset layout (window can get far away)
- CogEngine: Save selection window settings (current actor and category)
- CogEngine: More stats in the stats window
- CogEngine: Overlay mode of stats.
- CogEngine: Stat main menu widget could have a tooltip on each stat with a control to change set the emulation (FPS, Ping, Packetloss)
- CogEngine: Skeleton window selectable have wrong height
- CogEngine: Property grid
- CogEngine: user settings
- CogInput: Add multiple IMC on the input data asset. Maybe propose a current imc
- CogInput: Add mouse over highlight on the buttons of the gamepad window
- CogAbilities: Apply tweaks on spawn
@@ -25,4 +16,4 @@
- CogSample: Create more abilities
- CogSample: Add area of effects in the level
- CogAI: Create a CogAI project with windows for BT and other AI tools
- CogPackage: in package mode the Gameplay Cues are not visible.