diff --git a/Config/UserEditorPerProjectUserSettings.ini b/Config/UserEditorPerProjectUserSettings.ini new file mode 100644 index 0000000..1e7943d --- /dev/null +++ b/Config/UserEditorPerProjectUserSettings.ini @@ -0,0 +1,3 @@ +[/Script/GameplayDebugger.GameplayDebuggerUserSettings] +FontSize=15 + diff --git a/Content/Characters/Creature1/Attributes/GE_Creature1_Attributes.uasset b/Content/Characters/Creature1/Attributes/GE_Creature1_Attributes.uasset index fb28f87..eb3124f 100644 Binary files a/Content/Characters/Creature1/Attributes/GE_Creature1_Attributes.uasset and b/Content/Characters/Creature1/Attributes/GE_Creature1_Attributes.uasset differ diff --git a/Content/Characters/Creature1/BP_Creature1.uasset b/Content/Characters/Creature1/BP_Creature1.uasset index cfc40e5..867bd3c 100644 Binary files a/Content/Characters/Creature1/BP_Creature1.uasset and b/Content/Characters/Creature1/BP_Creature1.uasset differ diff --git a/Content/Characters/Creature1/BT_Creature1.uasset b/Content/Characters/Creature1/BT_Creature1.uasset index b409787..d899c28 100644 Binary files a/Content/Characters/Creature1/BT_Creature1.uasset and b/Content/Characters/Creature1/BT_Creature1.uasset differ diff --git a/Content/Characters/Creature1/BT_Creature1_SubTree1.uasset b/Content/Characters/Creature1/BT_Creature1_SubTree1.uasset new file mode 100644 index 0000000..29c3456 Binary files /dev/null and b/Content/Characters/Creature1/BT_Creature1_SubTree1.uasset differ diff --git a/Content/Characters/Creature1/DT_Montages.uasset b/Content/Characters/Creature1/DT_Montages.uasset new file mode 100644 index 0000000..7fef339 Binary files /dev/null and b/Content/Characters/Creature1/DT_Montages.uasset differ diff --git a/Content/Characters/Creature2/BP_Creature2.uasset b/Content/Characters/Creature2/BP_Creature2.uasset index c55f0ec..e9ea70f 100644 Binary files a/Content/Characters/Creature2/BP_Creature2.uasset and b/Content/Characters/Creature2/BP_Creature2.uasset differ diff --git a/Content/Characters/_Shared_/BP_Creature.uasset b/Content/Characters/_Shared_/BP_Creature.uasset index 3e1aa1d..6d90474 100644 Binary files a/Content/Characters/_Shared_/BP_Creature.uasset and b/Content/Characters/_Shared_/BP_Creature.uasset differ diff --git a/Content/Characters/_Shared_/BTTask_ActivateAbility.uasset b/Content/Characters/_Shared_/BTTask_ActivateAbility.uasset index d801c28..79e10ca 100644 Binary files a/Content/Characters/_Shared_/BTTask_ActivateAbility.uasset and b/Content/Characters/_Shared_/BTTask_ActivateAbility.uasset differ diff --git a/Content/Core/Debug/Cheats/GE_Cheat_Big.uasset b/Content/Core/Debug/Cheats/GE_Cheat_Big.uasset index 7645841..f3e1f37 100644 Binary files a/Content/Core/Debug/Cheats/GE_Cheat_Big.uasset and b/Content/Core/Debug/Cheats/GE_Cheat_Big.uasset differ diff --git a/Content/Core/GameplayCues/Damage/CG_DamageReceived.uasset b/Content/Core/GameplayCues/Damage/CG_DamageReceived.uasset new file mode 100644 index 0000000..b43a0b8 Binary files /dev/null and b/Content/Core/GameplayCues/Damage/CG_DamageReceived.uasset differ diff --git a/Content/Core/GameplayCues/Damage/M_Damage.uasset b/Content/Core/GameplayCues/Damage/M_Damage.uasset new file mode 100644 index 0000000..87f10c0 Binary files /dev/null and b/Content/Core/GameplayCues/Damage/M_Damage.uasset differ diff --git a/Content/Core/GameplayCues/Damage/VFX_Damage.uasset b/Content/Core/GameplayCues/Damage/VFX_Damage.uasset new file mode 100644 index 0000000..c373340 Binary files /dev/null and b/Content/Core/GameplayCues/Damage/VFX_Damage.uasset differ diff --git a/Content/Core/Mannequins/Animations/ABP_Manny.uasset b/Content/Core/Mannequins/Animations/ABP_Manny.uasset index d03ac0f..ac777f9 100644 Binary files a/Content/Core/Mannequins/Animations/ABP_Manny.uasset and b/Content/Core/Mannequins/Animations/ABP_Manny.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/AM_HitReact_F_H.uasset b/Content/Core/Mannequins/Animations/Manny/AM_HitReact_F_H.uasset new file mode 100644 index 0000000..750d715 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/AM_HitReact_F_H.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Lgt_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Lgt_01.uasset new file mode 100644 index 0000000..d14c2f5 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Lgt_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Med_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Med_01.uasset new file mode 100644 index 0000000..5dc0c20 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Back_Med_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Hvy_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Hvy_01.uasset new file mode 100644 index 0000000..ff44636 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Hvy_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_01.uasset new file mode 100644 index 0000000..450908b Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_02.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_02.uasset new file mode 100644 index 0000000..76554ef Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_02.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_03.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_03.uasset new file mode 100644 index 0000000..f568023 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_03.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_04.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_04.uasset new file mode 100644 index 0000000..0ec092d Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Lgt_04.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_01.uasset new file mode 100644 index 0000000..64e2b74 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_02.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_02.uasset new file mode 100644 index 0000000..e6c8d81 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Front_Med_02.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Lgt_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Lgt_01.uasset new file mode 100644 index 0000000..c063e2c Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Lgt_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Med_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Med_01.uasset new file mode 100644 index 0000000..b8c230f Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Left_Med_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Lgt_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Lgt_01.uasset new file mode 100644 index 0000000..7ace7f0 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Lgt_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Med_01.uasset b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Med_01.uasset new file mode 100644 index 0000000..3c98553 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_HitReact_Right_Med_01.uasset differ diff --git a/Content/Core/Mannequins/Animations/Manny/MM_Rifle_Idle_ADS.uasset b/Content/Core/Mannequins/Animations/Manny/MM_Rifle_Idle_ADS.uasset new file mode 100644 index 0000000..8c40458 Binary files /dev/null and b/Content/Core/Mannequins/Animations/Manny/MM_Rifle_Idle_ADS.uasset differ diff --git a/Content/Core/Materials/M_Particle_Translucent.uasset b/Content/Core/Materials/M_Particle_Translucent.uasset index 60e0f14..3e9d53c 100644 Binary files a/Content/Core/Materials/M_Particle_Translucent.uasset and b/Content/Core/Materials/M_Particle_Translucent.uasset differ diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugDraw.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugDraw.cpp index 8eaf861..5555c3b 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugDraw.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugDraw.cpp @@ -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 Replicators; - ACogDebugReplicator::GetRemoteReplicators(*World, Replicators); + return; + } - for (ACogDebugReplicator* Replicator : Replicators) + TArray 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); } } diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp index d36bd79..500ca3b 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugReplicator.cpp @@ -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; -} \ No newline at end of file +} diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugSettings.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugSettings.cpp index 14eed99..69d527d 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugSettings.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugSettings.cpp @@ -1,10 +1,11 @@ #include "CogDebugSettings.h" #include "CogCommonDebugFilteredActorInterface.h" +#include "CogDebugReplicator.h" //-------------------------------------------------------------------------------------------------------------------------- TWeakObjectPtr 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 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); + } + } } //-------------------------------------------------------------------------------------------------------------------------- diff --git a/Plugins/Cog/Source/CogDebug/Private/CogDebugShape.cpp b/Plugins/Cog/Source/CogDebug/Private/CogDebugShape.cpp index bef0f22..aa2044c 100644 --- a/Plugins/Cog/Source/CogDebug/Private/CogDebugShape.cpp +++ b/Plugins/Cog/Source/CogDebug/Private/CogDebugShape.cpp @@ -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& 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) { diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h b/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h index 6efc8ee..d59fbf2 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebugReplicator.h @@ -85,6 +85,16 @@ public: UFUNCTION(Client, Reliable) void Client_SendCategoriesVerbosity(const TArray& 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 ServerSelection = nullptr; + + bool bIsServerFilteringBySelection = true; }; diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebugSettings.h b/Plugins/Cog/Source/CogDebug/Public/CogDebugSettings.h index 46f33ad..bb7719d 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebugSettings.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebugSettings.h @@ -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 Selection; - - static bool FilterBySelection; - static bool Persistent; static bool TextShadow; @@ -71,4 +72,12 @@ public: static float TextSize; static TArray SecondaryBoneWildcards; + +private: + + static bool IsDebugActiveForObject_Internal(const UObject* WorldContextObject, const AActor* InSelection, bool InIsFilteringBySelection); + + static TWeakObjectPtr Selection; + + static bool bIsFilteringBySelection; }; diff --git a/Plugins/Cog/Source/CogDebug/Public/CogDebugShape.h b/Plugins/Cog/Source/CogDebug/Public/CogDebugShape.h index 0e07f08..387c8bd 100644 --- a/Plugins/Cog/Source/CogDebug/Public/CogDebugShape.h +++ b/Plugins/Cog/Source/CogDebug/Public/CogDebugShape.h @@ -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& 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); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp index 546c585..96c9a46 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineReplicator.cpp @@ -178,4 +178,4 @@ void ACogEngineReplicator::Server_ResetPossession_Implementation() } #endif // !UE_BUILD_SHIPPING -} \ No newline at end of file +} diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp index 250f477..2d339f8 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_DebugSettings.cpp @@ -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."); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_LogCategories.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_LogCategories.cpp index e0be0b6..271b93d 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_LogCategories.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_LogCategories.cpp @@ -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."); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp index 2002109..91c9de8 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp @@ -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 SelectedClass = GetSelectedActorClass(); + if (SelectedClass == nullptr) + { + return; + } + + TArray Actors; + for (TActorIterator It(World, SelectedClass); It; ++It) + { + AActor* Actor = *It; + if (GetNameSafe(Actor) == SelectionName) + { + SetGlobalSelection(Actor); + } + } +} + +//-------------------------------------------------------------------------------------------------------------------------- +TSubclassOf UCogEngineWindow_Selection::GetSelectedActorClass() const +{ + TSubclassOf 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 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 ItSubClass : SubClasses) + for (int32 i = 0; i < ActorClasses.Num(); ++i) { - if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(ItSubClass)), false)) + TSubclassOf 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 Actors; - for (TActorIterator It(GetWorld(), SelectedSubClass); It; ++It) + for (TActorIterator 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 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(); } \ No newline at end of file diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_DebugSettings.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_DebugSettings.h index 0d62c41..237c540 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_DebugSettings.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_DebugSettings.h @@ -28,7 +28,7 @@ protected: private: UPROPERTY(Config) - bool FilterBySelection = true; + bool bIsFilteringBySelection = true; UPROPERTY(Config) bool Persistent = false; diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h index 3d318f3..01facad 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h @@ -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 Value) { SelectedSubClass = Value; } + const TArray>& GetActorClasses() const { return ActorClasses; } - TSubclassOf GetCurrentActorSubClass() const { return SelectedSubClass; } - - const TArray>& GetActorSubClasses() const { return SubClasses; } - - void SetActorSubClasses(const TArray>& Value) { SubClasses = Value; } + void SetActorClasses(const TArray>& 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 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 SelectedSubClass; - - TArray> SubClasses; + TArray> ActorClasses; ETraceTypeQuery TraceType = TraceTypeQuery1; }; diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index 6f9d518..c92c104 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -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)) diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp index fe1bb31..90d4ff0 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp @@ -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(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(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(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 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); } } diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp index 4d960fe..700787a 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp @@ -82,6 +82,29 @@ void UCogAIWindow_Blackboard::RenderContent() return; } + TArray 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(); diff --git a/Plugins/CogAI/Source/CogAI/Public/CogAIWindow_BehaviorTree.h b/Plugins/CogAI/Source/CogAI/Public/CogAIWindow_BehaviorTree.h index a340255..6fe4778 100644 --- a/Plugins/CogAI/Source/CogAI/Public/CogAIWindow_BehaviorTree.h +++ b/Plugins/CogAI/Source/CogAI/Public/CogAIWindow_BehaviorTree.h @@ -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; }; diff --git a/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Gamepad.cpp b/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Gamepad.cpp index f7c9718..67830d3 100644 --- a/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Gamepad.cpp +++ b/Plugins/CogInput/Source/CogInput/Private/CogInputWindow_Gamepad.cpp @@ -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()) { - 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(); } diff --git a/Plugins/CogInput/Source/CogInput/Public/CogInputWindow_Gamepad.h b/Plugins/CogInput/Source/CogInput/Public/CogInputWindow_Gamepad.h index bc83b31..76c09e1 100644 --- a/Plugins/CogInput/Source/CogInput/Public/CogInputWindow_Gamepad.h +++ b/Plugins/CogInput/Source/CogInput/Public/CogInputWindow_Gamepad.h @@ -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); diff --git a/README.md b/README.md index a45c4b5..47a18d8 100644 --- a/README.md +++ b/README.md @@ -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", diff --git a/Source/CogSample/CogSample.Build.cs b/Source/CogSample/CogSample.Build.cs index 0d9e4e8..c1f1827 100644 --- a/Source/CogSample/CogSample.Build.cs +++ b/Source/CogSample/CogSample.Build.cs @@ -8,6 +8,7 @@ public class CogSample : ModuleRules PublicDependencyModuleNames.AddRange(new string[] { + "AIModule", "CogCommon", "Core", "CoreUObject", diff --git a/Source/CogSample/CogSampleAbilitySystemComponent.cpp b/Source/CogSample/CogSampleAbilitySystemComponent.cpp new file mode 100644 index 0000000..f7d3dd3 --- /dev/null +++ b/Source/CogSample/CogSampleAbilitySystemComponent.cpp @@ -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); + } +} diff --git a/Source/CogSample/CogSampleAbilitySystemComponent.h b/Source/CogSample/CogSampleAbilitySystemComponent.h new file mode 100644 index 0000000..f996dff --- /dev/null +++ b/Source/CogSample/CogSampleAbilitySystemComponent.h @@ -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; + + +}; diff --git a/Source/CogSample/CogSampleBTTask_BlueprintBase.cpp b/Source/CogSample/CogSampleBTTask_BlueprintBase.cpp new file mode 100644 index 0000000..944fe07 --- /dev/null +++ b/Source/CogSample/CogSampleBTTask_BlueprintBase.cpp @@ -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(); +} diff --git a/Source/CogSample/CogSampleBTTask_BlueprintBase.h b/Source/CogSample/CogSampleBTTask_BlueprintBase.h new file mode 100644 index 0000000..94700ab --- /dev/null +++ b/Source/CogSample/CogSampleBTTask_BlueprintBase.h @@ -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; +}; \ No newline at end of file diff --git a/Source/CogSample/CogSampleCharacter.cpp b/Source/CogSample/CogSampleCharacter.cpp index aca20b5..7798ae2 100644 --- a/Source/CogSample/CogSampleCharacter.cpp +++ b/Source/CogSample/CogSampleCharacter.cpp @@ -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(TEXT("AbilitySystem")); + AbilitySystem = CreateDefaultSubobject(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(AddedSpec->GetPrimaryInstance())) - { - Ab->SetCooldownTag(UCogSampleFunctionLibrary_Tag::ActiveAbilityCooldownTags[Index]); - } + continue; } - Index++; + UCogSampleGameplayAbility* Ability = Cast(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& 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(MontageName, ContextString, bPrintWarning); + + if (Row == nullptr) + { + return false; + } + + Montage = Row->Montage; + return Montage != nullptr; +} \ No newline at end of file diff --git a/Source/CogSample/CogSampleCharacter.h b/Source/CogSample/CogSampleCharacter.h index 5eb14f0..fea11b0 100644 --- a/Source/CogSample/CogSampleCharacter.h +++ b/Source/CogSample/CogSampleCharacter.h @@ -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& 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> 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); diff --git a/Source/CogSample/CogSampleDamageEvent.h b/Source/CogSample/CogSampleDamageEvent.h index 6399da3..56c5ef1 100644 --- a/Source/CogSample/CogSampleDamageEvent.h +++ b/Source/CogSample/CogSampleDamageEvent.h @@ -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); diff --git a/Source/CogSample/CogSampleDamageableInterface.h b/Source/CogSample/CogSampleDamageableInterface.h new file mode 100644 index 0000000..c4bc648 --- /dev/null +++ b/Source/CogSample/CogSampleDamageableInterface.h @@ -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) {} +}; diff --git a/Source/CogSample/CogSampleExecCalculation_Damage.cpp b/Source/CogSample/CogSampleExecCalculation_Damage.cpp index 696c5ac..0b13197 100644 --- a/Source/CogSample/CogSampleExecCalculation_Damage.cpp +++ b/Source/CogSample/CogSampleExecCalculation_Damage.cpp @@ -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(TargetAbilitySystem->AbilityActorInfo.IsValid() ? TargetAbilitySystem->GetAvatarActor() : nullptr) : nullptr; - ACogSampleCharacter* SourceCharacter = (SourceAbilitySystem != nullptr) ? Cast(SourceAbilitySystem->AbilityActorInfo.IsValid() ? SourceAbilitySystem->GetAvatarActor() : nullptr) : nullptr; + UCogSampleAbilitySystemComponent* TargetAbilitySystem = Cast(ExecutionParams.GetTargetAbilitySystemComponent()); + AActor* TargetActor = (TargetAbilitySystem != nullptr) ? TargetAbilitySystem->GetAvatarActor() : nullptr; - if (TargetCharacter == nullptr) + UCogSampleAbilitySystemComponent* SourceAbilitySystem = Cast(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(TargetActor)) { - SourceCharacter->HandleDamageDealt(Params); + DamageReceiver->HandleDamageReceived(Params); + } + + if (ICogSampleDamageableInterface* DamageDealer = Cast(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); + } + } +} \ No newline at end of file diff --git a/Source/CogSample/CogSampleExecCalculation_Damage.h b/Source/CogSample/CogSampleExecCalculation_Damage.h index d77abe3..08fbc0b 100644 --- a/Source/CogSample/CogSampleExecCalculation_Damage.h +++ b/Source/CogSample/CogSampleExecCalculation_Damage.h @@ -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); + +}; diff --git a/Source/CogSample/CogSampleFunctionLibrary_Tag.cpp b/Source/CogSample/CogSampleFunctionLibrary_Tag.cpp index 33a755c..3135fae 100644 --- a/Source/CogSample/CogSampleFunctionLibrary_Tag.cpp +++ b/Source/CogSample/CogSampleFunctionLibrary_Tag.cpp @@ -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"); diff --git a/Source/CogSample/CogSampleFunctionLibrary_Tag.h b/Source/CogSample/CogSampleFunctionLibrary_Tag.h index d823fe5..d4808db 100644 --- a/Source/CogSample/CogSampleFunctionLibrary_Tag.h +++ b/Source/CogSample/CogSampleFunctionLibrary_Tag.h @@ -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); diff --git a/Source/CogSample/CogSampleGameState.cpp b/Source/CogSample/CogSampleGameState.cpp index 994c2db..31a7690 100644 --- a/Source/CogSample/CogSampleGameState.cpp +++ b/Source/CogSample/CogSampleGameState.cpp @@ -164,8 +164,7 @@ void ACogSampleGameState::InitializeCog() CogWindowManager->CreateWindow("Engine.Plots"); UCogEngineWindow_Selection* SelectionWindow = CogWindowManager->CreateWindow("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("Engine.Scalability"); diff --git a/Source/CogSample/CogSampleGameplayEffectContext.cpp b/Source/CogSample/CogSampleGameplayEffectContext.cpp index 52311aa..08ef3af 100644 --- a/Source/CogSample/CogSampleGameplayEffectContext.cpp +++ b/Source/CogSample/CogSampleGameplayEffectContext.cpp @@ -249,4 +249,15 @@ void UCogSampleEffectContextLibrary::EffectContextGetAllFloatValues(FGameplayEff { Entries = TypedEffectContext->FloatValues; } -} \ No newline at end of file +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool UCogSampleEffectContextLibrary::EffectContextGetGameplayCueIsPredicted(FGameplayEffectContextHandle EffectContext) +{ + if (FCogSampleGameplayEffectContext* TypedEffectContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext)) + { + return TypedEffectContext->bGameplayCueIsPredicted; + } + + return false; +} diff --git a/Source/CogSample/CogSampleGameplayEffectContext.h b/Source/CogSample/CogSampleGameplayEffectContext.h index c91ce10..1d3bc61 100644 --- a/Source/CogSample/CogSampleGameplayEffectContext.h +++ b/Source/CogSample/CogSampleGameplayEffectContext.h @@ -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 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); diff --git a/Source/CogSample/CogSampleLogCategories.h b/Source/CogSample/CogSampleLogCategories.h index 8e824a0..6c2ef09 100644 --- a/Source/CogSample/CogSampleLogCategories.h +++ b/Source/CogSample/CogSampleLogCategories.h @@ -1,4 +1,5 @@ #pragma once + #include "CoreMinimal.h" DECLARE_LOG_CATEGORY_EXTERN(LogCogAlways, VeryVerbose, All); diff --git a/TODO.txt b/TODO.txt index 50b7e46..1064627 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 \ No newline at end of file +- CogPackage: in package mode the Gameplay Cues are not visible.