mirror of
https://github.com/Ed94/Cog.git
synced 2026-06-13 00:01:37 -07:00
CogEngine: Fix and improve Plot window
CogEngine: Fix and improve the Plot window - Fix ImPlot assert - Improve UI CogSample: - Add Inputs and AnimNotify plot events - Fix ability system warning
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "CogEngineWindow_Plots.h"
|
||||
|
||||
#include "CogDebugPlot.h"
|
||||
#include "CogImguiHelper.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "Engine/World.h"
|
||||
#include "imgui.h"
|
||||
@@ -80,7 +81,7 @@ void FCogEngineWindow_Plots::RenderMenu()
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
if (ImGui::MenuItem("Clear Data"))
|
||||
if (ImGui::MenuItem("Clear data"))
|
||||
{
|
||||
FCogDebugPlot::Clear();
|
||||
}
|
||||
@@ -101,11 +102,27 @@ void FCogEngineWindow_Plots::RenderMenu()
|
||||
}
|
||||
|
||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||
if (ImGui::SliderFloat("Time Range", &Config->TimeRange, 1.0f, 30.0f, "%0.1f"))
|
||||
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 30.0f, "%0.1f"))
|
||||
{
|
||||
bApplyTimeScale = true;
|
||||
}
|
||||
|
||||
|
||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||
ImGui::SliderFloat("Drag view sensitivity", &Config->DragViewSensitivity, 1.0f, 50.0f, "%0.0f");
|
||||
|
||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||
ImGui::Checkbox("Show time bar at game time", &Config->ShowTimeBarAtGameTime);
|
||||
|
||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||
ImGui::Checkbox("Show time bar at cursor", &Config->ShowTimeBarAtCursor);
|
||||
|
||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||
ImGui::Checkbox("Show value at cursor", &Config->ShowValueAtCursor);
|
||||
|
||||
constexpr ImGuiColorEditFlags ColorEditFlags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||
FCogImguiHelper::ColorEdit4("Pause background color", Config->PauseBackgroundColor, ColorEditFlags);
|
||||
ImGui::SetItemTooltip("Background color of the plot when paused.");
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
@@ -124,22 +141,35 @@ void FCogEngineWindow_Plots::RenderPlotsList(TArray<FCogDebugPlotEntry*>& Visibl
|
||||
|
||||
ImGui::Indent(6);
|
||||
|
||||
for (FCogDebugPlotEntry& Entry : FCogDebugPlot::Plots)
|
||||
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
|
||||
{
|
||||
if (Entry.CurrentYAxis != ImAxis_COUNT && Entry.CurrentRow != INDEX_NONE)
|
||||
if (Plot.CurrentYAxis != ImAxis_COUNT && Plot.CurrentRow != INDEX_NONE)
|
||||
{
|
||||
VisiblePlots.Add(&Entry);
|
||||
VisiblePlots.Add(&Plot);
|
||||
}
|
||||
|
||||
ImGui::PushID(Index);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Entry.IsEventPlot ? IM_COL32(128, 128, 255, 255) : IM_COL32(255, 255, 255, 255));
|
||||
ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Name.ToString()), false, 0);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, Plot.IsEventPlot ? IM_COL32(128, 128, 255, 255) : IM_COL32(255, 255, 255, 255));
|
||||
|
||||
const bool IsAssignedToRow = Plot.CurrentRow != INDEX_NONE;
|
||||
if (ImGui::Selectable(TCHAR_TO_ANSI(*Plot.Name.ToString()), IsAssignedToRow, ImGuiSelectableFlags_AllowDoubleClick))
|
||||
{
|
||||
if (IsAssignedToRow)
|
||||
{
|
||||
Plot.ResetAxis();
|
||||
}
|
||||
else
|
||||
{
|
||||
Plot.AssignAxis(0, ImAxis_Y1);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
|
||||
{
|
||||
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
|
||||
const auto EntryName = StringCast<ANSICHAR>(*Plot.Name.ToString());
|
||||
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
|
||||
ImGui::Text("%s", EntryName.Get());
|
||||
ImGui::EndDragDropSource();
|
||||
@@ -174,6 +204,13 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
|
||||
static float RowRatios[] = { 1, 1, 1, 1, 1, 1 };
|
||||
static float ColRatios[] = { 1 };
|
||||
static ImPlotSubplotFlags SubplotsFlags = ImPlotSubplotFlags_LinkCols;
|
||||
|
||||
const bool PushPlotBgStyle = FCogDebugPlot::Pause;
|
||||
if (PushPlotBgStyle)
|
||||
{
|
||||
ImPlot::PushStyleColor(ImPlotCol_PlotBg, FCogImguiHelper::ToImVec4(Config->PauseBackgroundColor));
|
||||
}
|
||||
|
||||
if (ImPlot::BeginSubplots("", Config->Rows, 1, ImVec2(-1, -1), SubplotsFlags, RowRatios, ColRatios))
|
||||
{
|
||||
for (int PlotIndex = 0; PlotIndex < Config->Rows; ++PlotIndex)
|
||||
@@ -209,94 +246,136 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
|
||||
Config->TimeRange = TimeRange;
|
||||
}
|
||||
|
||||
const float Time = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Setup all the Z and Y axis limits. Must be done before calling
|
||||
// ImPlot::GetPlotPos or ImPlot::GetPlotSize as it calls SetupLock()
|
||||
//------------------------------------------------------------------
|
||||
{
|
||||
//--------------------------------------------------------------------------------
|
||||
// Make the time axis move forward automatically, unless the user pauses or zoom.
|
||||
//--------------------------------------------------------------------------------
|
||||
if (FCogDebugPlot::Pause == false && ImGui::GetIO().MouseWheel == 0)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, Time - TimeRange, Time, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
if (bApplyTimeScale)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, Time - Config->TimeRange, Time, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Set the Y axis limit for Events.
|
||||
//--------------------------------------------------------------------------------
|
||||
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
|
||||
{
|
||||
if (PlotPtr == nullptr)
|
||||
{ continue; }
|
||||
|
||||
if (PlotPtr->CurrentRow != PlotIndex)
|
||||
{ continue; }
|
||||
|
||||
if (PlotPtr->IsEventPlot)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(PlotPtr->CurrentYAxis, 0, PlotPtr->MaxRow + 2, ImGuiCond_Always);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ImVec2 PlotMin = ImPlot::GetPlotPos();
|
||||
const ImVec2 PlotSize = ImPlot::GetPlotSize();
|
||||
const ImVec2 PlotMax = PlotMin + PlotSize;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Draw a vertical lines representing the current time and the mouse time
|
||||
// Pause the scrolling if the user drag inside
|
||||
//----------------------------------------------------------------
|
||||
RenderTimeMarker();
|
||||
const ImVec2 Mouse = ImGui::GetMousePos();
|
||||
if (Mouse.x > PlotMin.x
|
||||
&& Mouse.y > PlotMin.y
|
||||
&& Mouse.x < PlotMax.x
|
||||
&& Mouse.y < PlotMax.y
|
||||
&& ImGui::GetDragDropPayload() == nullptr)
|
||||
{
|
||||
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
|
||||
if (FMath::Abs(Drag.x) > Config->DragViewSensitivity)
|
||||
{
|
||||
FCogDebugPlot::Pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
FCogDebugPlot::Pause = false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Draw a vertical lines representing the current time and the mouse time
|
||||
//---------------------------------------------------------------------------
|
||||
if (Config->ShowTimeBarAtGameTime || Config->ShowTimeBarAtGameTime)
|
||||
{
|
||||
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
|
||||
|
||||
const float PlotTop = PlotMin.y;
|
||||
const float TimeBarBottom = PlotTop + PlotSize.y;
|
||||
|
||||
ImPlot::PushPlotClipRect();
|
||||
if (Config->ShowTimeBarAtCursor)
|
||||
{
|
||||
PlotDrawList->AddLine(ImVec2(ImGui::GetMousePos().x, PlotTop), ImVec2(ImGui::GetMousePos().x, TimeBarBottom), IM_COL32(128, 128, 128, 64));
|
||||
}
|
||||
|
||||
if (Config->ShowTimeBarAtGameTime && FCogDebugPlot::Pause)
|
||||
{
|
||||
const float TimeBarX = ImPlot::PlotToPixels(Time, 0.0f).x;
|
||||
PlotDrawList->AddLine(ImVec2(TimeBarX, PlotTop), ImVec2(TimeBarX, TimeBarBottom), IM_COL32(255, 255, 255, 64));
|
||||
}
|
||||
ImPlot::PopPlotClipRect();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Draw all the plots assigned to this row
|
||||
//-----------------------------------------------------------
|
||||
for (FCogDebugPlotEntry* PlotPtr : VisiblePlots)
|
||||
{
|
||||
if (PlotPtr == nullptr)
|
||||
{ continue; }
|
||||
|
||||
FCogDebugPlotEntry& Plot = *PlotPtr;
|
||||
if (Plot.CurrentRow != PlotIndex)
|
||||
{ continue; }
|
||||
|
||||
ImPlot::SetAxis(Plot.CurrentYAxis);
|
||||
|
||||
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
|
||||
const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString());
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Plot Events
|
||||
//-------------------------------------------------------
|
||||
if (Plot.IsEventPlot)
|
||||
{
|
||||
continue;
|
||||
RenderEvents(Plot, Label.Get(), PlotMin, PlotMax);
|
||||
}
|
||||
//-------------------------------------------------------
|
||||
// Plot Values
|
||||
//-------------------------------------------------------
|
||||
else if (Plot.Values.empty() == false)
|
||||
{
|
||||
RenderValues(Plot, Label.Get());
|
||||
}
|
||||
|
||||
FCogDebugPlotEntry& Entry = *PlotPtr;
|
||||
|
||||
if (Entry.Values.empty())
|
||||
//-------------------------------------------------------
|
||||
// Allow legend item labels to be drag and drop sources
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::BeginDragDropSourceItem(Label.Get()))
|
||||
{
|
||||
continue;
|
||||
const auto EntryName = StringCast<ANSICHAR>(*Plot.Name.ToString());
|
||||
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
|
||||
ImGui::TextUnformatted(EntryName.Get());
|
||||
ImPlot::EndDragDropSource();
|
||||
}
|
||||
|
||||
if (Entry.CurrentRow == PlotIndex)
|
||||
{
|
||||
//--------------------------------------------------------------------------------
|
||||
// Make the time axis move forward automatically, unless the user pauses or zoom.
|
||||
//--------------------------------------------------------------------------------
|
||||
if (FCogDebugPlot::Pause == false && ImGui::GetIO().MouseWheel == 0)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, Entry.Time - TimeRange, Entry.Time, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
if (bApplyTimeScale)
|
||||
{
|
||||
ImPlot::SetupAxisLimits(ImAxis_X1, Entry.Time - Config->TimeRange, Entry.Time, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
ImPlot::SetAxis(Entry.CurrentYAxis);
|
||||
|
||||
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
|
||||
const auto Label = StringCast<ANSICHAR>(*Entry.Name.ToString());
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Pause the scrolling if the user drag inside
|
||||
//----------------------------------------------------------------
|
||||
const ImVec2 Mouse = ImGui::GetMousePos();
|
||||
if (Mouse.x > PlotMin.x
|
||||
&& Mouse.y > PlotMin.y
|
||||
&& Mouse.x < PlotMax.x
|
||||
&& Mouse.y < PlotMax.y
|
||||
&& ImGui::GetDragDropPayload() == nullptr)
|
||||
{
|
||||
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
|
||||
if (FMath::Abs(Drag.x) > 10)
|
||||
{
|
||||
FCogDebugPlot::Pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Plot Events
|
||||
//-------------------------------------------------------
|
||||
const bool IsEventPlot = Entry.Events.Num() > 0;
|
||||
if (IsEventPlot)
|
||||
{
|
||||
RenderEvents(Entry, Label.Get(), PlotMin, PlotMax);
|
||||
}
|
||||
//-------------------------------------------------------
|
||||
// Plot Values
|
||||
//-------------------------------------------------------
|
||||
else
|
||||
{
|
||||
RenderValues(Entry, Label.Get());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Allow legend item labels to be drag and drop sources
|
||||
//-------------------------------------------------------
|
||||
if (ImPlot::BeginDragDropSourceItem(Label.Get()))
|
||||
{
|
||||
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
|
||||
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
|
||||
ImGui::TextUnformatted(EntryName.Get());
|
||||
ImPlot::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
@@ -352,45 +431,37 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
|
||||
}
|
||||
ImPlot::EndSubplots();
|
||||
}
|
||||
|
||||
if (PushPlotBgStyle)
|
||||
{
|
||||
ImPlot::PopStyleColor();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineWindow_Plots::RenderTimeMarker() const
|
||||
{
|
||||
const ImVec2 PlotMin = ImPlot::GetPlotPos();
|
||||
const ImVec2 PlotSize = ImPlot::GetPlotSize();
|
||||
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
|
||||
|
||||
const float PlotTop = PlotMin.y;
|
||||
const float TimeBarBottom = PlotTop + PlotSize.y;
|
||||
|
||||
ImPlot::PushPlotClipRect();
|
||||
PlotDrawList->AddLine(ImVec2(ImGui::GetMousePos().x, PlotTop), ImVec2(ImGui::GetMousePos().x, TimeBarBottom), IM_COL32(128, 128, 128, 64));
|
||||
if (FCogDebugPlot::Pause)
|
||||
{
|
||||
const float Time = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0;
|
||||
const float TimeBarX = ImPlot::PlotToPixels(Time, 0.0f).x;
|
||||
PlotDrawList->AddLine(ImVec2(TimeBarX, PlotTop), ImVec2(TimeBarX, TimeBarBottom), IM_COL32(255, 255, 255, 64));
|
||||
}
|
||||
ImPlot::PopPlotClipRect();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char* Label)
|
||||
void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const
|
||||
{
|
||||
//----------------------------------------------------------------
|
||||
// Custom tooltip
|
||||
// Value at cursor tooltip
|
||||
//----------------------------------------------------------------
|
||||
if (ImPlot::IsPlotHovered())
|
||||
if (Config->ShowValueAtCursor && ImPlot::IsPlotHovered())
|
||||
{
|
||||
float Value;
|
||||
if (Entry.FindValue(ImPlot::GetPlotMousePos().x, Value))
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s: %0.2f", Label, Value);
|
||||
ImGui::EndTooltip();
|
||||
FCogWindowWidgets::BeginTableTooltip();
|
||||
if (ImGui::BeginTable("Params", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", Label);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%0.2f", Value);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
FCogWindowWidgets::EndTableTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,8 +494,6 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
|
||||
//--------------------------------------------------------------------
|
||||
Entry.UpdateTime(GetWorld());
|
||||
|
||||
ImPlot::SetupAxisLimits(Entry.CurrentYAxis, 0, Entry.MaxRow + 2, ImGuiCond_Always);
|
||||
|
||||
ImPlot::PushPlotClipRect();
|
||||
|
||||
|
||||
@@ -447,7 +516,7 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
|
||||
const bool IsInstant = Event.StartTime == Event.EndTime;
|
||||
if (IsInstant)
|
||||
{
|
||||
constexpr float Radius = 10.0f;
|
||||
constexpr float Radius = 10.0f;
|
||||
PlotDrawList->AddNgon(PosMid, 10, Event.BorderColor, 4);
|
||||
PlotDrawList->AddNgonFilled(PosMid, 10, Event.FillColor, 4);
|
||||
PlotDrawList->AddText(ImVec2(PosMid.x + 15, PosMid.y - 6), IM_COL32(255, 255, 255, 255), TCHAR_TO_ANSI(*Event.DisplayName));
|
||||
@@ -494,7 +563,7 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, FCogDebugPlotEntry& Entry)
|
||||
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry)
|
||||
{
|
||||
if (ImPlot::IsPlotHovered() && HoveredEvent != nullptr)
|
||||
{
|
||||
|
||||
@@ -32,13 +32,11 @@ protected:
|
||||
|
||||
void RenderMenu();
|
||||
|
||||
void RenderTimeMarker() const;
|
||||
|
||||
static void RenderValues(FCogDebugPlotEntry& Entry, const char* Label);
|
||||
void RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const;
|
||||
|
||||
void RenderEvents(FCogDebugPlotEntry& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const;
|
||||
|
||||
static void RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, FCogDebugPlotEntry& Entry);
|
||||
static void RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry);
|
||||
|
||||
TObjectPtr<UCogEngineConfig_Plots> Config = nullptr;
|
||||
|
||||
@@ -60,11 +58,31 @@ public:
|
||||
int Rows = 1;
|
||||
|
||||
UPROPERTY(Config)
|
||||
float TimeRange = 10.0f;
|
||||
float TimeRange = 20.0f;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowTimeBarAtGameTime = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowTimeBarAtCursor = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool ShowValueAtCursor = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
float DragViewSensitivity = 10.0f;
|
||||
|
||||
UPROPERTY(Config)
|
||||
FColor PauseBackgroundColor = FColor(10, 0, 0, 255);
|
||||
|
||||
virtual void Reset() override
|
||||
{
|
||||
Rows = 1;
|
||||
TimeRange = 10.0f;
|
||||
TimeRange = 20.0f;
|
||||
ShowTimeBarAtGameTime = true;
|
||||
ShowTimeBarAtCursor = true;
|
||||
ShowValueAtCursor = true;
|
||||
DragViewSensitivity = 10.0f;
|
||||
PauseBackgroundColor = FColor(10, 0, 0, 255);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "CogSampleAnimNotify.h"
|
||||
|
||||
#include "CogCommon.h"
|
||||
|
||||
#include "Animation/AnimSequenceBase.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
|
||||
#if ENABLE_COG
|
||||
#include "CogDebugPlot.h"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogSampleAnimNotify::UCogSampleAnimNotify(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
bIsNativeBranchingPoint = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotify::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference)
|
||||
{
|
||||
Super::Notify(MeshComp, Animation, EventReference);
|
||||
|
||||
#if ENABLE_COG
|
||||
FCogDebugPlot::PlotEventInstant(MeshComp->GetOwner(), "Anim Notify", GetFName())
|
||||
.AddParam("Name", GetNameSafe(this))
|
||||
.AddParam("Animation", GetNameSafe(Animation))
|
||||
.AddParam("Debug Info", GetDebugInfo());
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotify::BranchingPointNotify(FBranchingPointNotifyPayload& BranchingPointPayload)
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Replace UAnimNotify::BranchingPointNotify to fill the EventReference with the NotifyEvent for
|
||||
// UGPCoreAnimMotifyFunctionLibrary::AnimNotifyEventReferenceGetMontage to work properly
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Super::BranchingPointNotify(BranchingPointPayload);
|
||||
const FAnimNotifyEventReference EventReference(BranchingPointPayload.NotifyEvent,
|
||||
BranchingPointPayload.SequenceAsset);
|
||||
|
||||
Notify(BranchingPointPayload.SkelMeshComponent, BranchingPointPayload.SequenceAsset, EventReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FString UCogSampleAnimNotify::GetDebugInfo_Implementation() const
|
||||
{
|
||||
FString DebugInfo;
|
||||
return DebugInfo;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Animation/AnimNotifies/AnimNotify.h"
|
||||
|
||||
#include "CogSampleAnimNotify.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class UCogSampleAnimNotify : public UAnimNotify
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogSampleAnimNotify(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
FString GetDebugInfo() const;
|
||||
|
||||
void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override;
|
||||
|
||||
void BranchingPointNotify(FBranchingPointNotifyPayload& BranchingPointPayload) override;
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "CogSampleAnimNotifyState.h"
|
||||
|
||||
#include "CogCommon.h"
|
||||
|
||||
#include "Animation/AnimNotifies/AnimNotify.h"
|
||||
#include "Animation/AnimNotifyEndDataContext.h"
|
||||
#include "Animation/AnimSequenceBase.h"
|
||||
#include "Components/SkeletalMeshComponent.h"
|
||||
|
||||
#if ENABLE_COG
|
||||
#include "CogDebugPlot.h"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogSampleAnimNotifyState::UCogSampleAnimNotifyState(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
bIsNativeBranchingPoint = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotifyState::NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference)
|
||||
{
|
||||
#if ENABLE_COG
|
||||
FCogDebugPlot::PlotEventStart(MeshComp->GetOwner(), "Anim Notify", GetFName())
|
||||
.AddParam("Name", GetNameSafe(this))
|
||||
.AddParam("Animation", GetNameSafe(Animation))
|
||||
.AddParam("Debug Info", GetDebugInfo());
|
||||
#endif
|
||||
|
||||
Super::NotifyBegin(MeshComp, Animation, TotalDuration, EventReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotifyState::NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference)
|
||||
{
|
||||
#if ENABLE_COG
|
||||
FCogDebugPlot::PlotEventStop(MeshComp->GetOwner(), "Anim Notify", GetFName());
|
||||
#endif
|
||||
|
||||
Super::NotifyEnd(MeshComp, Animation, EventReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotifyState::BranchingPointNotifyBegin(FBranchingPointNotifyPayload& BranchingPointPayload)
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Replace UAnimNotifyState::BranchingPointNotifyBegin to fill the EventReference with the NotifyEvent for
|
||||
// UGPCoreAnimMotifyFunctionLibrary::AnimNotifyEventReferenceGetMontage to work properly
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Super::BranchingPointNotifyBegin(BranchingPointPayload);
|
||||
|
||||
const FAnimNotifyEventReference EventReference(BranchingPointPayload.NotifyEvent,
|
||||
BranchingPointPayload.SequenceAsset);
|
||||
|
||||
NotifyBegin(BranchingPointPayload.SkelMeshComponent,
|
||||
BranchingPointPayload.SequenceAsset,
|
||||
BranchingPointPayload.NotifyEvent
|
||||
? BranchingPointPayload.NotifyEvent->GetDuration()
|
||||
: 0.f,
|
||||
EventReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleAnimNotifyState::BranchingPointNotifyEnd(FBranchingPointNotifyPayload& BranchingPointPayload)
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Replace UAnimNotifyState::BranchingPointNotifyEnd to fill the EventReference with the NotifyEvent for
|
||||
// UGPCoreAnimMotifyFunctionLibrary::AnimNotifyEventReferenceGetMontage to work properly
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Super::BranchingPointNotifyEnd(BranchingPointPayload);
|
||||
|
||||
FAnimNotifyEventReference EventReference(BranchingPointPayload.NotifyEvent, BranchingPointPayload.SequenceAsset);
|
||||
if (BranchingPointPayload.bReachedEnd)
|
||||
{
|
||||
EventReference.AddContextData<UE::Anim::FAnimNotifyEndDataContext>(true);
|
||||
}
|
||||
NotifyEnd(BranchingPointPayload.SkelMeshComponent, BranchingPointPayload.SequenceAsset, EventReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FString UCogSampleAnimNotifyState::GetDebugInfo_Implementation() const
|
||||
{
|
||||
FString DebugInfo;
|
||||
return DebugInfo;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Animation/AnimNotifies/AnimNotifyState.h"
|
||||
|
||||
#include "CogSampleAnimNotifyState.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class UCogSampleAnimNotifyState : public UAnimNotifyState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCogSampleAnimNotifyState(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
FString GetDebugInfo() const;
|
||||
|
||||
void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
|
||||
|
||||
void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override;
|
||||
|
||||
void BranchingPointNotifyBegin(FBranchingPointNotifyPayload& BranchingPointPayload) override;
|
||||
|
||||
void BranchingPointNotifyEnd(FBranchingPointNotifyPayload& BranchingPointPayload) override;
|
||||
};
|
||||
@@ -370,8 +370,18 @@ void ACogSampleCharacter::SetupPlayerInputComponent(class UInputComponent* Playe
|
||||
int32 AbilityIndex = 0;
|
||||
for (const FActiveAbilityInfo& AbilityInfo : ActiveAbilities)
|
||||
{
|
||||
EnhancedInputComponent->BindAction(AbilityInfo.InputAction, ETriggerEvent::Started, this, &ACogSampleCharacter::OnAbilityInputStarted, AbilityIndex);
|
||||
EnhancedInputComponent->BindAction(AbilityInfo.InputAction, ETriggerEvent::Completed, this, &ACogSampleCharacter::OnAbilityInputCompleted, AbilityIndex);
|
||||
EnhancedInputComponent->BindActionValueLambda(AbilityInfo.InputAction, ETriggerEvent::Started,
|
||||
[this, &AbilityInfo, AbilityIndex](const FInputActionValue& InputActionValue)
|
||||
{
|
||||
OnAbilityInputStarted(AbilityInfo.InputAction, InputActionValue, AbilityIndex);
|
||||
});
|
||||
|
||||
EnhancedInputComponent->BindActionValueLambda(AbilityInfo.InputAction, ETriggerEvent::Completed,
|
||||
[this, &AbilityInfo, AbilityIndex](const FInputActionValue& InputActionValue)
|
||||
{
|
||||
OnAbilityInputCompleted(AbilityInfo.InputAction, InputActionValue, AbilityIndex);
|
||||
});
|
||||
|
||||
AbilityIndex++;
|
||||
}
|
||||
|
||||
@@ -385,10 +395,14 @@ void ACogSampleCharacter::SetupPlayerInputComponent(class UInputComponent* Playe
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::OnAbilityInputStarted(const FInputActionValue& Value, int32 Index)
|
||||
void ACogSampleCharacter::OnAbilityInputStarted(const UInputAction* InputAction, const FInputActionValue& Value, int32 Index)
|
||||
{
|
||||
COG_LOG_OBJECT(LogCogInput, ELogVerbosity::Verbose, this, TEXT("%d"), Index);
|
||||
|
||||
#if ENABLE_COG
|
||||
FCogDebugPlot::PlotEventStart(this, "Input", InputAction->GetFName());
|
||||
#endif
|
||||
|
||||
if (ActiveAbilityHandles.IsValidIndex(Index) == false)
|
||||
{
|
||||
return;
|
||||
@@ -429,10 +443,14 @@ void ACogSampleCharacter::OnAbilityInputStarted(const FInputActionValue& Value,
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::OnAbilityInputCompleted(const FInputActionValue& Value, int32 Index)
|
||||
void ACogSampleCharacter::OnAbilityInputCompleted(const UInputAction* InputAction, const FInputActionValue& Value, int32 Index)
|
||||
{
|
||||
COG_LOG_OBJECT(LogCogInput, ELogVerbosity::Verbose, this, TEXT("%d"), Index);
|
||||
|
||||
#if ENABLE_COG
|
||||
FCogDebugPlot::PlotEventStop(this, "Input", InputAction->GetFName());
|
||||
#endif
|
||||
|
||||
if (ActiveAbilityHandles.IsValidIndex(Index) == false)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -310,9 +310,9 @@ protected:
|
||||
|
||||
void Look(const FInputActionValue& Value);
|
||||
|
||||
void OnAbilityInputStarted(const FInputActionValue& Value, int32 Index);
|
||||
void OnAbilityInputStarted(const UInputAction* InputAction, const FInputActionValue& Value, int32 Index);
|
||||
|
||||
void OnAbilityInputCompleted(const FInputActionValue& Value, int32 Index);
|
||||
void OnAbilityInputCompleted(const UInputAction* InputAction, const FInputActionValue& Value, int32 Index);
|
||||
|
||||
void ActivateItem(const FInputActionValue& Value, int32 Index);
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include "CogSampleAbilitySystemComponent.h"
|
||||
#include "GameFramework/GameState.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
#if ENABLE_COG
|
||||
#include "CogAll.h"
|
||||
@@ -25,6 +27,13 @@ ACogSampleGameState::ACogSampleGameState(const FObjectInitializer & ObjectInitia
|
||||
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
DOREPLIFETIME(ThisClass, _ServerFramerateRaw);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleGameState::BeginPlay()
|
||||
{
|
||||
@@ -66,9 +75,52 @@ void ACogSampleGameState::Tick(float DeltaSeconds)
|
||||
#if ENABLE_COG
|
||||
|
||||
extern ENGINE_API float GAverageFPS;
|
||||
extern ENGINE_API float GAverageMS;
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate", GAverageFPS);
|
||||
FCogDebugPlot::PlotValue(this, "Frame Time", GAverageMS);
|
||||
|
||||
constexpr float smoothing = 10.0f;
|
||||
|
||||
_ClientFramerateSmooth = _ClientFramerateSmooth >= 0.0f
|
||||
? FMath::FInterpTo(_ClientFramerateSmooth, GAverageFPS, DeltaSeconds, smoothing)
|
||||
: GAverageFPS;
|
||||
|
||||
_ServerFramerateSmooth = _ServerFramerateSmooth >= 0.0f
|
||||
? FMath::FInterpTo(_ServerFramerateSmooth, _ServerFramerateRaw, DeltaSeconds, smoothing)
|
||||
: _ServerFramerateRaw;
|
||||
|
||||
if (GetLocalRole() != ROLE_Authority)
|
||||
{
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Client Raw", GAverageFPS);
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Client Smooth", _ClientFramerateSmooth);
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Server Raw", _ServerFramerateRaw);
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Server Smooth", _ServerFramerateSmooth);
|
||||
|
||||
if (const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController())
|
||||
{
|
||||
if (const APlayerController* PlayerController = LocalPlayer->PlayerController)
|
||||
{
|
||||
if (const APlayerState* PlayerState = PlayerController->GetPlayerState<APlayerState>())
|
||||
{
|
||||
FCogDebugPlot::PlotValue(this, "Ping", PlayerState->GetPingInMilliseconds());
|
||||
}
|
||||
|
||||
if (const UNetConnection* Connection = PlayerController->GetNetConnection())
|
||||
{
|
||||
FCogDebugPlot::PlotValue(this,
|
||||
"Packet Loss In",
|
||||
Connection->GetInLossPercentage().GetAvgLossPercentage() * 100.0f);
|
||||
|
||||
FCogDebugPlot::PlotValue(this,
|
||||
"Packet Loss Out",
|
||||
Connection->GetOutLossPercentage().GetAvgLossPercentage() * 100.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Raw", GAverageFPS);
|
||||
FCogDebugPlot::PlotValue(this, "Frame Rate Smooth", _ClientFramerateSmooth);
|
||||
}
|
||||
|
||||
|
||||
if (CogWindowManager != nullptr)
|
||||
{
|
||||
|
||||
@@ -36,11 +36,19 @@ private:
|
||||
UPROPERTY()
|
||||
TObjectPtr<UObject> CogWindowManagerRef = nullptr;
|
||||
|
||||
protected:
|
||||
UPROPERTY(Replicated)
|
||||
float _ServerFramerateRaw = 0.0f;
|
||||
|
||||
#if ENABLE_COG
|
||||
|
||||
void InitializeCog();
|
||||
|
||||
TObjectPtr<UCogWindowManager> CogWindowManager = nullptr;
|
||||
|
||||
float _ClientFramerateSmooth = 0.0f;
|
||||
|
||||
float _ServerFramerateSmooth = 0.0f;
|
||||
|
||||
#endif //ENABLE_COG
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#if ENABLE_COG
|
||||
#include "CogAbilityReplicator.h"
|
||||
#include "CogDebugDraw.h"
|
||||
#include "CogDebugPlot.h"
|
||||
#include "CogDebugReplicator.h"
|
||||
#include "CogEngineReplicator.h"
|
||||
#include "Framework/Application/NavigationConfig.h"
|
||||
|
||||
@@ -47,7 +47,7 @@ FCogSampleSpawnPredictionKey FCogSampleSpawnPredictionKey::MakeFromAbility(const
|
||||
FCogSampleSpawnPredictionKey Key;
|
||||
Key.Creator = InAbility.GetAvatarActorFromActorInfo() != nullptr ? InAbility.GetAvatarActorFromActorInfo()->GetFName() : FName();
|
||||
Key.Ability = InAbility.GetFName();
|
||||
Key.PredictionKey = Spec->ActivationInfo.GetActivationPredictionKey();
|
||||
Key.PredictionKey = InAbility.GetCurrentActivationInfo().GetActivationPredictionKey();
|
||||
Key.InstanceIndex = InInstanceIndex;
|
||||
Key.GameTime = InAbility.GetWorld()->GetTimeSeconds();
|
||||
return Key;
|
||||
|
||||
Reference in New Issue
Block a user