Add target acquisition in the sample

This commit is contained in:
Arnaud Jamin
2023-10-06 02:27:00 -04:00
parent 25f2e06400
commit 92396410d4
36 changed files with 1657 additions and 97 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,7 @@
#include "CogDebugHelper.h"
#include "CogDebugDrawImGui.h"
#include "CogImguiHelper.h"
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
#include "CogDebugModule.h"
#include "CogDebugReplicator.h"
#include "Engine/SkeletalMesh.h"
@@ -16,7 +16,7 @@
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::String2D(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FString& Text, const FVector2D& Location, const FColor& Color, bool Persistent)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
FCogDebugDrawImGui::AddText(
FCogImguiHelper::ToImVec2(Location),
@@ -31,7 +31,7 @@ void FCogDebugDraw::String2D(const FLogCategoryBase& LogCategory, const UObject*
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Segment2D(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector2D& SegmentStart, const FVector2D& SegmentEnd, const FColor& Color, bool Persistent)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
FCogDebugDrawImGui::AddLine(
FCogImguiHelper::ToImVec2(SegmentStart),
@@ -46,7 +46,7 @@ void FCogDebugDraw::Segment2D(const FLogCategoryBase& LogCategory, const UObject
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Circle2D(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector2D& Location, float Radius, const FColor& Color, bool Persistent)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
FCogDebugDrawImGui::AddCircle(
FCogImguiHelper::ToImVec2(Location),
@@ -63,7 +63,7 @@ void FCogDebugDraw::Circle2D(const FLogCategoryBase& LogCategory, const UObject*
void FCogDebugDraw::Rect2D(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector2D& Min, const FVector2D& Max, const FColor& Color, bool Persistent)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const ImVec2 ImMin = FCogImguiHelper::ToImVec2(Min);
const ImVec2 ImMax = FCogImguiHelper::ToImVec2(Max);
@@ -82,7 +82,7 @@ void FCogDebugDraw::Rect2D(const FLogCategoryBase& LogCategory, const UObject* W
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::String(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FString& Text, const FVector& Location, const FColor& Color, const bool Persistent)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_LOCATION(WorldContextObject, LogCategory, Verbose, Location, 10.0f, NewColor, TEXT("%s"), *Text);
@@ -102,7 +102,7 @@ void FCogDebugDraw::String(const FLogCategoryBase& LogCategory, const UObject* W
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Point(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& Location, const float Size, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
::DrawDebugPoint(
@@ -121,7 +121,7 @@ void FCogDebugDraw::Point(const FLogCategoryBase& LogCategory, const UObject* Wo
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Segment(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& SegmentStart, const FVector& SegmentEnd, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_SEGMENT(WorldContextObject, LogCategory, Verbose, SegmentStart, SegmentEnd, NewColor, TEXT_EMPTY);
@@ -142,7 +142,7 @@ void FCogDebugDraw::Segment(const FLogCategoryBase& LogCategory, const UObject*
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Bone(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& BoneLocation, const FVector& ParentLocation, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_SEGMENT(WorldContextObject, LogCategory, Verbose, BoneLocation, ParentLocation, NewColor, TEXT_EMPTY);
@@ -173,7 +173,7 @@ void FCogDebugDraw::Bone(const FLogCategoryBase& LogCategory, const UObject* Wor
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Arrow(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& SegmentStart, const FVector& SegmentEnd, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_ARROW(WorldContextObject, LogCategory, Verbose, SegmentStart, SegmentEnd, NewColor, TEXT_EMPTY);
@@ -195,7 +195,7 @@ void FCogDebugDraw::Arrow(const FLogCategoryBase& LogCategory, const UObject* Wo
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Axis(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& AxisLoc, const FRotator& AxisRot, float Scale, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
FRotationMatrix R(AxisRot);
UE_VLOG_ARROW(WorldContextObject, LogCategory, Verbose, AxisLoc, AxisLoc + R.GetScaledAxis(EAxis::X) * Scale, FColor::Red, TEXT_EMPTY);
@@ -218,7 +218,7 @@ void FCogDebugDraw::Axis(const FLogCategoryBase& LogCategory, const UObject* Wor
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Circle(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FMatrix& Matrix, float Radius, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
const FVector Center = Matrix.GetOrigin();
@@ -243,7 +243,7 @@ void FCogDebugDraw::Circle(const FLogCategoryBase& LogCategory, const UObject* W
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::CircleArc(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FMatrix& Matrix, float InnerRadius, float OuterRadius, float Angle, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
@@ -269,7 +269,7 @@ void FCogDebugDraw::CircleArc(const FLogCategoryBase& LogCategory, const UObject
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::FlatCapsule(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector2D& Start, const FVector2D& End, const float Radius, const float Z, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
// TODO : Add VLOG
@@ -294,7 +294,7 @@ void FCogDebugDraw::FlatCapsule(const FLogCategoryBase& LogCategory, const UObje
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Sphere(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& Location, float Radius, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_CAPSULE(WorldContextObject, LogCategory, Verbose, Location, 0.0f, Radius, FQuat::Identity, NewColor, TEXT_EMPTY);
@@ -316,7 +316,7 @@ void FCogDebugDraw::Sphere(const FLogCategoryBase& LogCategory, const UObject* W
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Box(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& Center, const FVector& Extent, const FQuat& Rotation, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_OBOX(WorldContextObject, LogCategory, Verbose, FBox(-Extent, Extent), FQuatRotationTranslationMatrix::Make(Rotation, Center), NewColor, TEXT_EMPTY);
@@ -339,7 +339,7 @@ void FCogDebugDraw::Box(const FLogCategoryBase& LogCategory, const UObject* Worl
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::SolidBox(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& Center, const FVector& Extent, const FQuat& Rotation, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_OBOX(WorldContextObject, LogCategory, Verbose, FBox(-Extent, Extent), FQuatRotationTranslationMatrix::Make(Rotation, Center), NewColor, TEXT_EMPTY);
@@ -366,7 +366,7 @@ void FCogDebugDraw::SolidBox(const FLogCategoryBase& LogCategory, const UObject*
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Frustrum(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FMatrix& Matrix, const float Angle, const float AspectRatio, const float NearPlane, const float FarPlane, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
@@ -390,7 +390,7 @@ void FCogDebugDraw::Frustrum(const FLogCategoryBase& LogCategory, const UObject*
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Capsule(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const FVector& Center, const float HalfHeight, const float Radius, const FQuat& Rotation, const FColor& Color, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FColor NewColor = FCogDebugSettings::ModulateDebugColor(WorldContextObject->GetWorld(), Color, Persistent);
UE_VLOG_CAPSULE(WorldContextObject, LogCategory, Verbose, Center, HalfHeight, Radius, FQuat::Identity, NewColor, TEXT_EMPTY);
@@ -414,7 +414,7 @@ void FCogDebugDraw::Capsule(const FLogCategoryBase& LogCategory, const UObject*
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Points(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const TArray<FVector>& Points, float Radius, const FColor& StartColor, const FColor& EndColor, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
int32 index = 0;
for (const FVector& Point : Points)
@@ -429,7 +429,7 @@ void FCogDebugDraw::Points(const FLogCategoryBase& LogCategory, const UObject* W
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugDraw::Path(const FLogCategoryBase& LogCategory, const UObject* WorldContextObject, const TArray<FVector>& Points, float PointSize, const FColor& StartColor, const FColor& EndColor, const bool Persistent, const uint8 DepthPriority)
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
if (Points.Num() == 0)
{
@@ -465,7 +465,7 @@ void FCogDebugDraw::Skeleton(const FLogCategoryBase& LogCategory, const USkeleta
return;
}
if (FCogDebugLogCategoryManager::IsLogCategoryActive(LogCategory))
if (FCogDebugLog::IsLogCategoryActive(LogCategory))
{
const FReferenceSkeleton& ReferenceSkeleton = Skeleton->GetSkeletalMeshAsset()->GetRefSkeleton();
const FTransform WorldTransform = Skeleton->GetComponentTransform();
@@ -1,4 +1,4 @@
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
#include "CogDebugModule.h"
#include "CogDebugReplicator.h"
@@ -10,7 +10,7 @@
DEFINE_LOG_CATEGORY(LogCogNone);
DEFINE_LOG_CATEGORY(LogCogServerDebug);
TMap<FName, FCogDebugLogCategoryInfo> FCogDebugLogCategoryManager::LogCategories;
TMap<FName, FCogDebugLogCategoryInfo> FCogDebugLog::LogCategories;
//--------------------------------------------------------------------------------------------------------------------------
@@ -34,7 +34,7 @@ FString FCogDebugLogCategoryInfo::GetDisplayName() const
//--------------------------------------------------------------------------------------------------------------------------
// FCogDebugLogCategoryManager
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::AddLogCategory(FLogCategoryBase& LogCategory, const FString& DisplayName, bool bVisible)
void FCogDebugLog::AddLogCategory(FLogCategoryBase& LogCategory, const FString& DisplayName, bool bVisible)
{
LogCategories.Add(LogCategory.GetCategoryName(),
FCogDebugLogCategoryInfo
@@ -47,19 +47,19 @@ void FCogDebugLogCategoryManager::AddLogCategory(FLogCategoryBase& LogCategory,
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugLogCategoryManager::IsVerbosityActive(ELogVerbosity::Type Verbosity)
bool FCogDebugLog::IsVerbosityActive(ELogVerbosity::Type Verbosity)
{
return Verbosity >= ELogVerbosity::Verbose;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugLogCategoryManager::IsLogCategoryActive(const FLogCategoryBase& LogCategory)
bool FCogDebugLog::IsLogCategoryActive(const FLogCategoryBase& LogCategory)
{
return IsVerbosityActive(LogCategory.GetVerbosity());
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugLogCategoryManager::IsLogCategoryActive(FName CategoryName)
bool FCogDebugLog::IsLogCategoryActive(FName CategoryName)
{
if (FLogCategoryBase* LogCategory = FindLogCategory(CategoryName))
{
@@ -70,13 +70,13 @@ bool FCogDebugLogCategoryManager::IsLogCategoryActive(FName CategoryName)
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::SetLogCategoryActive(FLogCategoryBase& LogCategory, bool Value)
void FCogDebugLog::SetLogCategoryActive(FLogCategoryBase& LogCategory, bool Value)
{
LogCategory.SetVerbosity(Value ? ELogVerbosity::Verbose : ELogVerbosity::Warning);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::OnServerVerbosityChanged(FName CategoryName, ELogVerbosity::Type Verbosity)
void FCogDebugLog::OnServerVerbosityChanged(FName CategoryName, ELogVerbosity::Type Verbosity)
{
if (FCogDebugLogCategoryInfo* LogCategoryInfo = FindLogCategoryInfo(CategoryName))
{
@@ -85,7 +85,7 @@ void FCogDebugLogCategoryManager::OnServerVerbosityChanged(FName CategoryName, E
}
//--------------------------------------------------------------------------------------------------------------------------
ELogVerbosity::Type FCogDebugLogCategoryManager::GetServerVerbosity(FName CategoryName)
ELogVerbosity::Type FCogDebugLog::GetServerVerbosity(FName CategoryName)
{
if (FCogDebugLogCategoryInfo* LogCategoryInfo = FindLogCategoryInfo(CategoryName))
{
@@ -96,7 +96,7 @@ ELogVerbosity::Type FCogDebugLogCategoryManager::GetServerVerbosity(FName Catego
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::SetServerVerbosity(UWorld& World, FName CategoryName, ELogVerbosity::Type Verbosity)
void FCogDebugLog::SetServerVerbosity(UWorld& World, FName CategoryName, ELogVerbosity::Type Verbosity)
{
if (ACogDebugReplicator* Replicator = FCogDebugModule::Get().GetLocalReplicator(World))
{
@@ -105,25 +105,25 @@ void FCogDebugLogCategoryManager::SetServerVerbosity(UWorld& World, FName Catego
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::SetServerVerbosityActive(UWorld& World, FName CategoryName, bool Value)
void FCogDebugLog::SetServerVerbosityActive(UWorld& World, FName CategoryName, bool Value)
{
SetServerVerbosity(World, CategoryName, Value ? ELogVerbosity::Verbose : ELogVerbosity::Warning);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebugLogCategoryManager::IsServerVerbosityActive(FName CategoryName)
bool FCogDebugLog::IsServerVerbosityActive(FName CategoryName)
{
return IsVerbosityActive(GetServerVerbosity(CategoryName));
}
//--------------------------------------------------------------------------------------------------------------------------
FCogDebugLogCategoryInfo* FCogDebugLogCategoryManager::FindLogCategoryInfo(FName CategoryName)
FCogDebugLogCategoryInfo* FCogDebugLog::FindLogCategoryInfo(FName CategoryName)
{
return LogCategories.Find(CategoryName);
}
//--------------------------------------------------------------------------------------------------------------------------
FLogCategoryBase* FCogDebugLogCategoryManager::FindLogCategory(FName CategoryName)
FLogCategoryBase* FCogDebugLog::FindLogCategory(FName CategoryName)
{
if (FCogDebugLogCategoryInfo* LogCategoryInfo = FindLogCategoryInfo(CategoryName))
{
@@ -138,7 +138,7 @@ FLogCategoryBase* FCogDebugLogCategoryManager::FindLogCategory(FName CategoryNam
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebugLogCategoryManager::DeactivateAllLogCateories(UWorld& World)
void FCogDebugLog::DeactivateAllLogCateories(UWorld& World)
{
FString ToggleStr = TEXT("Log LogCogNone Only");
GEngine->Exec(&World, *ToggleStr);
@@ -1,6 +1,6 @@
#include "CogDebugLogBlueprint.h"
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
#include "CogDebugLogMacros.h"
//--------------------------------------------------------------------------------------------------------------------------
@@ -35,7 +35,7 @@ bool UCogDebugLogBlueprint::IsLogActive(const UObject* WorldContextObject, FCogL
if (const FLogCategoryBase* LogCategoryPtr = LogCategory.GetLogCategory())
{
if (FCogDebugLogCategoryManager::IsLogCategoryActive(*LogCategoryPtr) == false)
if (FCogDebugLog::IsLogCategoryActive(*LogCategoryPtr) == false)
{
return false;
}
@@ -1,6 +1,6 @@
#include "CogDebugLogCategory.h"
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
//--------------------------------------------------------------------------------------------------------------------------
FLogCategoryBase* FCogLogCategory::GetLogCategory() const
@@ -18,7 +18,7 @@ FLogCategoryBase* FCogLogCategory::GetLogCategory() const
if (LogCategory == nullptr)
{
if (FCogDebugLogCategoryInfo* CategoryInfo = FCogDebugLogCategoryManager::GetLogCategories().Find(Name))
if (FCogDebugLogCategoryInfo* CategoryInfo = FCogDebugLog::GetLogCategories().Find(Name))
{
LogCategory = CategoryInfo->LogCategory;
}
@@ -181,7 +181,7 @@ void ACogDebugReplicator::Server_SetCategoryVerbosity_Implementation(FName LogCa
ENetMode NetMode = GetWorld()->GetNetMode();
if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer)
{
if (FCogDebugLogCategoryInfo* LogCategoryInfo = FCogDebugLogCategoryManager::FindLogCategoryInfo(LogCategoryName))
if (FCogDebugLogCategoryInfo* LogCategoryInfo = FCogDebugLog::FindLogCategoryInfo(LogCategoryName))
{
LogCategoryInfo->LogCategory->SetVerbosity((ELogVerbosity::Type)Verbosity);
@@ -203,7 +203,7 @@ void ACogDebugReplicator::NetMulticast_SendCategoriesVerbosity_Implementation(co
{
for (const FCogServerCategoryData& Category : Categories)
{
FCogDebugLogCategoryManager::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
}
}
@@ -219,7 +219,7 @@ void ACogDebugReplicator::Client_SendCategoriesVerbosity_Implementation(const TA
{
for (const FCogServerCategoryData& Category : Categories)
{
FCogDebugLogCategoryManager::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
FCogDebugLog::OnServerVerbosityChanged(Category.LogCategoryName, (ELogVerbosity::Type)Category.Verbosity);
}
}
@@ -235,7 +235,7 @@ void ACogDebugReplicator::Server_RequestAllCategoriesVerbosity_Implementation()
if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer)
{
TArray<FCogServerCategoryData> CategoriesData;
for (auto& Entry : FCogDebugLogCategoryManager::GetLogCategories())
for (auto& Entry : FCogDebugLog::GetLogCategories())
{
FCogDebugLogCategoryInfo& CategoryInfo = Entry.Value;
if (CategoryInfo.LogCategory != nullptr)
@@ -3,7 +3,7 @@
#include "CoreMinimal.h"
#include "imgui.h"
class FCogDebugDrawImGui
class COGDEBUG_API FCogDebugDrawImGui
{
public:
static void AddLine(const ImVec2& P1, const ImVec2& P2, ImU32 Color, float Thickness = 1.0f, float Duration = 0.0f, bool FadeColor = false);
@@ -20,7 +20,7 @@ struct COGDEBUG_API FCogDebugLogCategoryInfo
};
//--------------------------------------------------------------------------------------------------------------------------
struct COGDEBUG_API FCogDebugLogCategoryManager
struct COGDEBUG_API FCogDebugLog
{
static void AddLogCategory(FLogCategoryBase& LogCategory, const FString& DisplayName = "", bool bVisible = true);
@@ -1,7 +1,7 @@
#include "CogDebugLogCategoryDetails.h"
#include "CogDebugLogCategory.h"
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
#include "DetailWidgetRow.h"
#include "Editor.h"
#include "IPropertyUtilities.h"
@@ -27,7 +27,7 @@ void FCogLogCategoryDetails::CustomizeHeader(TSharedRef<IPropertyHandle> StructP
PropertyOptions.Empty();
PropertyOptions.Add(MakeShareable(new FString("None")));
for (auto& Entry : FCogDebugLogCategoryManager::GetLogCategories())
for (auto& Entry : FCogDebugLog::GetLogCategories())
{
PropertyOptions.Add(MakeShareable(new FString(Entry.Value.LogCategory->GetCategoryName().ToString())));
}
@@ -247,7 +247,7 @@ TSharedPtr<FLogCategoryViewerNode> SLogCategoryListWidget::UpdatePropertyOptions
PropertyOptions.Add(InitiallySelected);
// Gather all ULogCategory classes
for (auto& Entry : FCogDebugLogCategoryManager::GetLogCategories())
for (auto& Entry : FCogDebugLog::GetLogCategories())
{
// if we have a search string and this doesn't match, don't show it
if (LogCategoryTextFilter.IsValid() && !LogCategoryTextFilter->PassesFilter(Entry.Value.LogCategory->GetCategoryName()))
@@ -2,7 +2,7 @@
#include "CogDebugHelper.h"
#include "CogWindowWidgets.h"
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogEngineWindow_LogCategories::RenderHelp()
@@ -49,7 +49,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
if (ImGui::MenuItem("Reset"))
{
FCogDebugLogCategoryManager::DeactivateAllLogCateories(*World);
FCogDebugLog::DeactivateAllLogCateories(*World);
}
if (ImGui::IsItemHovered())
@@ -77,7 +77,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
ImGuiStyle& Style = ImGui::GetStyle();
int Index = 0;
for (const auto& Entry : FCogDebugLogCategoryManager::GetLogCategories())
for (const auto& Entry : FCogDebugLog::GetLogCategories())
{
FName CategoryName = Entry.Key;
const FCogDebugLogCategoryInfo& CategoryInfo = Entry.Value;
@@ -96,8 +96,8 @@ void UCogEngineWindow_LogCategories::RenderContent()
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
if (IsClient)
{
ELogVerbosity::Type Verbosity = FCogDebugLogCategoryManager::GetServerVerbosity(CategoryName);
bool IsActive = FCogDebugLogCategoryManager::IsVerbosityActive(Verbosity);
ELogVerbosity::Type Verbosity = FCogDebugLog::GetServerVerbosity(CategoryName);
bool IsActive = FCogDebugLog::IsVerbosityActive(Verbosity);
if (Verbosity == ELogVerbosity::VeryVerbose)
{
@@ -107,7 +107,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
if (ImGui::Checkbox("##Server", &IsActive))
{
ELogVerbosity::Type NewVerbosity = IsActive ? (IsControlDown ? ELogVerbosity::VeryVerbose : ELogVerbosity::Verbose) : ELogVerbosity::Warning;
FCogDebugLogCategoryManager::SetServerVerbosity(*World, CategoryName, NewVerbosity);
FCogDebugLog::SetServerVerbosity(*World, CategoryName, NewVerbosity);
}
if (Verbosity == ELogVerbosity::VeryVerbose)
@@ -128,7 +128,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
{
ELogVerbosity::Type Verbosity = Category->GetVerbosity();
bool IsActive = FCogDebugLogCategoryManager::IsVerbosityActive(Verbosity);
bool IsActive = FCogDebugLog::IsVerbosityActive(Verbosity);
if (Verbosity == ELogVerbosity::VeryVerbose)
{
@@ -162,7 +162,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
{
if (IsClient)
{
ELogVerbosity::Type CurrentVerbosity = FCogDebugLogCategoryManager::GetServerVerbosity(CategoryName);
ELogVerbosity::Type CurrentVerbosity = FCogDebugLog::GetServerVerbosity(CategoryName);
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("##Server", FCogDebugHelper::VerbosityToString(CurrentVerbosity)))
{
@@ -173,7 +173,7 @@ void UCogEngineWindow_LogCategories::RenderContent()
if (ImGui::Selectable(FCogDebugHelper::VerbosityToString(Verbosity), IsSelected))
{
FCogDebugLogCategoryManager::SetServerVerbosity(*World, CategoryName, Verbosity);
FCogDebugLog::SetServerVerbosity(*World, CategoryName, Verbosity);
}
}
ImGui::EndCombo();
+10
View File
@@ -5,3 +5,13 @@
#ifndef USE_COG
#define USE_COG (ENABLE_DRAW_DEBUG && !NO_LOGGING)
#endif
#if !USE_COG
#define COG(expr) (0)
#else //!ENABLE_COG
#define COG(expr) { expr; }
#endif //!ENABLE_COG
+23 -12
View File
@@ -6,6 +6,7 @@
#include "CogSampleAttributeSet_Health.h"
#include "CogSampleAttributeSet_Misc.h"
#include "CogSampleCharacterMovementComponent.h"
#include "CogSampleFunctionLibrary_Team.h"
#include "CogSampleGameplayAbility.h"
#include "CogSampleLogCategories.h"
#include "CogSampleRootMotionParams.h"
@@ -77,7 +78,7 @@ void ACogSampleCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >
Params.Condition = COND_OwnerOnly;
DOREPLIFETIME_WITH_PARAMS_FAST(ACogSampleCharacter, ActiveAbilityHandles, Params);
DOREPLIFETIME_WITH_PARAMS_FAST(ACogSampleCharacter, TeamID, Params);
DOREPLIFETIME_WITH_PARAMS_FAST(ACogSampleCharacter, Team, Params);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -116,18 +117,16 @@ UAbilitySystemComponent* ACogSampleCharacter::GetAbilitySystemComponent() const
//--------------------------------------------------------------------------------------------------------------------------
ECogInterfacesAllegiance ACogSampleCharacter::GetAllegianceWithOtherActor(const AActor* OtherActor) const
{
const ACogSampleCharacter* OtherCharacter = Cast<ACogSampleCharacter>(OtherActor);
if (OtherCharacter == nullptr)
{
return ECogInterfacesAllegiance::Neutral;
}
ECogSampleAllegiance Allegiance = UCogSampleFunctionLibrary_Team::GetActorsAllegiance(this, OtherActor);
if (TeamID == OtherCharacter->TeamID)
switch (Allegiance)
{
return ECogInterfacesAllegiance::Friendly;
case ECogSampleAllegiance::Enemy: return ECogInterfacesAllegiance::Enemy;
case ECogSampleAllegiance::Friendly: return ECogInterfacesAllegiance::Friendly;
case ECogSampleAllegiance::Neutral: return ECogInterfacesAllegiance::Neutral;
}
return ECogInterfacesAllegiance::Enemy;
return ECogInterfacesAllegiance::Neutral;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -507,8 +506,8 @@ void ACogSampleCharacter::OnScaleAttributeChanged(const FOnAttributeChangeData&
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::SetTeamID(int32 Value)
{
TeamID = Value;
MARK_PROPERTY_DIRTY_FROM_NAME(ACogSampleCharacter, TeamID, this);
Team = Value;
MARK_PROPERTY_DIRTY_FROM_NAME(ACogSampleCharacter, Team, this);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -608,4 +607,16 @@ void ACogSampleCharacter::UpdateActiveAbilitySlots()
FGameplayTag SlotTag = FCogSampleTagLibrary::ActiveAbilityCooldownTags[i];
AbilityInstance->SetSlotTag(SlotTag);
}
}
//--------------------------------------------------------------------------------------------------------------------------
FVector ACogSampleCharacter::GetTargetLocation() const
{
return GetActorLocation();
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::GetTargetCapsules(TArray<const UCapsuleComponent*>& Capsules) const
{
Capsules.Add(GetCapsuleComponent());
}
+13 -13
View File
@@ -7,6 +7,8 @@
#include "CogDefines.h"
#include "CogInterfaceAllegianceActor.h"
#include "CogInterfaceDebugFilteredActor.h"
#include "CogSampleTargetableInterface.h"
#include "CogSampleTeamInterface.h"
#include "GameFramework/Character.h"
#include "GameplayAbilitySpecHandle.h"
#include "GameplayTagContainer.h"
@@ -26,17 +28,6 @@ struct FCogSampleRootMotionParams;
struct FGameplayEffectSpec;
struct FOnAttributeChangeData;
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class ECogSampleAllegianceFilter : uint8
{
None = 0 UMETA(Hidden),
Ally = 1 << 0,
Neutral = 1 << 1,
Enemy = 1 << 2,
};
ENUM_CLASS_FLAGS(ECogSampleAllegianceFilter);
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FActiveAbilityInfo
@@ -72,6 +63,8 @@ class ACogSampleCharacter : public ACharacter
, public IAbilitySystemInterface
, public ICogInterfacesDebugFilteredActor
, public ICogInterfacesAllegianceActor
, public ICogSampleTeamInterface
, public ICogSampleTargetableInterface
{
GENERATED_BODY()
@@ -102,6 +95,13 @@ public:
//----------------------------------------------------------------------------------------------------------------------
ECogInterfacesAllegiance GetAllegianceWithOtherActor(const AActor* OtherActor) const override;
//----------------------------------------------------------------------------------------------------------------------
// ICogSampleTargetInterface overrides
//----------------------------------------------------------------------------------------------------------------------
virtual FVector GetTargetLocation() const override;
virtual void GetTargetCapsules(TArray<const UCapsuleComponent*>& Capsules) const override;
//----------------------------------------------------------------------------------------------------------------------
void OnAcknowledgePossession(APlayerController* InController);
@@ -181,13 +181,13 @@ public:
//----------------------------------------------------------------------------------------------------------------------
UFUNCTION(BlueprintPure)
int32 GetTeamID() const { return TeamID; }
virtual int32 GetTeam() const override { return Team; }
UFUNCTION(BlueprintCallable)
void SetTeamID(int32 Value);
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true"))
int32 TeamID = 0;
int32 Team = 0;
//----------------------------------------------------------------------------------------------------------------------
// Root Motion
@@ -4,10 +4,12 @@
#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "CogSampleGameplayEffectContext.h"
#include "CogSampleTargetableInterface.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/Character.h"
#include "GameplayCueNotifyTypes.h"
#include "GameplayEffectTypes.h"
#include "Kismet/KismetMathLibrary.h"
#include "Particles/ParticleSystemComponent.h"
#include "ScalableFloat.h"
@@ -108,3 +110,144 @@ int32 UCogSampleFunctionLibrary_Gameplay::GetIntValue(const FScalableFloat& Scal
return (int32)ScalableFloat.GetValueAtLevel(Level);
}
//--------------------------------------------------------------------------------------------------------------------------
FCollisionObjectQueryParams UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(const TArray<TEnumAsByte<EObjectTypeQuery>>& ObjectTypes)
{
TArray<TEnumAsByte<ECollisionChannel>> CollisionObjectTraces;
CollisionObjectTraces.AddUninitialized(ObjectTypes.Num());
for (auto Iter = ObjectTypes.CreateConstIterator(); Iter; ++Iter)
{
CollisionObjectTraces[Iter.GetIndex()] = UEngineTypes::ConvertToCollisionChannel(*Iter);
}
FCollisionObjectQueryParams ObjectParams;
for (auto Iter = CollisionObjectTraces.CreateConstIterator(); Iter; ++Iter)
{
const ECollisionChannel& Channel = (*Iter);
if (FCollisionObjectQueryParams::IsValidObjectQuery(Channel))
{
ObjectParams.AddObjectTypesToQuery(Channel);
}
}
return ObjectParams;
}
//--------------------------------------------------------------------------------------------------------------------------
FVector UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(const AActor* Actor)
{
if (Actor == nullptr)
{
return FVector::ZeroVector;
}
if (const ICogSampleTargetableInterface* Targetable = Cast<ICogSampleTargetableInterface>(Actor))
{
return Targetable->GetTargetLocation();
}
return Actor->GetActorLocation();
}
//--------------------------------------------------------------------------------------------------------------------------
float UCogSampleFunctionLibrary_Gameplay::AngleBetweenVector2D(FVector2D A, FVector2D B)
{
A.Normalize();
B.Normalize();
return FMath::RadiansToDegrees(FMath::Acos(FVector2D::DotProduct(A, B)));
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleFunctionLibrary_Gameplay::FindSegmentPointDistance(const FVector2D& Segment1, const FVector2D& Segment2, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance)
{
const float DistSquared = FVector2D::DistSquared(Segment1, Segment2);
if (FMath::IsNearlyZero(DistSquared))
{
Time = 0.0f;
Projection = Segment1;
Distance = FVector2D::Distance(Point, Segment1);
}
else
{
Time = FMath::Max(0.0f, FMath::Min(1.0f, FVector2D::DotProduct(Point - Segment1, Segment2 - Segment1) / DistSquared));
Projection = Segment1 + Time * (Segment2 - Segment1);
Distance = FVector2D::Distance(Point, Projection);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(const FVector2D& CapsulePoint1, const FVector2D& CapsulePoint2, const float CapsuleRadius, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance)
{
FindSegmentPointDistance(CapsulePoint1, CapsulePoint2, Point, Projection, Time, Distance);
float projectionToPointDistance = Distance;
Distance -= CapsuleRadius;
if (Distance > 0.0f)
{
Projection = Point + ((Projection - Point) / projectionToPointDistance) * Distance;
}
else
{
Projection = Point;
}
}
//--------------------------------------------------------------------------------------------------------------------------
FVector2D UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(const FVector2D& value, const FVector2D& displaySize)
{
FVector2D result;
if (displaySize.X > displaySize.Y)
{
const float screenXStart = (displaySize.X - displaySize.Y) * 0.5f;
const float screenXEnd = displaySize.X - screenXStart;
result.X = UKismetMathLibrary::MapRangeUnclamped(value.X, -1.0f, 1.0f, screenXStart, screenXEnd);
result.Y = UKismetMathLibrary::MapRangeUnclamped(value.Y, -1.0f, 1.0f, displaySize.Y, 0.0f);
}
else
{
const float ScreenYStart = (displaySize.Y - displaySize.X) * 0.5f;
const float ScreenYEnd = displaySize.Y - ScreenYStart;
result.X = UKismetMathLibrary::MapRangeUnclamped(value.X, -1.0f, 1.0f, 0.0f, displaySize.X);
result.Y = UKismetMathLibrary::MapRangeUnclamped(value.Y, -1.0f, 1.0f, ScreenYEnd, ScreenYStart);
}
return result;
}
//--------------------------------------------------------------------------------------------------------------------------
float UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(const float Value, const FVector2D& DisplaySize)
{
return Value * 0.5f * FMath::Min(DisplaySize.X, DisplaySize.Y);
}
//--------------------------------------------------------------------------------------------------------------------------
FVector2D UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const FVector2D& Value, const FVector2D& DisplaySize)
{
FVector2D Result;
if (DisplaySize.X > DisplaySize.Y)
{
const float screenXStart = (DisplaySize.X - DisplaySize.Y) * 0.5f;
const float screenXEnd = DisplaySize.X - screenXStart;
Result.X = UKismetMathLibrary::MapRangeUnclamped(Value.X, screenXStart, screenXEnd, -1.0f, 1.0f);
Result.Y = UKismetMathLibrary::MapRangeUnclamped(Value.Y, 0.0f, DisplaySize.Y, -1.0f, 1.0f);
}
else
{
const float screenYStart = (DisplaySize.Y - DisplaySize.X) * 0.5f;
const float screenYEnd = DisplaySize.Y - screenYStart;
Result.X = UKismetMathLibrary::MapRangeUnclamped(Value.X, 0.0f, DisplaySize.X, -1.0f, 1.0f);
Result.Y = UKismetMathLibrary::MapRangeUnclamped(Value.Y, screenYStart, screenYEnd, -1.0f, 1.0f);
}
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
float UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const float Value, const FVector2D& DisplaySize)
{
return Value * 2.0f / FMath::Min(DisplaySize.X, DisplaySize.Y);
}
@@ -11,12 +11,14 @@ struct FGameplayAttributeData;
struct FGameplayCueNotify_SpawnResult;
struct FGameplayCueParameters;
//--------------------------------------------------------------------------------------------------------------------------
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(meta = (ScriptName = "CogSampleFunctionLibrary_Gameplay"))
class UCogSampleFunctionLibrary_Gameplay : public UBlueprintFunctionLibrary
{
@@ -24,8 +26,6 @@ class UCogSampleFunctionLibrary_Gameplay : public UBlueprintFunctionLibrary
public:
static void AdjustAttributeForMaxChange(UAbilitySystemComponent* AbilityComponent, FGameplayAttributeData& AffectedAttribute, float OldValue, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty);
UFUNCTION(BlueprintPure)
static FVector GetActorBottomLocation(const AActor* Actor);
@@ -49,4 +49,28 @@ public:
UFUNCTION(BlueprintPure)
static int32 GetIntValue(const FScalableFloat& ScalableFloat, int32 Level);
UFUNCTION(BlueprintPure)
static FVector GetActorTargetLocation(const AActor* Actor);
UFUNCTION(BlueprintPure)
static float AngleBetweenVector2D(FVector2D A, FVector2D B);
UFUNCTION(BlueprintPure)
static void FindSegmentPointDistance(const FVector2D& Segment1, const FVector2D& Segment2, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance);
UFUNCTION(BlueprintPure)
static void FindCapsulePointDistance(const FVector2D& CapsulePoint1, const FVector2D& CapsulePoint2, const float CapsuleRadius, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance);
static void AdjustAttributeForMaxChange(UAbilitySystemComponent* AbilityComponent, FGameplayAttributeData& AffectedAttribute, float OldValue, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty);
static FCollisionObjectQueryParams ConfigureCollisionObjectParams(const TArray<TEnumAsByte<EObjectTypeQuery>>& ObjectTypes);
static FVector2D ViewportToScreen(const FVector2D& value, const FVector2D& displaySize);
static float ViewportToScreen(const float value, const FVector2D& displaySize);
static FVector2D ScreenToViewport(const FVector2D& value, const FVector2D& displaySize);
static float ScreenToViewport(const float value, const FVector2D& displaySize);
};
@@ -0,0 +1,70 @@
#include "CogSampleFunctionLibrary_Team.h"
#include "CogSampleTeamInterface.h"
//--------------------------------------------------------------------------------------------------------------------------
ECogSampleAllegiance UCogSampleFunctionLibrary_Team::GetTeamsAllegiance(int32 Team1, int32 Team2)
{
if (Team1 == 0 || Team2 == 0)
{
return ECogSampleAllegiance::Neutral;
}
if (Team1 == Team2)
{
return ECogSampleAllegiance::Friendly;
}
return ECogSampleAllegiance::Enemy;
}
//--------------------------------------------------------------------------------------------------------------------------
ECogSampleAllegiance UCogSampleFunctionLibrary_Team::GetActorsAllegiance(const AActor* Actor1, const AActor* Actor2)
{
const ICogSampleTeamInterface* TeamActor1 = Cast<ICogSampleTeamInterface>(Actor1);
const ICogSampleTeamInterface* TeamActor2 = Cast<ICogSampleTeamInterface>(Actor2);
if (TeamActor1 == nullptr || TeamActor2 == nullptr)
{
return ECogSampleAllegiance::Neutral;
}
const int32 Team1 = TeamActor1->GetTeam();
const int32 Team2 = TeamActor2->GetTeam();
const ECogSampleAllegiance Allegiance = GetTeamsAllegiance(Team1, Team2);
return Allegiance;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleFunctionLibrary_Team::MatchAllegiance(const AActor* Actor1, const AActor* Actor2, int32 AllegianceFilter)
{
const ECogSampleAllegiance Allegiance = GetActorsAllegiance(Actor1, Actor2);
const bool Result = MatchAllegianceFilter(Allegiance, AllegianceFilter);
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleFunctionLibrary_Team::MatchAllegianceFilter(ECogSampleAllegiance Allegiance, int32 AllegianceFilter)
{
const bool HasFriendly = (AllegianceFilter & (int)ECogSampleAllegianceFilter::Friendly) != 0;
const bool HasNeutral = (AllegianceFilter & (int)ECogSampleAllegianceFilter::Neutral) != 0;
const bool HasEnemy = (AllegianceFilter & (int)ECogSampleAllegianceFilter::Enemy) != 0;
if (Allegiance == ECogSampleAllegiance::Friendly && HasFriendly)
{
return true;
}
if (Allegiance == ECogSampleAllegiance::Neutral && HasNeutral)
{
return true;
}
if (Allegiance == ECogSampleAllegiance::Enemy && HasEnemy)
{
return true;
}
return false;
}
@@ -0,0 +1,46 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleFunctionLibrary_Team.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleAllegiance : uint8
{
Friendly,
Neutral,
Enemy,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class ECogSampleAllegianceFilter : uint8
{
None = 0 UMETA(Hidden),
Friendly = 1 << 0,
Neutral = 1 << 1,
Enemy = 1 << 2,
};
ENUM_CLASS_FLAGS(ECogSampleAllegianceFilter);
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(meta = (ScriptName = "CogSampleFunctionLibrary_Team"))
class UCogSampleFunctionLibrary_Team : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure)
static ECogSampleAllegiance GetTeamsAllegiance(int32 Team1, int32 Team2);
UFUNCTION(BlueprintPure)
static ECogSampleAllegiance GetActorsAllegiance(const AActor* Actor1, const AActor* Actor2);
UFUNCTION(BlueprintPure)
static bool MatchAllegiance(const AActor* Actor1, const AActor* Actor2, UPARAM(meta = (Bitmask, BitmaskEnum = "/Script/CogSample.ECogSampleAllegianceFilter")) int32 AllegianceFilter);
UFUNCTION(BlueprintPure)
static bool MatchAllegianceFilter(ECogSampleAllegiance Allegiance, UPARAM(meta = (Bitmask, BitmaskEnum = "/Script/CogSample.ECogSampleAllegianceFilter")) int32 AllegianceFilter);
};
+2
View File
@@ -22,6 +22,7 @@
#include "CogAbilityWindow_Tags.h"
#include "CogAbilityWindow_Tweaks.h"
#include "CogDebugDefines.h"
#include "CogDebugDrawImGui.h"
#include "CogDebugPlot.h"
#include "CogEngineDataAsset_Collisions.h"
#include "CogEngineDataAsset_Spawns.h"
@@ -220,6 +221,7 @@ void ACogSampleGameState::InitializeCog()
void ACogSampleGameState::RenderCog(float DeltaTime)
{
CogWindowManager->Render(DeltaTime);
FCogDebugDrawImGui::Draw();
}
#endif //USE_COG
+13 -11
View File
@@ -4,7 +4,7 @@
#include "CogDefines.h"
#if USE_COG
#include "CogDebugLogCategoryManager.h"
#include "CogDebugLog.h"
#endif //USE_COG
DEFINE_LOG_CATEGORY(LogCogAlways);
@@ -15,22 +15,24 @@ DEFINE_LOG_CATEGORY(LogCogRotation);
DEFINE_LOG_CATEGORY(LogCogControlRotation);
DEFINE_LOG_CATEGORY(LogCogBaseAimRotation);
DEFINE_LOG_CATEGORY(LogCogSkeleton);
DEFINE_LOG_CATEGORY(LogCogTargetAcquisition);
namespace CogSampleLog
{
void RegiterAllLogCategories()
{
#if USE_COG
FCogDebugLogCategoryManager::AddLogCategory(LogCogAlways, "Always", false);
FCogDebugLogCategoryManager::AddLogCategory(LogAbilitySystem, "Ability System");
FCogDebugLogCategoryManager::AddLogCategory(LogGameplayEffects, "Gameplay Effects");
FCogDebugLogCategoryManager::AddLogCategory(LogCogCollision, "Collision");
FCogDebugLogCategoryManager::AddLogCategory(LogCogInput, "Input");
FCogDebugLogCategoryManager::AddLogCategory(LogCogPosition, "Position");
FCogDebugLogCategoryManager::AddLogCategory(LogCogRotation, "Rotation");
FCogDebugLogCategoryManager::AddLogCategory(LogCogControlRotation, "ControlRotation");
FCogDebugLogCategoryManager::AddLogCategory(LogCogBaseAimRotation, "BaseAimRotation");
FCogDebugLogCategoryManager::AddLogCategory(LogCogSkeleton, "Skeleton");
FCogDebugLog::AddLogCategory(LogCogAlways, "Always", false);
FCogDebugLog::AddLogCategory(LogAbilitySystem, "Ability System");
FCogDebugLog::AddLogCategory(LogGameplayEffects, "Gameplay Effects");
FCogDebugLog::AddLogCategory(LogCogCollision, "Collision");
FCogDebugLog::AddLogCategory(LogCogInput, "Input");
FCogDebugLog::AddLogCategory(LogCogPosition, "Position");
FCogDebugLog::AddLogCategory(LogCogRotation, "Rotation");
FCogDebugLog::AddLogCategory(LogCogControlRotation, "ControlRotation");
FCogDebugLog::AddLogCategory(LogCogBaseAimRotation, "BaseAimRotation");
FCogDebugLog::AddLogCategory(LogCogSkeleton, "Skeleton");
FCogDebugLog::AddLogCategory(LogCogTargetAcquisition, "Target Acquisition");
#endif //USE_COG
}
}
@@ -8,6 +8,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogCogRotation, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogControlRotation, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogBaseAimRotation, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogSkeleton, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogTargetAcquisition, Warning, All);
namespace CogSampleLog
{
@@ -2,6 +2,7 @@
#include "CogDefines.h"
#include "CogSampleCharacter.h"
#include "CogSampleTargetAcquisition.h"
#include "Net/UnrealNetwork.h"
#if USE_COG
@@ -38,4 +39,18 @@ void ACogSamplePlayerController::AcknowledgePossession(APawn* P)
{
PossessedCharacter->OnAcknowledgePossession(this);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSamplePlayerController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (TargetAcquisition != nullptr)
{
TArray<AActor*> TagretToIgnore;
FCogSampleTargetAcquisitionResult Result;
TargetAcquisition->FindBestTarget(this, TagretToIgnore, nullptr, true, FVector2D::ZeroVector, false, Result);
Target = Result.Target;
}
}
@@ -5,6 +5,8 @@
#include "GameFramework/PlayerController.h"
#include "CogSamplePlayerController.generated.h"
class UCogSampleTargetAcquisition;
UCLASS(config=Game)
class ACogSamplePlayerController : public APlayerController
{
@@ -13,11 +15,19 @@ class ACogSamplePlayerController : public APlayerController
public:
ACogSamplePlayerController();
virtual void BeginPlay() override;
virtual void AcknowledgePossession(APawn* P);
virtual void Tick(float DeltaSeconds);
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true"))
UCogSampleTargetAcquisition* TargetAcquisition = nullptr;
UPROPERTY(BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true"))
TSoftObjectPtr<AActor> Target = nullptr;
};
@@ -0,0 +1,886 @@
#include "CogSampleTargetAcquisition.h"
#include "Camera/CameraComponent.h"
#include "CogDefines.h"
#include "CogSampleCharacter.h"
#include "CogSampleFunctionLibrary_Gameplay.h"
#include "CogSampleLogCategories.h"
#include "CogSampleTargetableInterface.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/PlayerController.h"
#if USE_COG
#include "CogDebugDraw.h"
#include "CogDebugLog.h"
#endif //USE_COG
//--------------------------------------------------------------------------------------------------------------------------
// UCogSampleTargetAcquisition_Generic
//--------------------------------------------------------------------------------------------------------------------------
struct FCogSampleTargetCandidateEvaluationParameters
{
const AActor* Source;
FVector SourceLocation;
const APlayerController* Controller;
TArray<AActor*> TargetsToIgnore;
bool bWorldDistanceIgnoreZ = false;
float MaxWorldDistance = 0.0f;
FVector2D CrosshairPosition = FVector2D::ZeroVector;
FVector YawDirection = FVector::ZeroVector;
FVector CameraRight = FVector::ZeroVector;
FMatrix ViewProjectionMatrix;
FIntRect ViewRect;
FCollisionObjectQueryParams BlockersParams;
bool bUseSearchDirection = false;
FVector2D SearchDirectionScreenOrigin = FVector2D::ZeroVector;
FVector2D SearchDirectionNormalized = FVector2D::ZeroVector;
bool IsDebugPersistent = false;
};
//--------------------------------------------------------------------------------------------------------------------------
struct FCogSampleTargetCandidateEvaluationResult
{
AActor* BestTarget;
float MinScore;
bool bFoundLocationInsideShape;
};
//--------------------------------------------------------------------------------------------------------------------------
// UCogSampleTargetAcquisition_Generic
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleTargetAcquisition::FindBestTargets(
const APlayerController* Controller,
const int32 TargetCount,
const TArray<AActor*>& TargetsToIgnore,
const AActor* CurrentLockedTarget,
const bool bForceSynchronousDetection,
const FVector2D ScreenSearchDirection,
bool bIsDebugPersistent,
TArray<FCogSampleTargetAcquisitionResult>& Results) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargets);
COG(FCogDebugDraw::String2D(LogCogTargetAcquisition, Controller, GetName(), FVector2D(20, 20), FColor::White, bIsDebugPersistent));
TArray<AActor*> TempTargetsToIgnore(TargetsToIgnore);
//---------------------------------------
// Find multiple target
//---------------------------------------
for (int32 i = 0; i < TargetCount; i++)
{
FCogSampleTargetAcquisitionResult Result;
FindBestTarget(
Controller,
TempTargetsToIgnore,
CurrentLockedTarget,
bForceSynchronousDetection,
ScreenSearchDirection,
bIsDebugPersistent,
Result);
//---------------------------------------
// Stop when out of valid targets
//---------------------------------------
if (Result.Target == nullptr)
{
break;
}
Results.Add(Result);
TempTargetsToIgnore.Add(Result.Target);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleTargetAcquisition::FindBestTarget(
const APlayerController* Controller,
const TArray<AActor*>& TargetsToIgnore,
const AActor* CurrentLockedTarget,
const bool bForceSynchronousDetection,
const FVector2D TargetSwitchSearchDirection,
const bool bIsDebugPersistent,
FCogSampleTargetAcquisitionResult& Result) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTarget);
ACogSampleCharacter* Character = Cast<ACogSampleCharacter>(Controller->GetPawn());
if (Character == nullptr)
{
return;
}
if (FMath::IsNearlyZero(DetectionLength) && FMath::IsNearlyZero(DetectionRadius))
{
return;
}
FMatrix ViewProjectionMatrix;
FIntRect ViewRect;
if (GetViewInfo(Controller, ViewProjectionMatrix, ViewRect) == false)
{
return;
}
FVector2D SearchDirectionScreenOrigin(ViewRect.Width() / 2.0f, ViewRect.Height() / 2.0f);
if (CurrentLockedTarget != nullptr)
{
FVector CurrentLockedTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(CurrentLockedTarget);
FSceneView::ProjectWorldToScreen(CurrentLockedTargetLocation, ViewRect, ViewProjectionMatrix, SearchDirectionScreenOrigin);
}
//----------------------------------------------------------------------------------------------------------------------
// Draw the ScreenSearchDirection if valid
//----------------------------------------------------------------------------------------------------------------------
#if USE_COG
const FVector2D SearchDirectionNormalized = (TargetSwitchSearchDirection.IsNearlyZero() == false) ? TargetSwitchSearchDirection.GetSafeNormal() : FVector2D::ZeroVector;
if (SearchDirectionNormalized.IsNearlyZero() == false)
{
COG(FCogDebugDraw::Segment2D(LogCogTargetAcquisition, Controller, FVector2D::ZeroVector, FVector2D(SearchDirectionNormalized.X, -SearchDirectionNormalized.Y), FColor(255, 255, 0, 255), bIsDebugPersistent));
}
#endif //USE_COG
static const FName TraceTag(TEXT("FindLockTarget_GatherTargets"));
FCollisionQueryParams QueryParams(TraceTag, SCENE_QUERY_STAT_ONLY(CogSampleTargetAcquisition), false);
QueryParams.bReturnPhysicalMaterial = true;
QueryParams.bReturnFaceIndex = false;
QueryParams.AddIgnoredActor(Character);
const FCollisionObjectQueryParams ObjectParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(ObjectTypes);
const FVector CastLocation = GetReferentialLocation(Character, DetectionLocation);
const FRotator CastRotation = GetReferentialRotation(Character, DetectionRotation);
const float CapsuleHalfHeight = DetectionLength * 0.5f;
const float CapsuleRadius = DetectionRadius;
const FVector CapsuleCenter = CastLocation + CastRotation.Vector() * CapsuleHalfHeight;
const FQuat CapsuleRotation = (CastRotation + FRotator(90, 0, 0)).Quaternion();
const FCollisionShape CapsuleShape = FCollisionShape::MakeCapsule(CapsuleRadius, CapsuleHalfHeight);
COG(FCogDebugDraw::Capsule(LogCogTargetAcquisition, Controller, CapsuleCenter, CapsuleHalfHeight, CapsuleRadius, CapsuleRotation, FColor::Yellow, bIsDebugPersistent, 0));
//-------------------------------------------------
// Gather targets asynchronously
//-------------------------------------------------
TArray<AActor*> QueriedActors;
//if (UseAsyncDetection && bForceSynchronousDetection == false)
//{
// TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition_Generic::EvaluateCandidateQueryAsync);
// FOverlapDatum OutData;
// if (Character->GetWorld()->QueryOverlapData(QueryHandle, OutData))
// {
// for (const FOverlapResult& Overlap : OutData.OutOverlaps)
// {
// if (AActor* Target = Overlap.GetActor())
// {
// QueriedActors.Add(Target);
// }
// }
// }
// QueryHandle = Character->GetWorld()->AsyncOverlapByObjectType(
// CapsuleCenter,
// CapsuleRotation,
// ObjectParams,
// CapsuleShape,
// QueryParams);
//}
//-------------------------------------------------
// Gather targets synchronously
//-------------------------------------------------
//else
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::EvaluateCandidateQuerySync);
TArray<FOverlapResult> OutOverlaps;
const bool Hit = Character->GetWorld()->OverlapMultiByObjectType(
OutOverlaps,
CapsuleCenter,
CapsuleRotation,
ObjectParams,
CapsuleShape,
QueryParams);
for (const FOverlapResult& Overlap : OutOverlaps)
{
if (AActor* Target = Overlap.GetActor())
{
QueriedActors.Add(Target);
}
}
}
//-------------------------------------------------
// Validate actors
//-------------------------------------------------
TArray<AActor*> ValidCandidates;
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::EvaluateCandidateCheckValids);
for (AActor* Actor : QueriedActors)
{
if (CheckIfTargetValid(Controller, Character, Actor) == false)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, "Filter", UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Actor), FColor::Red, bIsDebugPersistent));
continue;
}
ValidCandidates.Add(Actor);
}
}
FindBestTargetInCandidates(Controller, TargetsToIgnore, ValidCandidates, TargetSwitchSearchDirection, SearchDirectionScreenOrigin, bIsDebugPersistent, Result);
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::GetViewInfo(
const APlayerController* Controller,
FMatrix& viewProjectionMatrix,
FIntRect& viewRect) const
{
const ULocalPlayer* localPlayer = Controller->GetLocalPlayer();
if (localPlayer == nullptr || localPlayer->ViewportClient == nullptr)
{
return false;
}
FSceneViewProjectionData projectionData;
if (localPlayer->GetProjectionData(localPlayer->ViewportClient->Viewport, projectionData) == false)
{
return false;
}
viewProjectionMatrix = projectionData.ComputeViewProjectionMatrix();
viewRect = projectionData.GetConstrainedViewRect();
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::EvaluateCandidate(
AActor* CandidateTarget,
const FCogSampleTargetCandidateEvaluationParameters& EvalParams,
FCogSampleTargetCandidateEvaluationResult& EvalResult) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::EvaluateCandidate);
if (EvalParams.TargetsToIgnore.Contains(CandidateTarget))
{
return false;
}
const FVector CandidateTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(CandidateTarget);
FVector CandidateLocationDelta = CandidateTargetLocation - EvalParams.SourceLocation;
if (EvalParams.bWorldDistanceIgnoreZ)
{
CandidateLocationDelta.Z = 0.0f;
}
const float CandidateWorldDistance = CandidateLocationDelta.Length();
const FVector CandidateWorldDirection = CandidateWorldDistance > 0.0f ? CandidateLocationDelta / CandidateWorldDistance : FVector::ZeroVector;
const float ScreenMagnitude = FMath::Min(EvalParams.ViewRect.Width(), EvalParams.ViewRect.Height());
const bool IsSearchDirectionUsed = bUseSearchDirectionScore && EvalParams.SearchDirectionNormalized.IsNearlyZero() == false;
//--------------------------------------------------------------------------------------------------------------
// Filter by world distance limit
//--------------------------------------------------------------------------------------------------------------
if (CandidateWorldDistance > EvalParams.MaxWorldDistance)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Dist: %0.2f"), CandidateWorldDistance * 0.01f), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
return false;
}
//--------------------------------------------------------------------------------------------------------------
// Filter candidates base on yaw limit when using yaw, otherwise filter anyone behind the character
//--------------------------------------------------------------------------------------------------------------
const FVector CandidateWorldDirectionFlat = CandidateWorldDirection.GetSafeNormal2D();
const float CandidateDot = EvalParams.YawDirection.Dot(CandidateWorldDirectionFlat);
const float CandidateYaw = FRotator::NormalizeAxis(FMath::RadiansToDegrees(FMath::Acos(CandidateDot)));
if (bUseYawLimit && CandidateYaw > YawMax)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Yaw: %0.2f"), CandidateYaw), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
return false;
}
//--------------------------------------------------------------------------------------------------------------
// Find the candidate screen location. If the result distance is lower than zero, it means the crosshair is
// inside the candidate capsules.
//--------------------------------------------------------------------------------------------------------------
FVector2D CandidateScreenLocation;
FVector2D CandidateClosestScreenLocation;
float CandidateClosestScreenDistance;
const UCapsuleComponent* CandidateBestHitZone = nullptr;
if (!ComputeCandidateScreenLocation(CandidateTarget, EvalParams, CandidateTargetLocation, CandidateScreenLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance))
{
return false;
}
//--------------------------------------------------------------------------------------------------------------
// Filter candidates not inside the screen distance limits.
//--------------------------------------------------------------------------------------------------------------
if (bUseScreenLimit)
{
if (!CheckCandidateWithinScreenDistance(EvalParams.Controller, EvalParams.ViewRect, CandidateTargetLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance, EvalParams.IsDebugPersistent))
{
return false;
}
}
//--------------------------------------------------------------------------------------------------------------
// Raycast to verify this target is not blocked by a collision.
//--------------------------------------------------------------------------------------------------------------
if (!HasLineOfSightToTarget(EvalParams.Source, CandidateTarget, EvalParams.BlockersParams))
{
return false;
}
const bool bIsInsideCandidate = CandidateClosestScreenDistance < 0.0f;
if (!IsSearchDirectionUsed && bPrioritizeInsideHitZones)
{
//--------------------------------------------------------------------------------------------------------------
// We always prioritize the candidates if the crosshair is inside them. Thus if we are inside another candidate
// but not inside this one, we discard it (unless we are switching the lock target)
//--------------------------------------------------------------------------------------------------------------
if (EvalResult.bFoundLocationInsideShape && bIsInsideCandidate == false)
{
return false;
}
//--------------------------------------------------------------------------------------------------------------
// if we are inside the capsule of this candidate, we can discard subsequent candidates that are not inside
// but also the best previous candidate since we were not inside it.
//--------------------------------------------------------------------------------------------------------------
if (bIsInsideCandidate && EvalResult.bFoundLocationInsideShape == false)
{
EvalResult.BestTarget = nullptr;
EvalResult.MinScore = FLT_MAX;
}
}
//--------------------------------------------------------------------------------------------------------------
// Compute a score based on the world distance
//--------------------------------------------------------------------------------------------------------------
float CandidateWorldDistanceRatio = 0.0f;
float CandidateWorldDistanceScore = 0.0f;
if (bUseWorldDistanceScore)
{
CandidateWorldDistanceRatio = (WorldDistanceMax > 0.0f) ? CandidateWorldDistance / WorldDistanceMax : 0.0f;
CandidateWorldDistanceScore = WorldDistanceScoreMultiplier * (WorldDistanceScoreCurve != nullptr ? WorldDistanceScoreCurve->GetFloatValue(CandidateWorldDistanceRatio) : CandidateWorldDistanceRatio);
}
//--------------------------------------------------------------------------------------------------------------
// Compute a score based on screen distance
//--------------------------------------------------------------------------------------------------------------
float CandidateScreenDistanceRatio = 0.0f;
float CandidateScreenDistanceScore = 0.0f;
if (bUseScreenDistanceScore && IsSearchDirectionUsed == false)
{
CandidateScreenDistanceRatio = CandidateClosestScreenDistance / ScreenMagnitude;
CandidateScreenDistanceScore = ScreenDistanceScoreMultiplier * (ScreenDistanceScoreCurve != nullptr ? ScreenDistanceScoreCurve->GetFloatValue(CandidateScreenDistanceRatio) : CandidateScreenDistanceRatio);
}
//--------------------------------------------------------------------------------------------------------------
// Compute a score based on yaw
//--------------------------------------------------------------------------------------------------------------
float CandidateYawRatio = 0.0f;
float CandidateYawScore = 0.0f;
if (bUseYawScore)
{
CandidateYawRatio = YawMax > 0.0f ? CandidateYaw / YawMax : 0.0f;
CandidateYawScore = YawScoreMultiplier * (YawScoreCurve != nullptr ? YawScoreCurve->GetFloatValue(CandidateYawRatio) : CandidateYawRatio);
}
//--------------------------------------------------------------------------------------------------------------
// Compute a score based on the search direction. (for target lock switch)
//--------------------------------------------------------------------------------------------------------------
float SearchDirectionDistanceScore = 0.0f;
float SearchDirectionAngleScore = 0.0f;
float SearchDirectionDistanceRatio = 0.0f;
float SearchDirectionAngleRatio = 0.0f;
if (IsSearchDirectionUsed)
{
const float TargetAngleWithSearchDirection = UCogSampleFunctionLibrary_Gameplay::AngleBetweenVector2D(CandidateScreenLocation - EvalParams.SearchDirectionScreenOrigin, EvalParams.SearchDirectionNormalized);
if (FMath::Abs(TargetAngleWithSearchDirection) > SearchDirectionMaxAngle)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("MaxAngle: %0.2f"), TargetAngleWithSearchDirection), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
return false;
}
SearchDirectionDistanceRatio = FVector2D::Distance(CandidateScreenLocation, EvalParams.SearchDirectionScreenOrigin) / ScreenMagnitude;
SearchDirectionDistanceScore = SearchDirectionDistanceScoreMultiplier * (ScreenSearchDirectionDistanceScoreCurve != nullptr ? ScreenSearchDirectionDistanceScoreCurve->GetFloatValue(SearchDirectionDistanceRatio) : SearchDirectionDistanceRatio);
SearchDirectionAngleRatio = SearchDirectionMaxAngle > 0.0f ? TargetAngleWithSearchDirection / SearchDirectionMaxAngle : 0.0f;
SearchDirectionAngleScore = ScreenSearchDirectionAngleScoreMultiplier * (ScreenSearchDirectionAngleScoreCurve != nullptr ? ScreenSearchDirectionAngleScoreCurve->GetFloatValue(SearchDirectionAngleRatio) : SearchDirectionAngleRatio);
}
//--------------------------------------------------------------------------------------------------------------
// Compute final score by summing all the scores. The best score is the smallest one.
//--------------------------------------------------------------------------------------------------------------
const float TargetScore = CandidateWorldDistanceScore + CandidateScreenDistanceScore + CandidateYawScore + SearchDirectionDistanceScore + SearchDirectionAngleScore;
//--------------------------------------------------------------------------------------------------------------
// Draw the score of each candidate
//--------------------------------------------------------------------------------------------------------------
#if USE_COG
/*
if (FCogDebugLog::IsLogCategoryActive(LogCogTargetAcquisition))
{
ImVec2 CandidateClosestViewportLocation = ImGui::ScreenToViewport(ImGui::ToImVec2(CandidateClosestScreenLocation));
FCogDebugDraw::Point(LogCogTargetAcquisition, EvalParams.Controller, CandidateTargetLocation, 8.0f, FColor::Blue, EvalParams.IsDebugPersistent, 0);
FString Text;
if (LogCogTargetAcquisition.GetVerbosity() == ELogVerbosity::VeryVerbose)
{
if (bUseScreenDistanceScore)
{
Text.Append(FString::Printf(TEXT
(
"XY: %.0f %.0f \n"
"SD: %.0f => %.0f => %.0f \n"
),
CandidateClosestViewportLocation.x * 100.0f, CandidateClosestViewportLocation.y * 100.0f,
CandidateClosestScreenDistance, CandidateScreenDistanceRatio * 100, CandidateScreenDistanceScore * 100));
}
if (bUseWorldDistanceScore)
{
Text.Append(FString::Printf(TEXT("WD: %.0f => %.0f => %.0f \n"),
CandidateWorldDistance * 0.01f,
CandidateWorldDistanceRatio * 100,
CandidateWorldDistanceScore * 100));
}
if (bUseYawScore)
{
Text.Append(FString::Printf(TEXT("Y: %.1f => %.0f => %.0f \n"),
CandidateYaw,
CandidateYawRatio * 100,
CandidateYawScore * 100));
}
if (bUseSearchDirectionScore)
{
Text.Append(FString::Printf(TEXT("VD: %.0f => %.0f \n" "VA: %.0f => %.0f \n"),
SearchDirectionDistanceRatio * 100,
SearchDirectionDistanceScore * 100,
SearchDirectionAngleRatio * 100,
SearchDirectionAngleScore * 100));
}
Text.Append(FString::Printf(TEXT("==> %.0f \n"), TargetScore * 100));
}
else
{
Text = FString::Printf(TEXT("%0.f"), TargetScore * 100);
}
FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, Text, CandidateTargetLocation, FColor::White, EvalParams.IsDebugPersistent);
}
*/
#endif //USE_COG
if (EvalResult.MinScore < TargetScore)
{
return false;
}
EvalResult.BestTarget = CandidateTarget;
EvalResult.MinScore = TargetScore;
EvalResult.bFoundLocationInsideShape = EvalResult.bFoundLocationInsideShape || bIsInsideCandidate;
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleTargetAcquisition::FindBestTargetInCandidates(
const APlayerController* Controller,
const TArray<AActor*>& TargetsToIgnore,
const TArray<AActor*>& Candidates,
const FVector2D ScreenSearchDirection,
const FVector2D SearchDirectionScreenOrigin,
const bool bIsDebugPersistent,
FCogSampleTargetAcquisitionResult& Result) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargetInCandidates);
ACogSampleCharacter* Character = Cast<ACogSampleCharacter>(Controller->GetPawn());
if (Character == nullptr)
{
return;
}
//----------------------------------------------------------------------------------------------------------------------
// Compute view matrix to project each candidate capsules in screen space
//----------------------------------------------------------------------------------------------------------------------
FMatrix ViewProjectionMatrix;
FIntRect ViewRect;
if (GetViewInfo(Controller, ViewProjectionMatrix, ViewRect) == false)
{
return;
}
//----------------------------------------------------------------------------------------------------------------------
// Draw screen limits
//----------------------------------------------------------------------------------------------------------------------
FVector2D ScreenCrosshairPosition(0.5f * ViewRect.Width(), 0.5f * ViewRect.Height());
COG(FCogDebugDraw::Circle2D(LogCogTargetAcquisition, Controller, ScreenCrosshairPosition, 5.0f, FColor(255, 255, 255, 255), bIsDebugPersistent));
#if USE_COG
//if (bUseScreenLimit)
//{
// if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Rectangle)
// {
// COG(FCogDebugDraw::Rect2D(
// LogCogTargetAcquisition,
// Controller,
// FVector2D(-ScreenMaxX, -ScreenMaxY),
// FVector2D(ScreenMaxX, ScreenMaxY),
// FColor(255, 255, 255, 255),
// bIsDebugPersistent));
// }
// else
// {
// COG(FCogDebugDraw::Circle2D(
// LogCogTargetAcquisition,
// Controller,
// ScreenCrosshairPosition,
// ImGui::ViewportToScreen(ScreenMaxX),
// FColor(255, 255, 255, 255),
// bIsDebugPersistent));
// }
//}
#endif //USE_COG
const FRotator YawRotation = GetReferentialRotation(Character, YawReferential);
const FVector YawDirection = YawRotation.Vector();
FCogSampleTargetCandidateEvaluationParameters EvalParams;
EvalParams.Source = Character;
EvalParams.SourceLocation = Character->GetActorLocation();
EvalParams.Controller = Controller;
EvalParams.TargetsToIgnore = TargetsToIgnore;
EvalParams.bWorldDistanceIgnoreZ = WorldDistanceIgnoreZ;
EvalParams.MaxWorldDistance = WorldDistanceMax;
EvalParams.CrosshairPosition = ScreenCrosshairPosition;
EvalParams.YawDirection = YawDirection;
EvalParams.CameraRight = Character->GetFollowCamera()->GetComponentQuat().GetRightVector();
EvalParams.ViewProjectionMatrix = ViewProjectionMatrix;
EvalParams.ViewRect = ViewRect;
EvalParams.BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes);
EvalParams.bUseSearchDirection = ScreenSearchDirection.IsNearlyZero() == false;
EvalParams.SearchDirectionScreenOrigin = SearchDirectionScreenOrigin;
EvalParams.SearchDirectionNormalized = EvalParams.bUseSearchDirection ? ScreenSearchDirection.GetSafeNormal() : FVector2D::ZeroVector;
EvalParams.IsDebugPersistent = bIsDebugPersistent;
FCogSampleTargetCandidateEvaluationResult EvalResult
{
nullptr,
FLT_MAX,
false
};
//----------------------------------------------------------------------------------------------------------------------
// Evaluate candidates actors
//----------------------------------------------------------------------------------------------------------------------
for (int32 i = 0; i < Candidates.Num(); ++i)
{
AActor* Candidate = Candidates[i];
check(Candidate != nullptr);
if (Candidate == nullptr)
{
continue;
}
EvaluateCandidate(Candidate, EvalParams, EvalResult);
}
if (EvalResult.BestTarget != nullptr)
{
Result.Target = EvalResult.BestTarget;
Result.Score = EvalResult.MinScore;
COG(FCogDebugDraw::Point(LogCogTargetAcquisition, Controller, UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Result.Target), 10.0f, FColor::Green, EvalParams.IsDebugPersistent, 0));
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation(
const AActor* CandidateActor,
const FCogSampleTargetCandidateEvaluationParameters& EvalParams,
const FVector& CandidateTargetLocation,
FVector2D& CandidateScreenLocation,
FVector2D& CandidateClosestScreenLocation,
float& CandidateClosestScreenDistance) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::ComputeCandidateScreenLocation);
check(CandidateActor);
bool bFoundValidCandidate = false;
CandidateScreenLocation = FVector2D::ZeroVector;
CandidateClosestScreenDistance = FLT_MAX;
if (const ICogSampleTargetableInterface* Targetable = Cast<ICogSampleTargetableInterface>(CandidateActor))
{
TArray<const UCapsuleComponent*> Capsules;
Targetable->GetTargetCapsules(Capsules);
for (const UCapsuleComponent* Capsule : Capsules)
{
const float Radius = Capsule->GetScaledCapsuleRadius();
const float HalfHeight = Capsule->GetScaledCapsuleHalfHeight();
const FVector CapsuleLocation = Capsule->GetComponentLocation();
const FVector CapsuleTop = CapsuleLocation + FVector::UpVector * (HalfHeight - Radius);
const FVector CapsuleBottom = CapsuleLocation - FVector::UpVector * (HalfHeight - Radius);
const FVector CapsuleRight = CapsuleLocation - EvalParams.CameraRight * Radius;
FVector2D CapsuleTop2D;
FVector2D CapsuleBot2D;
FVector2D CapsuleRight2D;
if (FSceneView::ProjectWorldToScreen(CapsuleTop, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleTop2D) == false)
{
continue;
}
if (FSceneView::ProjectWorldToScreen(CapsuleBottom, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleBot2D) == false)
{
continue;
}
if (FSceneView::ProjectWorldToScreen(CapsuleRight, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleRight2D) == false)
{
continue;
}
//if (Type == ECogSampleTargetAcquisitionType::Melee && CandidateCharacter != nullptr && !UCogFunctionLibrary_Targeting::IsTargetCapsuleReachableByMelee(EvalParams.Source, CandidateCharacter, Capsule))
//{
// continue;
//}
const FVector2D CapsuleCenter2D = CapsuleBot2D + 0.5f * (CapsuleTop2D - CapsuleBot2D);
const float CapsuleRadius2D = FVector2D::Distance(CapsuleCenter2D, CapsuleRight2D);
FVector2D Projection;
float Time;
float ScreenCenterToCapsuleDistance;
UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(CapsuleBot2D, CapsuleTop2D, CapsuleRadius2D, EvalParams.CrosshairPosition, Projection, Time, ScreenCenterToCapsuleDistance);
if (ScreenCenterToCapsuleDistance < CandidateClosestScreenDistance)
{
CandidateScreenLocation = CapsuleCenter2D;
CandidateClosestScreenDistance = ScreenCenterToCapsuleDistance;
CandidateClosestScreenLocation = Projection;
bFoundValidCandidate = true;
}
#if USE_COG
const FColor CapsuleColor = (ScreenCenterToCapsuleDistance > 0.0f) ? FColor(255, 255, 255, 100) : FColor(0, 255, 0, 200);
FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D + FVector2D(CapsuleRadius2D, 0), CapsuleTop2D + FVector2D(CapsuleRadius2D, 0), CapsuleColor, EvalParams.IsDebugPersistent);
FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D - FVector2D(CapsuleRadius2D, 0), CapsuleTop2D - FVector2D(CapsuleRadius2D, 0), CapsuleColor, EvalParams.IsDebugPersistent);
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleTop2D, CapsuleRadius2D, CapsuleColor, EvalParams.IsDebugPersistent);
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D, CapsuleRadius2D, CapsuleColor, EvalParams.IsDebugPersistent);
#endif //USE_COG
}
}
else
{
if (FSceneView::ProjectWorldToScreen(CandidateTargetLocation, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CandidateScreenLocation))
{
CandidateClosestScreenDistance = CandidateScreenLocation.Length();
CandidateClosestScreenLocation = CandidateScreenLocation;
bFoundValidCandidate = true;
}
}
#if USE_COG
if (bFoundValidCandidate)
{
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CandidateClosestScreenLocation, 2.0f, FColor(0, 255, 0, 255), EvalParams.IsDebugPersistent);
}
#endif //USE_COG
return bFoundValidCandidate;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance(
const APlayerController* Controller,
const FIntRect& ViewRect,
const FVector& CandidateLocation,
const FVector2D& CandidateScreenLocation,
const float CandidateScreenDistance,
const bool bIsDebugPersistent) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance);
const FVector2D ScreenSize(ViewRect.Width(), ViewRect.Height());
const FVector2D CandidateViewportLocation = UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(CandidateScreenLocation, ScreenSize);
const float CandidateViewportDistance = UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(CandidateScreenDistance, ScreenSize);
//--------------------------------------------------------------------------------------------------------------
// Filter by screen distance - within rectangle
//--------------------------------------------------------------------------------------------------------------
if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Rectangle)
{
if (FMath::Abs(CandidateViewportLocation.X) > ScreenMaxX)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxX: %0.2f"), CandidateViewportLocation.X), CandidateLocation, FColor::Red, bIsDebugPersistent));
return false;
}
if (FMath::Abs(CandidateViewportLocation.Y) > ScreenMaxY)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxY: %0.2f"), CandidateViewportLocation.Y), CandidateLocation, FColor::Red, bIsDebugPersistent));
return false;
}
}
//--------------------------------------------------------------------------------------------------------------
// Filter by screen distance - within circle
//--------------------------------------------------------------------------------------------------------------
else if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Circle)
{
if (CandidateViewportDistance > ScreenMaxX)
{
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("Max: %0.2f"), CandidateViewportDistance), CandidateLocation, FColor::Red, bIsDebugPersistent));
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::CheckIfTargetValid(
const APlayerController* Controller,
const AActor* Source,
const AActor* Target) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::CheckIfTargetValid);
if (UCogSampleFunctionLibrary_Team::MatchAllegiance(Source, Target, Allegiance) == false)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::HasLineOfSightToTarget(
const AActor* Source,
const AActor* Target,
const FCollisionObjectQueryParams& BlockersParams) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::HasLineOfSightToTarget);
const FVector Origin = Source->GetActorLocation();
static const FName BlockerTraceTag(TEXT("FindLockTarget_Blocker"));
FCollisionQueryParams TargetQueryParams(BlockerTraceTag, SCENE_QUERY_STAT_ONLY(CogSampleTargetAcquisition), false);
TargetQueryParams.AddIgnoredActor(Target);
return true;
//return FCogHitDetectionHelper::HasLineOfSight(Source->GetWorld(), Origin, Target.GetTargetLocation(), BlockersParams, TargetQueryParams, LogCogTargetAcquisition);
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong(
const AActor* Source,
const AActor* Target,
const float DeltaTime,
float& Timer) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong);
const FCollisionObjectQueryParams BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes);
bool HasLineOfSight = HasLineOfSightToTarget(Source, Target, BlockersParams);
if (HasLineOfSight)
{
Timer = 0.0f;
}
else
{
Timer += DeltaTime;
if (Timer > BreakLineOfSightDelay)
{
Timer = 0.0f;
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------
FVector UCogSampleTargetAcquisition::GetReferentialLocation(const ACogSampleCharacter* Character, ECogSampleTargetAcquisitionLocationReferential Referential)
{
FVector Location;
switch (Referential)
{
case ECogSampleTargetAcquisitionLocationReferential::Character:
{
Location = UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(Character);
break;
}
case ECogSampleTargetAcquisitionLocationReferential::Camera:
{
Location = Character->GetFollowCamera()->GetComponentLocation();
break;
}
}
return Location;
}
//--------------------------------------------------------------------------------------------------------------------------
FRotator UCogSampleTargetAcquisition::GetReferentialRotation(const ACogSampleCharacter* Character, ECogSampleTargetAcquisitionRotationReferential Referential)
{
FRotator Rotation;
switch (Referential)
{
case ECogSampleTargetAcquisitionRotationReferential::Character:
{
Rotation = Character->GetActorRotation();
break;
}
case ECogSampleTargetAcquisitionRotationReferential::MoveInput:
{
//const FVector WorldInput = Character->TransformInputInWorldSpace(Character->GetDesiredMoveInput());
//if (WorldInput.IsNearlyZero())
//{
// Rotation = Character->GetActorRotation();
//}
//else
//{
// Rotation = WorldInput.GetSafeNormal().Rotation();
//}
//break;
}
case ECogSampleTargetAcquisitionRotationReferential::Camera:
{
Rotation = Character->GetFollowCamera()->GetComponentRotation();
break;
}
case ECogSampleTargetAcquisitionRotationReferential::CameraFlatten:
{
const FVector CameraForwardFlat = Character->GetFollowCamera()->GetComponentQuat().GetForwardVector().GetSafeNormal2D();
Rotation = CameraForwardFlat.Rotation();
break;
}
}
return Rotation;
}
@@ -0,0 +1,296 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleFunctionLibrary_Team.h"
#include "Engine/DataAsset.h"
#include "Engine/EngineTypes.h"
#include "WorldCollision.h"
#include "CogSampleTargetAcquisition.generated.h"
class ACogSampleCharacter;
class APlayerController;
class UCurveFloat;
struct FCogSampleTargetCandidateEvaluationResult;
struct FCogSampleTargetCandidateEvaluationParameters;
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleTargetAcquisitionType : uint8
{
Melee,
Range
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleTargetAcquisitionScreenLimitType : uint8
{
Rectangle,
Circle,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleTargetAcquisitionLocationReferential : uint8
{
Character,
Camera,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleTargetAcquisitionRotationReferential : uint8
{
Camera,
CameraFlatten,
Character,
MoveInput,
};
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType)
enum class ECogSampleTargetAcquisitionCrosshairReferential : uint8
{
Centered,
Offseted,
};
//--------------------------------------------------------------------------------------------------------------------------
struct FCogSampleTargetAcquisitionResult
{
public:
AActor* Target = nullptr;
float Score = FLT_MAX;
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS()
class UCogSampleTargetAcquisition : public UDataAsset
{
GENERATED_BODY()
public:
//--------------------------------------------------------------------------------------------------------------
// General
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
TArray<TEnumAsByte<EObjectTypeQuery>> BlockerTypes;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
float BreakLineOfSightDelay = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General", meta = (Bitmask, BitmaskEnum = "/Script/CogSample.ECogSampleAllegianceFilter"))
int32 Allegiance = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
bool AcceptDead = false;
//--------------------------------------------------------------------------------------------------------------
// Detection
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection")
ECogSampleTargetAcquisitionLocationReferential DetectionLocation = ECogSampleTargetAcquisitionLocationReferential::Camera;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Detection")
ECogSampleTargetAcquisitionRotationReferential DetectionRotation = ECogSampleTargetAcquisitionRotationReferential::Camera;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Detection")
float DetectionLength = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Detection")
float DetectionRadius = 600.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Detection")
bool UseAsyncDetection = true;
//--------------------------------------------------------------------------------------------------------------
// Screen Limit
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (ToolTip = "Limit based on the screen distance. The screen distance is computed between the crosshair and the candidate screen position"))
bool bUseScreenLimit = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
bool bPrioritizeInsideHitZones = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
bool ScreenTestUseAspectRatio = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
ECogSampleTargetAcquisitionCrosshairReferential CrosshairReferential = ECogSampleTargetAcquisitionCrosshairReferential::Centered;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
ECogSampleTargetAcquisitionScreenLimitType ScreenLimitType = ECogSampleTargetAcquisitionScreenLimitType::Rectangle;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
float ScreenMaxX = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
float ScreenMaxY = 1.0f;
//--------------------------------------------------------------------------------------------------------------
// Yaw Limit
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Yaw", meta = (ToolTip = "Limit based on the yaw angle. The yaw angle is computed between the camera forward vector and the direction between the player character and the candidate"))
bool bUseYawLimit = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Yaw", meta = (EditCondition = "bUseYawLimit", EditConditionHides))
float YawMax = 90.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Limit|Yaw")
ECogSampleTargetAcquisitionRotationReferential YawReferential = ECogSampleTargetAcquisitionRotationReferential::Camera;
//--------------------------------------------------------------------------------------------------------------
// World Distance
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|World Distance", meta = (ToolTip = "The world distance is the distance between the character position and the candidate position"))
bool bUseWorldDistanceScore = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|World Distance", meta = (EditCondition = "bUseWorldDistanceScore", EditConditionHides))
float WorldDistanceMax = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|World Distance", meta = (EditCondition = "bUseWorldDistanceScore", EditConditionHides))
UCurveFloat* WorldDistanceScoreCurve = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|World Distance", meta = (EditCondition = "bUseWorldDistanceScore", EditConditionHides))
float WorldDistanceScoreMultiplier = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|World Distance", meta = (EditCondition = "bUseWorldDistanceScore", EditConditionHides))
bool WorldDistanceIgnoreZ = false;
//--------------------------------------------------------------------------------------------------------------
// Screen Distance Score
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Screen Distance", meta = (ToolTip = "The screen distance is the distance between the crosshair and the candidate screen position"))
bool bUseScreenDistanceScore = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Screen Distance", meta = (EditCondition = "bUseScreenDistanceScore", EditConditionHides))
float ScreenDistanceScoreMultiplier = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Screen Distance", meta = (EditCondition = "bUseScreenDistanceScore", EditConditionHides))
UCurveFloat* ScreenDistanceScoreCurve = nullptr;
//--------------------------------------------------------------------------------------------------------------
// Yaw Scoring
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Yaw", meta = (ToolTip = "The yaw angle is computed between the camera forward vector and the direction between the player character and the candidate"))
bool bUseYawScore = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Yaw", meta = (EditCondition = "bUseYawScore", EditConditionHides))
float YawScoreMultiplier = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Yaw", meta = (EditCondition = "bUseYawScore", EditConditionHides))
UCurveFloat* YawScoreCurve = nullptr;
//--------------------------------------------------------------------------------------------------------------
// Search Direction
//--------------------------------------------------------------------------------------------------------------
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (ToolTip = "The search direction is used when the player has already a locked target and request a target switch with a direction performed by the stick or the mouse"))
bool bUseSearchDirectionScore = false;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (EditCondition = "bUseSearchDirectionScore", EditConditionHides))
float SearchDirectionMaxAngle = 60.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (EditCondition = "bUseSearchDirectionScore", EditConditionHides))
UCurveFloat* ScreenSearchDirectionAngleScoreCurve = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (EditCondition = "bUseSearchDirectionScore", EditConditionHides))
float ScreenSearchDirectionAngleScoreMultiplier = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (EditCondition = "bUseSearchDirectionScore", EditConditionHides))
UCurveFloat* ScreenSearchDirectionDistanceScoreCurve = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Scoring|Search Direction", meta = (EditCondition = "bUseSearchDirectionScore", EditConditionHides))
float SearchDirectionDistanceScoreMultiplier = 1.0f;
//--------------------------------------------------------------------------------------------------------------
virtual void FindBestTargets(
const APlayerController* Controller,
const int32 TargetCount,
const TArray<AActor*>& TargetsToIgnore,
const AActor* CurrentLockedTarget,
const bool bForceSynchronousDetection,
const FVector2D ScreenSearchDirection,
const bool bIsDebugPersistent,
TArray<FCogSampleTargetAcquisitionResult>& Results) const;
virtual bool HasLineOfSightToTargetBrokenForTooLong(
const AActor* Source,
const AActor* Target,
const float DeltaTime,
float& Timer) const;
virtual bool CheckIfTargetValid(
const APlayerController* Controller,
const AActor* Source,
const AActor* Target) const;
//--------------------------------------------------------------------------------------------------------------
// Utility
//--------------------------------------------------------------------------------------------------------------
void FindBestTargetInCandidates(
const APlayerController* Controller,
const TArray<AActor*>& TargetsToIgnore,
const TArray<AActor*>& Candidates,
const FVector2D ScreenSearchDirection,
const FVector2D SearchDirectionViewportOrigin,
const bool bIsDebugPersistent,
FCogSampleTargetAcquisitionResult& Result) const;
void FindBestTarget(
const APlayerController* Controller,
const TArray<AActor*>& TargetsToIgnore,
const AActor* CurrentLockedTarget,
const bool bForceSynchronousDetection,
const FVector2D ScreenSearchDirection,
const bool bIsDebugPersistent,
FCogSampleTargetAcquisitionResult& Result) const;
bool HasLineOfSightToTarget(
const AActor* Source,
const AActor* Target,
const FCollisionObjectQueryParams& BlockersParams) const;
bool EvaluateCandidate(
AActor* CandidateTarget,
const FCogSampleTargetCandidateEvaluationParameters& EvaluationParameters,
FCogSampleTargetCandidateEvaluationResult& EvaluationResult) const;
bool CheckCandidateWithinScreenDistance(
const APlayerController* Controller,
const FIntRect& viewRect,
const FVector& candidateLocation,
const FVector2D& candidateScreenLocation,
const float candidateScreenDistance,
const bool bIsDebugPersistent) const;
bool ComputeCandidateScreenLocation(
const AActor* CandidateTarget,
const FCogSampleTargetCandidateEvaluationParameters& EvalParams,
const FVector& CandidateTargetLocation,
FVector2D& CandidateScreenLocation,
FVector2D& CandidateClosestScreenLocation,
float& CandidateClosestScreenDistance) const;
bool GetViewInfo(
const APlayerController* Controller,
FMatrix& viewProjectionMatrix,
FIntRect& viewRect) const;
static FVector GetReferentialLocation(const ACogSampleCharacter* Character, ECogSampleTargetAcquisitionLocationReferential Referential);
static FRotator GetReferentialRotation(const ACogSampleCharacter* Character, ECogSampleTargetAcquisitionRotationReferential Referential);
};
@@ -0,0 +1,24 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleTargetableInterface.generated.h"
class UCapsuleComponent;
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogSampleTargetableInterface : public UInterface
{
GENERATED_BODY()
};
class ICogSampleTargetableInterface
{
GENERATED_BODY()
public:
virtual FVector GetTargetLocation() const { return FVector::ZeroVector; }
virtual void GetTargetCapsules(TArray<const UCapsuleComponent*>& Capsules) const { }
};
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "CoreMinimal.h"
#include "CogSampleTeamInterface.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
UINTERFACE(MinimalAPI, Blueprintable)
class UCogSampleTeamInterface : public UInterface
{
GENERATED_BODY()
};
class ICogSampleTeamInterface
{
GENERATED_BODY()
public:
virtual int32 GetTeam() const { return 0; }
};