mirror of
https://github.com/Ed94/Cog.git
synced 2026-06-22 20:15:00 -07:00
starting to add the hud in the sample
This commit is contained in:
@@ -6,12 +6,14 @@
|
||||
#define USE_COG (ENABLE_DRAW_DEBUG && !NO_LOGGING)
|
||||
#endif
|
||||
|
||||
#if !USE_COG
|
||||
#if USE_COG
|
||||
|
||||
#define COG(expr) (0)
|
||||
#define IF_COG(expr) { expr; }
|
||||
#define COG_LOG_CATEGORY FLogCategoryBase
|
||||
|
||||
#else //!ENABLE_COG
|
||||
#else //USE_COG
|
||||
|
||||
#define COG(expr) { expr; }
|
||||
#define IF_COG(expr) (0)
|
||||
#define COG_LOG_CATEGORY FNoLoggingCategory
|
||||
|
||||
#endif //!ENABLE_COG
|
||||
#endif //USE_COG
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "CogSampleFunctionLibrary_Team.h"
|
||||
#include "CogSampleGameplayAbility.h"
|
||||
#include "CogSampleLogCategories.h"
|
||||
#include "CogSamplePlayerController.h"
|
||||
#include "CogSampleRootMotionParams.h"
|
||||
#include "CogSampleTagLibrary.h"
|
||||
#include "Components/CapsuleComponent.h"
|
||||
@@ -93,6 +94,8 @@ void ACogSampleCharacter::BeginPlay()
|
||||
Subsystem->AddMappingContext(DefaultMappingContext, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TryFinishInitialize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -132,7 +135,7 @@ ECogInterfacesAllegiance ACogSampleCharacter::GetAllegianceWithOtherActor(const
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::InitializeAbilitySystem()
|
||||
{
|
||||
if (bIsInitialized)
|
||||
if (bIsAbilitySystemInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -205,7 +208,32 @@ void ACogSampleCharacter::InitializeAbilitySystem()
|
||||
GameplayEffectAddedHandle = AbilitySystem->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject(this, &ACogSampleCharacter::OnGameplayEffectAdded);
|
||||
GameplayEffectRemovedHandle = AbilitySystem->OnAnyGameplayEffectRemovedDelegate().AddUObject(this, &ACogSampleCharacter::OnGameplayEffectRemoved);
|
||||
|
||||
bIsAbilitySystemInitialized = true;
|
||||
|
||||
TryFinishInitialize();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::TryFinishInitialize()
|
||||
{
|
||||
if (bIsInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bIsAbilitySystemInitialized == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasActorBegunPlay() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bIsInitialized = true;
|
||||
|
||||
OnInitialized.Broadcast(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -252,9 +280,6 @@ void ACogSampleCharacter::SetupPlayerInputComponent(class UInputComponent* Playe
|
||||
{
|
||||
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
|
||||
|
||||
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
|
||||
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
|
||||
|
||||
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::Move);
|
||||
EnhancedInputComponent->BindAction(MoveZAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::MoveZ);
|
||||
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ACogSampleCharacter::Look);
|
||||
@@ -341,21 +366,37 @@ void ACogSampleCharacter::ActivateItem(const FInputActionValue& Value, int32 Ind
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::Move(const FInputActionValue& Value)
|
||||
{
|
||||
const FVector2D MovementVector = Value.Get<FVector2D>();
|
||||
FVector2D MoveInput2D = Value.Get<FVector2D>();
|
||||
|
||||
MoveInput.X = MoveInput2D.X;
|
||||
MoveInput.Y = MoveInput2D.Y;
|
||||
|
||||
MoveInputInWorldSpace = MoveInput;
|
||||
|
||||
if (Controller != nullptr)
|
||||
{
|
||||
const FRotator Rotation = Controller->GetControlRotation();
|
||||
const FRotator YawRotation(0, Rotation.Yaw, 0);
|
||||
|
||||
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
|
||||
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
|
||||
|
||||
AddMovementInput(ForwardDirection, MovementVector.Y);
|
||||
AddMovementInput(RightDirection, MovementVector.X);
|
||||
MoveInputInWorldSpace = TransformInputInWorldSpace(MoveInput);
|
||||
AddMovementInput(MoveInputInWorldSpace);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FVector ACogSampleCharacter::TransformInputInWorldSpace(const FVector& Input) const
|
||||
{
|
||||
if (Controller == nullptr)
|
||||
{
|
||||
return Input;
|
||||
}
|
||||
|
||||
FRotator ControlRotation = Controller->GetControlRotation();
|
||||
ControlRotation.Pitch = 0.0f;
|
||||
ControlRotation.Roll = 0.0f;
|
||||
|
||||
FVector WorldInput = ControlRotation.RotateVector(FVector(Input.Y, Input.X, 0.0f));
|
||||
|
||||
return WorldInput;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::MoveZ(const FInputActionValue& Value)
|
||||
{
|
||||
@@ -380,18 +421,27 @@ void ACogSampleCharacter::Look(const FInputActionValue& Value)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::OnDamageReceived(float MitigatedDamage, float UnmitigatedDamage, AActor* DamageDealer, const FGameplayEffectSpec& EffectSpec)
|
||||
void ACogSampleCharacter::HandleDamageReceived(const FCogSampleDamageEventParams& Params)
|
||||
{
|
||||
OnDamageReceived.Broadcast(Params);
|
||||
|
||||
#if USE_COG
|
||||
FCogDebugMetric::AddMetric(this, "Damage Received", MitigatedDamage, UnmitigatedDamage, false);
|
||||
FCogDebugMetric::AddMetric(this, "Damage Received", Params.MitigatedDamage, Params.UnmitigatedDamage, false);
|
||||
#endif //USE_COG
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSampleCharacter::OnDamageDealt(float MitigatedDamage, float UnmitigatedDamage, AActor* DamageReceiver, const FGameplayEffectSpec& EffectSpec)
|
||||
void ACogSampleCharacter::HandleDamageDealt(const FCogSampleDamageEventParams& Params)
|
||||
{
|
||||
OnDamageDealt.Broadcast(Params);
|
||||
|
||||
if (ACogSamplePlayerController* PlayerController = Cast<ACogSamplePlayerController>(GetController()))
|
||||
{
|
||||
PlayerController->OnPawnDealtDamage.Broadcast(Params);
|
||||
}
|
||||
|
||||
#if USE_COG
|
||||
FCogDebugMetric::AddMetric(this, "Damage Dealt", MitigatedDamage, UnmitigatedDamage, false);
|
||||
FCogDebugMetric::AddMetric(this, "Damage Dealt", Params.MitigatedDamage, Params.UnmitigatedDamage, false);
|
||||
#endif //USE_COG
|
||||
}
|
||||
|
||||
@@ -463,27 +513,27 @@ void ACogSampleCharacter::OnGhostTagNewOrRemoved(const FGameplayTag InTag, int32
|
||||
check(InTag == Tag_Status_Ghost);
|
||||
|
||||
bool bHasGhostTags = NewCount > 0;
|
||||
if (bIsGhost == bHasGhostTags)
|
||||
if (bIsInGhostMode == bHasGhostTags)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bIsGhost = bHasGhostTags;
|
||||
bIsInGhostMode = bHasGhostTags;
|
||||
|
||||
SetActorEnableCollision(bIsGhost == false);
|
||||
CameraBoom->bDoCollisionTest = bIsGhost == false;
|
||||
SetActorEnableCollision(bIsInGhostMode == false);
|
||||
CameraBoom->bDoCollisionTest = bIsInGhostMode == false;
|
||||
|
||||
if (UCogSampleCharacterMovementComponent* MovementComponent = Cast<UCogSampleCharacterMovementComponent>(GetMovementComponent()))
|
||||
{
|
||||
MovementComponent->bCheatFlying = bIsGhost;
|
||||
MovementComponent->SetMovementMode(bIsGhost ? MOVE_Flying : MOVE_Falling);
|
||||
MovementComponent->bCheatFlying = bIsInGhostMode;
|
||||
MovementComponent->SetMovementMode(bIsInGhostMode ? MOVE_Flying : MOVE_Falling);
|
||||
}
|
||||
|
||||
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
|
||||
{
|
||||
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
|
||||
{
|
||||
if (bIsGhost)
|
||||
if (bIsInGhostMode)
|
||||
{
|
||||
Subsystem->AddMappingContext(GhostMappingContext, 0);
|
||||
}
|
||||
@@ -619,4 +669,5 @@ FVector ACogSampleCharacter::GetTargetLocation() const
|
||||
void ACogSampleCharacter::GetTargetCapsules(TArray<const UCapsuleComponent*>& Capsules) const
|
||||
{
|
||||
Capsules.Add(GetCapsuleComponent());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "CogDefines.h"
|
||||
#include "CogInterfaceAllegianceActor.h"
|
||||
#include "CogInterfaceDebugFilteredActor.h"
|
||||
#include "CogSampleDamageEvent.h"
|
||||
#include "CogSampleTargetableInterface.h"
|
||||
#include "CogSampleTeamInterface.h"
|
||||
#include "GameFramework/Character.h"
|
||||
@@ -57,6 +58,9 @@ public:
|
||||
bool ActivateWhenGiven = false;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleCharacterEventDelegate, ACogSampleCharacter*, Character);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(config=Game)
|
||||
class ACogSampleCharacter : public ACharacter
|
||||
@@ -74,9 +78,10 @@ public:
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ACharacter overrides
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
virtual void BeginPlay();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason);
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
virtual void MarkComponentsAsPendingKill() override;
|
||||
|
||||
@@ -84,35 +89,42 @@ public:
|
||||
|
||||
virtual void PossessedBy(AController* NewController) override;
|
||||
|
||||
void OnAcknowledgePossession(APlayerController* InController);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// IAbilitySystemInterface overrides
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
UAbilitySystemComponent* GetAbilitySystemComponent() const override;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ICogInterfacesAllegianceActor overrides
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
|
||||
void OnDamageReceived(float DamageAmount, float UnmitigatedDamageAmount, AActor* DamageDealer, const FGameplayEffectSpec& EffectSpec);
|
||||
|
||||
void OnDamageDealt(float DamageAmount, float UnmitigatedDamageAmount, AActor* DamageReceiver, const FGameplayEffectSpec& EffectSpec);
|
||||
|
||||
void OnKilled(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
|
||||
|
||||
void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
|
||||
// Team
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
virtual int32 GetTeam() const override { return Team; }
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetTeamID(int32 Value);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true"))
|
||||
int32 Team = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Camera
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
@@ -120,17 +132,21 @@ public:
|
||||
|
||||
UCameraComponent* GetFollowCamera() const { return FollowCamera; }
|
||||
|
||||
/** Camera boom positioning the camera behind the character */
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
|
||||
USpringArmComponent* CameraBoom;
|
||||
|
||||
/** Follow camera */
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
|
||||
UCameraComponent* FollowCamera;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Input
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
FVector TransformInputInWorldSpace(const FVector& Input) const;
|
||||
|
||||
FVector GetMoveInput() const { return MoveInput; }
|
||||
|
||||
FVector GetMoveInputInWorldSpace() const { return MoveInputInWorldSpace; }
|
||||
|
||||
/** MappingContext */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
|
||||
UInputMappingContext* DefaultMappingContext;
|
||||
@@ -139,10 +155,6 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
|
||||
UInputMappingContext* GhostMappingContext;
|
||||
|
||||
/** Jump Input Action */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
|
||||
UInputAction* JumpAction;
|
||||
|
||||
/** Move Input Action */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
|
||||
UInputAction* MoveAction;
|
||||
@@ -161,6 +173,17 @@ public:
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Ability
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
UFUNCTION(BlueprintPure)
|
||||
bool IsInitialized() const { return bIsInitialized; }
|
||||
|
||||
void HandleDamageReceived(const FCogSampleDamageEventParams& Params);
|
||||
|
||||
void HandleDamageDealt(const FCogSampleDamageEventParams& Params);
|
||||
|
||||
void OnKilled(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
|
||||
|
||||
void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = Ability, meta = (AllowPrivateAccess = "true"))
|
||||
UAbilitySystemComponent* AbilitySystem = nullptr;
|
||||
|
||||
@@ -176,19 +199,15 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Ability)
|
||||
TArray<TSubclassOf<UGameplayEffect>> Effects;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Team
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
virtual int32 GetTeam() const override { return Team; }
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCogSampleCharacterEventDelegate OnInitialized;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetTeamID(int32 Value);
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCogSampleDamageEventDelegate OnDamageDealt;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCogSampleDamageEventDelegate OnDamageReceived;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true"))
|
||||
int32 Team = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Root Motion
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
@@ -200,6 +219,7 @@ private:
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Inputs
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void Move(const FInputActionValue& Value);
|
||||
|
||||
void MoveZ(const FInputActionValue& Value);
|
||||
@@ -212,9 +232,16 @@ private:
|
||||
|
||||
void ActivateItem(const FInputActionValue& Value, int32 Index);
|
||||
|
||||
FVector MoveInput;
|
||||
|
||||
FVector MoveInputInWorldSpace;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Ability system
|
||||
// Ability
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void TryFinishInitialize();
|
||||
|
||||
void InitializeAbilitySystem();
|
||||
|
||||
void ShutdownAbilitySystem();
|
||||
@@ -232,15 +259,6 @@ private:
|
||||
UFUNCTION()
|
||||
void OnRep_ActiveAbilityHandles();
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Root Motion
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
UFUNCTION(Reliable, Client)
|
||||
void Client_ApplyRootMotion(const FCogSampleRootMotionParams& Params);
|
||||
|
||||
uint16 ApplyRootMotionShared(const FCogSampleRootMotionParams& Params);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
UPROPERTY(ReplicatedUsing=OnRep_ActiveAbilityHandles, Transient)
|
||||
TArray<FGameplayAbilitySpecHandle> ActiveAbilityHandles;
|
||||
|
||||
@@ -252,9 +270,19 @@ private:
|
||||
|
||||
FDelegateHandle ScaleAttributeDelegateHandle;
|
||||
|
||||
bool bIsGhost = false;
|
||||
bool bIsAbilitySystemInitialized = false;
|
||||
|
||||
bool bIsInitialized = false;
|
||||
|
||||
bool bIsInGhostMode = false;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Root Motion
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
UFUNCTION(Reliable, Client)
|
||||
void Client_ApplyRootMotion(const FCogSampleRootMotionParams& Params);
|
||||
|
||||
uint16 ApplyRootMotionShared(const FCogSampleRootMotionParams& Params);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogSampleDamageEvent.generated.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
USTRUCT(BlueprintType)
|
||||
struct FCogSampleDamageEventParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float MitigatedDamage = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
float UnmitigatedDamage = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
AActor* DamageDealer = nullptr;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
AActor* DamageReceiver = nullptr;
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCogSampleDamageEventDelegate, const FCogSampleDamageEventParams&, Params);
|
||||
@@ -59,39 +59,45 @@ void UCogSampleExecCalculation_Damage::Execute_Implementation(const FGameplayEff
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
// Get flat Damage
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
float IncomingDamage = 0.0f;
|
||||
ExecutionParams.AttemptCalculateTransientAggregatorMagnitude(Tag_Effect_Data_Damage, EvaluationParameters, IncomingDamage);
|
||||
float UnmitigatedDamage = 0.0f;
|
||||
ExecutionParams.AttemptCalculateTransientAggregatorMagnitude(Tag_Effect_Data_Damage, EvaluationParameters, UnmitigatedDamage);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
// Apply resistances
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
float ReceivedDamage = 0.0f;
|
||||
float MitigatedDamage = 0.0f;
|
||||
if (TargetAbilitySystem->HasMatchingGameplayTag(Tag_Status_Immune_Damage) == false)
|
||||
{
|
||||
float Resistances = 0.0f;
|
||||
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().DamageResistanceDef, EvaluationParameters, Resistances);
|
||||
Resistances = FMath::Min(Resistances, 1.0f);
|
||||
ReceivedDamage = IncomingDamage * (1.0f - Resistances);
|
||||
MitigatedDamage = UnmitigatedDamage * (1.0f - Resistances);
|
||||
}
|
||||
|
||||
if (SpecAssetTags.HasTag(Tag_Effect_Type_Damage_Kill))
|
||||
{
|
||||
IncomingDamage = TargetAbilitySystem->GetNumericAttribute(UCogSampleAttributeSet_Health::GetMaxHealthAttribute());
|
||||
ReceivedDamage = IncomingDamage;
|
||||
UnmitigatedDamage = TargetAbilitySystem->GetNumericAttribute(UCogSampleAttributeSet_Health::GetMaxHealthAttribute());
|
||||
MitigatedDamage = UnmitigatedDamage;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
// Apply Damage
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
if (ReceivedDamage > 0.0f)
|
||||
if (MitigatedDamage > 0.0f)
|
||||
{
|
||||
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UCogSampleAttributeSet_Health::GetHealthAttribute(), EGameplayModOp::Additive, -ReceivedDamage));
|
||||
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(UCogSampleAttributeSet_Health::GetHealthAttribute(), EGameplayModOp::Additive, -MitigatedDamage));
|
||||
|
||||
TargetCharacter->OnDamageReceived(ReceivedDamage, IncomingDamage, SourceCharacter, EffectSpec);
|
||||
FCogSampleDamageEventParams Params;
|
||||
Params.DamageDealer = SourceCharacter;
|
||||
Params.DamageReceiver = TargetCharacter;
|
||||
Params.MitigatedDamage = MitigatedDamage;
|
||||
Params.UnmitigatedDamage = UnmitigatedDamage;
|
||||
|
||||
TargetCharacter->HandleDamageReceived(Params);
|
||||
|
||||
if (SourceCharacter != nullptr)
|
||||
{
|
||||
SourceCharacter->OnDamageDealt(ReceivedDamage, IncomingDamage, TargetCharacter, EffectSpec);
|
||||
SourceCharacter->HandleDamageDealt(Params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,16 @@
|
||||
#include "GameFramework/Character.h"
|
||||
#include "GameplayCueNotifyTypes.h"
|
||||
#include "GameplayEffectTypes.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
#include "Particles/ParticleSystemComponent.h"
|
||||
#include "ScalableFloat.h"
|
||||
|
||||
#if USE_COG
|
||||
#include "CogDebugDraw.h"
|
||||
#include "CogDebugLog.h"
|
||||
#endif //USE_COG
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleFunctionLibrary_Gameplay::AdjustAttributeForMaxChange(UAbilitySystemComponent* AbilityComponent, FGameplayAttributeData& AffectedAttribute, float OldValue, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty)
|
||||
{
|
||||
@@ -250,4 +256,62 @@ FVector2D UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const FVector2D&
|
||||
float UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const float Value, const FVector2D& DisplaySize)
|
||||
{
|
||||
return Value * 2.0f / FMath::Min(DisplaySize.X, DisplaySize.Y);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogSampleFunctionLibrary_Gameplay::HasLineOfSight(
|
||||
const UWorld* World,
|
||||
const FVector& Start,
|
||||
const FVector& End,
|
||||
const FCollisionObjectQueryParams& BlockersParams,
|
||||
const FCollisionQueryParams& QueryParams,
|
||||
const COG_LOG_CATEGORY& LogCategory)
|
||||
{
|
||||
IF_COG(FCogDebugDraw::Sphere(LogCategory, World, Start, 5.0f, FColor::Black, false, 0));
|
||||
IF_COG(FCogDebugDraw::Sphere(LogCategory, World, End, 10.0f, FColor::Black, false, 0));
|
||||
|
||||
FHitResult BlockerRaycastHit;
|
||||
if (World->LineTraceSingleByObjectType(BlockerRaycastHit, Start, End, BlockersParams, QueryParams))
|
||||
{
|
||||
IF_COG(FCogDebugDraw::Segment(LogCategory, World, Start, End, FColor(0, 0, 0, 10), false, 0));
|
||||
IF_COG(FCogDebugDraw::Sphere(LogCategory, World, BlockerRaycastHit.ImpactPoint, 5.0f, FColor::Red, false, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
IF_COG(FCogDebugDraw::Segment(LogCategory, World, Start, End, FColor(255, 255, 255, 10), false, 0));
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// We didn't touch a blocker, we have line of sight.
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogSampleFunctionLibrary_Gameplay::IsActorAbilitySystemMatchingTags(const UAbilitySystemComponent* AbilitySystem, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags)
|
||||
{
|
||||
if (AbilitySystem == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool bHasRequiredTags = AbilitySystem->HasAllMatchingGameplayTags(RequiredTags);
|
||||
const bool bHasIgnoredTags = AbilitySystem->HasAnyMatchingGameplayTags(IgnoredTags);
|
||||
|
||||
if (bHasRequiredTags && bHasIgnoredTags == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogSampleFunctionLibrary_Gameplay::IsActorMatchingTags(const AActor* Actor, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags)
|
||||
{
|
||||
const UAbilitySystemComponent* AbilitySystem = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor);
|
||||
bool Result = IsActorAbilitySystemMatchingTags(AbilitySystem, RequiredTags, IgnoredTags);
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogDefines.h"
|
||||
#include "CogSampleFunctionLibrary_Gameplay.generated.h"
|
||||
|
||||
class UAbilitySystemComponent;
|
||||
@@ -10,6 +11,7 @@ struct FGameplayAttribute;
|
||||
struct FGameplayAttributeData;
|
||||
struct FGameplayCueNotify_SpawnResult;
|
||||
struct FGameplayCueParameters;
|
||||
struct FGameplayTagContainer;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
|
||||
@@ -73,4 +75,11 @@ public:
|
||||
static FVector2D ScreenToViewport(const FVector2D& value, const FVector2D& displaySize);
|
||||
|
||||
static float ScreenToViewport(const float value, const FVector2D& displaySize);
|
||||
|
||||
static bool HasLineOfSight(const UWorld* World, const FVector& Start, const FVector& End, const FCollisionObjectQueryParams& BlockersParams, const FCollisionQueryParams& QueryParams, const COG_LOG_CATEGORY& LogCategory);
|
||||
|
||||
static bool IsActorAbilitySystemMatchingTags(const UAbilitySystemComponent* AbilitySystem, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags);
|
||||
|
||||
static bool IsActorMatchingTags(const AActor* Actor, const FGameplayTagContainer& RequiredTags, const FGameplayTagContainer& IgnoredTags);
|
||||
|
||||
};
|
||||
|
||||
@@ -51,6 +51,32 @@ void ACogSamplePlayerController::Tick(float DeltaSeconds)
|
||||
TArray<AActor*> TagretToIgnore;
|
||||
FCogSampleTargetAcquisitionResult Result;
|
||||
TargetAcquisition->FindBestTarget(this, TagretToIgnore, nullptr, true, FVector2D::ZeroVector, false, Result);
|
||||
Target = Result.Target;
|
||||
SetTarget(Result.Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSamplePlayerController::SetTarget(AActor* Value)
|
||||
{
|
||||
if (Value == Target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AActor* OldTarget = Target.Get();
|
||||
|
||||
Target = Value;
|
||||
|
||||
if (GetLocalRole() == ROLE_AutonomousProxy)
|
||||
{
|
||||
Server_SetTarget(Value);
|
||||
}
|
||||
|
||||
OnTargetChanged.Broadcast(this, Target.Get(), OldTarget);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void ACogSamplePlayerController::Server_SetTarget_Implementation(AActor* Value)
|
||||
{
|
||||
Target = Value;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AbilitySystemInterface.h"
|
||||
#include "CogSampleDamageEvent.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "CogSamplePlayerController.generated.h"
|
||||
|
||||
class UCogSampleTargetAcquisition;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCogSampleTargetChangedEventDelegate, ACogSamplePlayerController*, Controller, AActor*, NewTarget, AActor*, OldTarget);
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCLASS(config=Game)
|
||||
class ACogSamplePlayerController : public APlayerController
|
||||
{
|
||||
@@ -22,12 +27,25 @@ public:
|
||||
|
||||
virtual void Tick(float DeltaSeconds);
|
||||
|
||||
void SetTarget(AActor* Value);
|
||||
|
||||
AActor* GetTarget() const { return Target.Get(); }
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCogSampleTargetChangedEventDelegate OnTargetChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCogSampleDamageEventDelegate OnPawnDealtDamage;
|
||||
|
||||
private:
|
||||
|
||||
UFUNCTION(Reliable, Server)
|
||||
void Server_SetTarget(AActor* Value);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true"))
|
||||
UCogSampleTargetAcquisition* TargetAcquisition = nullptr;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = TargetAcquisition, meta = (AllowPrivateAccess = "true"))
|
||||
TSoftObjectPtr<AActor> Target = nullptr;
|
||||
TWeakObjectPtr<AActor> Target = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#endif //USE_COG
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
// UCogSampleTargetAcquisition_Generic
|
||||
// FCogSampleTargetTargetAcquisitionParams
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
struct FCogSampleTargetCandidateEvaluationParameters
|
||||
struct FCogSampleTargetTargetAcquisitionParams
|
||||
{
|
||||
const AActor* Source;
|
||||
FVector SourceLocation;
|
||||
@@ -35,18 +35,11 @@ struct FCogSampleTargetCandidateEvaluationParameters
|
||||
FVector2D SearchDirectionScreenOrigin = FVector2D::ZeroVector;
|
||||
FVector2D SearchDirectionNormalized = FVector2D::ZeroVector;
|
||||
bool IsDebugPersistent = false;
|
||||
bool IsCrosshairInsideAnyCandidate = false;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
struct FCogSampleTargetCandidateEvaluationResult
|
||||
{
|
||||
AActor* BestTarget;
|
||||
float MinScore;
|
||||
bool bFoundLocationInsideShape;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
// UCogSampleTargetAcquisition_Generic
|
||||
// UCogSampleTargetAcquisition
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleTargetAcquisition::FindBestTargets(
|
||||
const APlayerController* Controller,
|
||||
@@ -60,7 +53,7 @@ void UCogSampleTargetAcquisition::FindBestTargets(
|
||||
{
|
||||
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::FindBestTargets);
|
||||
|
||||
COG(FCogDebugDraw::String2D(LogCogTargetAcquisition, Controller, GetName(), FVector2D(20, 20), FColor::White, bIsDebugPersistent));
|
||||
IF_COG(FCogDebugDraw::String2D(LogCogTargetAcquisition, Controller, GetName(), FVector2D(20, 20), FColor::White, bIsDebugPersistent));
|
||||
|
||||
TArray<AActor*> TempTargetsToIgnore(TargetsToIgnore);
|
||||
|
||||
@@ -136,7 +129,7 @@ void UCogSampleTargetAcquisition::FindBestTarget(
|
||||
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));
|
||||
IF_COG(FCogDebugDraw::Segment2D(LogCogTargetAcquisition, Controller, FVector2D::ZeroVector, FVector2D(SearchDirectionNormalized.X, -SearchDirectionNormalized.Y), FColor(255, 255, 0, 255), bIsDebugPersistent));
|
||||
}
|
||||
#endif //USE_COG
|
||||
|
||||
@@ -155,7 +148,7 @@ void UCogSampleTargetAcquisition::FindBestTarget(
|
||||
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));
|
||||
IF_COG(FCogDebugDraw::Capsule(LogCogTargetAcquisition, Controller, CapsuleCenter, CapsuleHalfHeight, CapsuleRadius, CapsuleRotation, FColor::Yellow, bIsDebugPersistent, 0));
|
||||
|
||||
//-------------------------------------------------
|
||||
// Gather targets asynchronously
|
||||
@@ -220,7 +213,7 @@ void UCogSampleTargetAcquisition::FindBestTarget(
|
||||
{
|
||||
if (CheckIfTargetValid(Controller, Character, Actor) == false)
|
||||
{
|
||||
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, "Filter", UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Actor), FColor::Red, bIsDebugPersistent));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, "Filter", UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Actor), FColor::Red, bIsDebugPersistent));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -255,20 +248,161 @@ bool UCogSampleTargetAcquisition::GetViewInfo(
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FVector2D ScreenSize(ViewRect.Width(), ViewRect.Height());
|
||||
FVector2D ScreenCrosshairPosition = ScreenSize * 0.5f;;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Draw screen limits
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if USE_COG
|
||||
|
||||
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, Controller, ScreenCrosshairPosition, 5.0f, FColor(255, 255, 255, 255), bIsDebugPersistent);
|
||||
|
||||
if (bUseScreenLimit)
|
||||
{
|
||||
if (ScreenLimitType == ECogSampleTargetAcquisitionScreenLimitType::Rectangle)
|
||||
{
|
||||
FCogDebugDraw::Rect2D(
|
||||
LogCogTargetAcquisition,
|
||||
Controller,
|
||||
UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(FVector2D(-ScreenMaxX, -ScreenMaxY), ScreenSize),
|
||||
UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(FVector2D(ScreenMaxX, ScreenMaxY), ScreenSize),
|
||||
FColor(255, 255, 255, 255),
|
||||
bIsDebugPersistent);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCogDebugDraw::Circle2D(
|
||||
LogCogTargetAcquisition,
|
||||
Controller,
|
||||
ScreenCrosshairPosition,
|
||||
UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(ScreenMaxX, ScreenSize),
|
||||
FColor(255, 255, 255, 255),
|
||||
bIsDebugPersistent);
|
||||
}
|
||||
}
|
||||
#endif //USE_COG
|
||||
|
||||
const FRotator YawRotation = GetReferentialRotation(Character, YawReferential);
|
||||
const FVector YawDirection = YawRotation.Vector();
|
||||
|
||||
FCogSampleTargetTargetAcquisitionParams Params;
|
||||
Params.Source = Character;
|
||||
Params.SourceLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Character);
|
||||
Params.Controller = Controller;
|
||||
Params.TargetsToIgnore = TargetsToIgnore;
|
||||
Params.bWorldDistanceIgnoreZ = WorldDistanceIgnoreZ;
|
||||
Params.MaxWorldDistance = WorldDistanceMax;
|
||||
Params.CrosshairPosition = ScreenCrosshairPosition;
|
||||
Params.YawDirection = YawDirection;
|
||||
Params.CameraRight = Character->GetFollowCamera()->GetComponentQuat().GetRightVector();
|
||||
Params.ViewProjectionMatrix = ViewProjectionMatrix;
|
||||
Params.ViewRect = ViewRect;
|
||||
Params.BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes);
|
||||
Params.bUseSearchDirection = ScreenSearchDirection.IsNearlyZero() == false;
|
||||
Params.SearchDirectionScreenOrigin = SearchDirectionScreenOrigin;
|
||||
Params.SearchDirectionNormalized = Params.bUseSearchDirection ? ScreenSearchDirection.GetSafeNormal() : FVector2D::ZeroVector;
|
||||
Params.IsDebugPersistent = bIsDebugPersistent;
|
||||
Params.IsCrosshairInsideAnyCandidate = false;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Evaluate candidates actors
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
float MinScore = FLT_MAX;
|
||||
AActor* BestTarget = nullptr;
|
||||
|
||||
bool bIsCrosshairInsideAnyTarget = false;
|
||||
for (int32 i = 0; i < Candidates.Num(); ++i)
|
||||
{
|
||||
AActor* Candidate = Candidates[i];
|
||||
if (Candidate == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float CandidateScore = 0.0f;
|
||||
bool bIsCrosshairInsideCandidate = false;
|
||||
if (EvaluateCandidate(Candidate, Params, CandidateScore, bIsCrosshairInsideCandidate) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// If the crosshair is inside this candidate, we can discard subsequent candidates
|
||||
// that are not inside but also the best previous candidate since we were not inside it.
|
||||
//-----------------------------------------------------------------------------------------
|
||||
if (bPrioritizeTargetWithCrosshairInsideThem && bIsCrosshairInsideCandidate && bIsCrosshairInsideAnyTarget == false)
|
||||
{
|
||||
BestTarget = nullptr;
|
||||
MinScore = FLT_MAX;
|
||||
}
|
||||
|
||||
Params.IsCrosshairInsideAnyCandidate |= bIsCrosshairInsideCandidate;
|
||||
|
||||
if (CandidateScore > MinScore)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
MinScore = CandidateScore;
|
||||
BestTarget = Candidate;
|
||||
}
|
||||
|
||||
if (BestTarget != nullptr)
|
||||
{
|
||||
Result.Target = BestTarget;
|
||||
Result.Score = MinScore;
|
||||
|
||||
IF_COG(FCogDebugDraw::Point(LogCogTargetAcquisition, Controller, UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Result.Target), 20.0f, FColor::Green, Params.IsDebugPersistent, 100));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
AActor* CandidateTarget,
|
||||
const FCogSampleTargetCandidateEvaluationParameters& EvalParams,
|
||||
FCogSampleTargetCandidateEvaluationResult& EvalResult) const
|
||||
AActor* Candidate,
|
||||
const FCogSampleTargetTargetAcquisitionParams& EvalParams,
|
||||
float& CandidateScore,
|
||||
bool& bIsCrosshairInsideCandidate) const
|
||||
{
|
||||
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::EvaluateCandidate);
|
||||
|
||||
if (EvalParams.TargetsToIgnore.Contains(CandidateTarget))
|
||||
if (EvalParams.TargetsToIgnore.Contains(Candidate))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const FVector CandidateTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(CandidateTarget);
|
||||
const FVector CandidateTargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Candidate);
|
||||
|
||||
FVector CandidateLocationDelta = CandidateTargetLocation - EvalParams.SourceLocation;
|
||||
if (EvalParams.bWorldDistanceIgnoreZ)
|
||||
@@ -285,7 +419,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
if (CandidateWorldDistance > EvalParams.MaxWorldDistance)
|
||||
{
|
||||
COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Dist: %0.2f"), CandidateWorldDistance * 0.01f), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Dist: %0.2f"), CandidateWorldDistance * 0.01f), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -297,7 +431,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
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));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("Yaw: %0.2f"), CandidateYaw), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -309,7 +443,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
FVector2D CandidateClosestScreenLocation;
|
||||
float CandidateClosestScreenDistance;
|
||||
const UCapsuleComponent* CandidateBestHitZone = nullptr;
|
||||
if (!ComputeCandidateScreenLocation(CandidateTarget, EvalParams, CandidateTargetLocation, CandidateScreenLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance))
|
||||
if (!ComputeCandidateScreenLocation(Candidate, EvalParams, CandidateTargetLocation, CandidateScreenLocation, CandidateClosestScreenLocation, CandidateClosestScreenDistance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -328,32 +462,22 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// Raycast to verify this target is not blocked by a collision.
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
if (!HasLineOfSightToTarget(EvalParams.Source, CandidateTarget, EvalParams.BlockersParams))
|
||||
if (HasLineOfSightToTarget(EvalParams.Source, EvalParams.SourceLocation, Candidate, CandidateTargetLocation, EvalParams.BlockersParams) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool bIsInsideCandidate = CandidateClosestScreenDistance < 0.0f;
|
||||
if (!IsSearchDirectionUsed && bPrioritizeInsideHitZones)
|
||||
bIsCrosshairInsideCandidate = CandidateClosestScreenDistance < 0.0f;
|
||||
if (!IsSearchDirectionUsed && bPrioritizeTargetWithCrosshairInsideThem)
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// 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)
|
||||
if (EvalParams.IsCrosshairInsideAnyCandidate && bIsCrosshairInsideCandidate == 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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
@@ -403,7 +527,7 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
|
||||
if (FMath::Abs(TargetAngleWithSearchDirection) > SearchDirectionMaxAngle)
|
||||
{
|
||||
COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("MaxAngle: %0.2f"), TargetAngleWithSearchDirection), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, EvalParams.Controller, FString::Printf(TEXT("MaxAngle: %0.2f"), TargetAngleWithSearchDirection), CandidateTargetLocation, FColor::Red, EvalParams.IsDebugPersistent));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -416,19 +540,15 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// Compute final score by summing all the scores. The best score is the smallest one.
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
const float TargetScore = CandidateWorldDistanceScore + CandidateScreenDistanceScore + CandidateYawScore + SearchDirectionDistanceScore + SearchDirectionAngleScore;
|
||||
CandidateScore = 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;
|
||||
@@ -438,11 +558,9 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
{
|
||||
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));
|
||||
CandidateClosestScreenDistance, CandidateScreenDistanceRatio * 100, CandidateScreenDistanceScore * 100));
|
||||
}
|
||||
|
||||
if (bUseWorldDistanceScore)
|
||||
@@ -470,146 +588,24 @@ bool UCogSampleTargetAcquisition::EvaluateCandidate(
|
||||
SearchDirectionAngleScore * 100));
|
||||
}
|
||||
|
||||
Text.Append(FString::Printf(TEXT("==> %.0f \n"), TargetScore * 100));
|
||||
Text.Append(FString::Printf(TEXT("==> %.0f \n"), CandidateScore * 100));
|
||||
}
|
||||
else
|
||||
{
|
||||
Text = FString::Printf(TEXT("%0.f"), TargetScore * 100);
|
||||
Text = FString::Printf(TEXT("%0.f"), CandidateScore * 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 FCogSampleTargetTargetAcquisitionParams& Params,
|
||||
const FVector& CandidateTargetLocation,
|
||||
FVector2D& CandidateScreenLocation,
|
||||
FVector2D& CandidateClosestScreenLocation,
|
||||
@@ -636,39 +632,34 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation(
|
||||
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;
|
||||
const FVector CapsuleRight = CapsuleLocation - Params.CameraRight * Radius;
|
||||
|
||||
FVector2D CapsuleTop2D;
|
||||
FVector2D CapsuleBot2D;
|
||||
FVector2D CapsuleRight2D;
|
||||
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleTop, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleTop2D) == false)
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleTop, Params.ViewRect, Params.ViewProjectionMatrix, CapsuleTop2D) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleBottom, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleBot2D) == false)
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleBottom, Params.ViewRect, Params.ViewProjectionMatrix, CapsuleBot2D) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleRight, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CapsuleRight2D) == false)
|
||||
if (FSceneView::ProjectWorldToScreen(CapsuleRight, Params.ViewRect, Params.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);
|
||||
UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(CapsuleBot2D, CapsuleTop2D, CapsuleRadius2D, Params.CrosshairPosition, Projection, Time, ScreenCenterToCapsuleDistance);
|
||||
|
||||
if (ScreenCenterToCapsuleDistance < CandidateClosestScreenDistance)
|
||||
{
|
||||
@@ -680,16 +671,16 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation(
|
||||
|
||||
#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);
|
||||
FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D + FVector2D(CapsuleRadius2D, 0), CapsuleTop2D + FVector2D(CapsuleRadius2D, 0), CapsuleColor, Params.IsDebugPersistent);
|
||||
FCogDebugDraw::Segment2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D - FVector2D(CapsuleRadius2D, 0), CapsuleTop2D - FVector2D(CapsuleRadius2D, 0), CapsuleColor, Params.IsDebugPersistent);
|
||||
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleTop2D, CapsuleRadius2D, CapsuleColor, Params.IsDebugPersistent);
|
||||
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CapsuleBot2D, CapsuleRadius2D, CapsuleColor, Params.IsDebugPersistent);
|
||||
#endif //USE_COG
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FSceneView::ProjectWorldToScreen(CandidateTargetLocation, EvalParams.ViewRect, EvalParams.ViewProjectionMatrix, CandidateScreenLocation))
|
||||
if (FSceneView::ProjectWorldToScreen(CandidateTargetLocation, Params.ViewRect, Params.ViewProjectionMatrix, CandidateScreenLocation))
|
||||
{
|
||||
CandidateClosestScreenDistance = CandidateScreenLocation.Length();
|
||||
CandidateClosestScreenLocation = CandidateScreenLocation;
|
||||
@@ -700,7 +691,7 @@ bool UCogSampleTargetAcquisition::ComputeCandidateScreenLocation(
|
||||
#if USE_COG
|
||||
if (bFoundValidCandidate)
|
||||
{
|
||||
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CandidateClosestScreenLocation, 2.0f, FColor(0, 255, 0, 255), EvalParams.IsDebugPersistent);
|
||||
FCogDebugDraw::Circle2D(LogCogTargetAcquisition, CandidateActor, CandidateClosestScreenLocation, 2.0f, FColor(0, 255, 0, 255), Params.IsDebugPersistent);
|
||||
}
|
||||
#endif //USE_COG
|
||||
|
||||
@@ -729,13 +720,13 @@ bool UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance(
|
||||
{
|
||||
if (FMath::Abs(CandidateViewportLocation.X) > ScreenMaxX)
|
||||
{
|
||||
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxX: %0.2f"), CandidateViewportLocation.X), CandidateLocation, FColor::Red, bIsDebugPersistent));
|
||||
IF_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));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("MaxY: %0.2f"), CandidateViewportLocation.Y), CandidateLocation, FColor::Red, bIsDebugPersistent));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -746,7 +737,7 @@ bool UCogSampleTargetAcquisition::CheckCandidateWithinScreenDistance(
|
||||
{
|
||||
if (CandidateViewportDistance > ScreenMaxX)
|
||||
{
|
||||
COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("Max: %0.2f"), CandidateViewportDistance), CandidateLocation, FColor::Red, bIsDebugPersistent));
|
||||
IF_COG(FCogDebugDraw::String(LogCogTargetAcquisition, Controller, FString::Printf(TEXT("Max: %0.2f"), CandidateViewportDistance), CandidateLocation, FColor::Red, bIsDebugPersistent));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -767,25 +758,30 @@ bool UCogSampleTargetAcquisition::CheckIfTargetValid(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (UCogSampleFunctionLibrary_Gameplay::IsActorMatchingTags(Target, RequiredTags, IgnoredTags) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
bool UCogSampleTargetAcquisition::HasLineOfSightToTarget(
|
||||
const AActor* Source,
|
||||
const FVector& SourceLocation,
|
||||
const AActor* Target,
|
||||
const FVector& TargetLocation,
|
||||
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(Source);
|
||||
TargetQueryParams.AddIgnoredActor(Target);
|
||||
|
||||
return true;
|
||||
//return FCogHitDetectionHelper::HasLineOfSight(Source->GetWorld(), Origin, Target.GetTargetLocation(), BlockersParams, TargetQueryParams, LogCogTargetAcquisition);
|
||||
return UCogSampleFunctionLibrary_Gameplay::HasLineOfSight(Source->GetWorld(), SourceLocation, TargetLocation, BlockersParams, TargetQueryParams, LogCogTargetAcquisition);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -797,8 +793,11 @@ bool UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong(
|
||||
{
|
||||
TRACE_CPUPROFILER_EVENT_SCOPE(UCogSampleTargetAcquisition::HasLineOfSightToTargetBrokenForTooLong);
|
||||
|
||||
const FVector& SourceLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Source);
|
||||
const FVector& TargetLocation = UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(Target);
|
||||
|
||||
const FCollisionObjectQueryParams BlockersParams = UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(BlockerTypes);
|
||||
bool HasLineOfSight = HasLineOfSightToTarget(Source, Target, BlockersParams);
|
||||
const bool HasLineOfSight = HasLineOfSightToTarget(Source, SourceLocation, Target, TargetLocation, BlockersParams);
|
||||
if (HasLineOfSight)
|
||||
{
|
||||
Timer = 0.0f;
|
||||
@@ -824,18 +823,18 @@ FVector UCogSampleTargetAcquisition::GetReferentialLocation(const ACogSampleChar
|
||||
|
||||
switch (Referential)
|
||||
{
|
||||
case ECogSampleTargetAcquisitionLocationReferential::Character:
|
||||
{
|
||||
Location = UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(Character);
|
||||
break;
|
||||
}
|
||||
case ECogSampleTargetAcquisitionLocationReferential::Character:
|
||||
{
|
||||
Location = UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(Character);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case ECogSampleTargetAcquisitionLocationReferential::Camera:
|
||||
{
|
||||
Location = Character->GetFollowCamera()->GetComponentLocation();
|
||||
break;
|
||||
}
|
||||
case ECogSampleTargetAcquisitionLocationReferential::Camera:
|
||||
{
|
||||
Location = Character->GetFollowCamera()->GetComponentLocation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Location;
|
||||
@@ -848,38 +847,38 @@ FRotator UCogSampleTargetAcquisition::GetReferentialRotation(const ACogSampleCha
|
||||
|
||||
switch (Referential)
|
||||
{
|
||||
case ECogSampleTargetAcquisitionRotationReferential::Character:
|
||||
{
|
||||
Rotation = Character->GetActorRotation();
|
||||
break;
|
||||
}
|
||||
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::MoveInput:
|
||||
{
|
||||
const FVector WorldInput = Character->GetMoveInputInWorldSpace();
|
||||
if (WorldInput.IsNearlyZero())
|
||||
{
|
||||
Rotation = Character->GetActorRotation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Rotation = WorldInput.GetSafeNormal().Rotation();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ECogSampleTargetAcquisitionRotationReferential::Camera:
|
||||
{
|
||||
Rotation = Character->GetFollowCamera()->GetComponentRotation();
|
||||
break;
|
||||
}
|
||||
case ECogSampleTargetAcquisitionRotationReferential::Camera:
|
||||
{
|
||||
Rotation = Character->GetFollowCamera()->GetComponentRotation();
|
||||
break;
|
||||
}
|
||||
|
||||
case ECogSampleTargetAcquisitionRotationReferential::CameraFlatten:
|
||||
{
|
||||
const FVector CameraForwardFlat = Character->GetFollowCamera()->GetComponentQuat().GetForwardVector().GetSafeNormal2D();
|
||||
Rotation = CameraForwardFlat.Rotation();
|
||||
break;
|
||||
}
|
||||
case ECogSampleTargetAcquisitionRotationReferential::CameraFlatten:
|
||||
{
|
||||
const FVector CameraForwardFlat = Character->GetFollowCamera()->GetComponentQuat().GetForwardVector().GetSafeNormal2D();
|
||||
Rotation = CameraForwardFlat.Rotation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Rotation;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
#include "CogSampleFunctionLibrary_Team.h"
|
||||
#include "Engine/DataAsset.h"
|
||||
#include "Engine/EngineTypes.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "WorldCollision.h"
|
||||
#include "CogSampleTargetAcquisition.generated.h"
|
||||
|
||||
class ACogSampleCharacter;
|
||||
class APlayerController;
|
||||
class UCurveFloat;
|
||||
struct FCogSampleTargetCandidateEvaluationResult;
|
||||
struct FCogSampleTargetCandidateEvaluationParameters;
|
||||
struct FCogSampleTargetTargetAcquisitionParams;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UENUM(BlueprintType)
|
||||
@@ -89,7 +89,10 @@ public:
|
||||
int32 Allegiance = 0;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
|
||||
bool AcceptDead = false;
|
||||
FGameplayTagContainer RequiredTags;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
|
||||
FGameplayTagContainer IgnoredTags;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// Detection
|
||||
@@ -118,7 +121,7 @@ public:
|
||||
bool bUseScreenLimit = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
|
||||
bool bPrioritizeInsideHitZones = true;
|
||||
bool bPrioritizeTargetWithCrosshairInsideThem = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Limit|Screen", meta = (EditCondition = "bUseScreenLimit", EditConditionHides))
|
||||
bool ScreenTestUseAspectRatio = true;
|
||||
@@ -237,10 +240,6 @@ public:
|
||||
const AActor* Source,
|
||||
const AActor* Target) const;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// Utility
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void FindBestTargetInCandidates(
|
||||
const APlayerController* Controller,
|
||||
const TArray<AActor*>& TargetsToIgnore,
|
||||
@@ -261,13 +260,16 @@ public:
|
||||
|
||||
bool HasLineOfSightToTarget(
|
||||
const AActor* Source,
|
||||
const FVector& SourceLocation,
|
||||
const AActor* Target,
|
||||
const FVector& TargetLocation,
|
||||
const FCollisionObjectQueryParams& BlockersParams) const;
|
||||
|
||||
bool EvaluateCandidate(
|
||||
AActor* CandidateTarget,
|
||||
const FCogSampleTargetCandidateEvaluationParameters& EvaluationParameters,
|
||||
FCogSampleTargetCandidateEvaluationResult& EvaluationResult) const;
|
||||
const FCogSampleTargetTargetAcquisitionParams& EvaluationParameters,
|
||||
float& CandidateScore,
|
||||
bool& bIsCrosshairInsideCandidate) const;
|
||||
|
||||
bool CheckCandidateWithinScreenDistance(
|
||||
const APlayerController* Controller,
|
||||
@@ -279,7 +281,7 @@ public:
|
||||
|
||||
bool ComputeCandidateScreenLocation(
|
||||
const AActor* CandidateTarget,
|
||||
const FCogSampleTargetCandidateEvaluationParameters& EvalParams,
|
||||
const FCogSampleTargetTargetAcquisitionParams& EvalParams,
|
||||
const FVector& CandidateTargetLocation,
|
||||
FVector2D& CandidateScreenLocation,
|
||||
FVector2D& CandidateClosestScreenLocation,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "CogSampleTask_WaitAttributeChanged.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
UCogSampleTask_WaitAttributeChanged* UCogSampleTask_WaitAttributeChanged::ListenForAttributeChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAttribute Attribute)
|
||||
{
|
||||
if (!IsValid(AbilitySystemComponent) || !Attribute.IsValid())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UCogSampleTask_WaitAttributeChanged* WaitForAttributeChangedTask = NewObject<UCogSampleTask_WaitAttributeChanged>();
|
||||
WaitForAttributeChangedTask->AbilitySystemComponent = AbilitySystemComponent;
|
||||
WaitForAttributeChangedTask->AttributeToListenFor = Attribute;
|
||||
|
||||
return WaitForAttributeChangedTask;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleTask_WaitAttributeChanged::Activate()
|
||||
{
|
||||
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeToListenFor).AddUObject(this, &UCogSampleTask_WaitAttributeChanged::AttributeChanged);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleTask_WaitAttributeChanged::EndTask()
|
||||
{
|
||||
if (IsValid(AbilitySystemComponent))
|
||||
{
|
||||
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeToListenFor).RemoveAll(this);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
MarkAsGarbage();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogSampleTask_WaitAttributeChanged::AttributeChanged(const FOnAttributeChangeData& Data)
|
||||
{
|
||||
OnAttributeChanged.Broadcast(Data.Attribute, Data.NewValue, Data.OldValue);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
|
||||
#include "CogSampleTask_WaitAttributeChanged.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnAttributeChangedDelegate, FGameplayAttribute, Attribute, float, NewValue, float, OldValue)
|
||||
;
|
||||
/**
|
||||
* Blueprint node to automatically register a listener for all attribute changes in an AbilitySystemComponent.
|
||||
*/
|
||||
UCLASS(BlueprintType, meta = (ExposedAsyncProxy = AsyncTask))
|
||||
class UCogSampleTask_WaitAttributeChanged : public UBlueprintAsyncActionBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnAttributeChangedDelegate OnAttributeChanged;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
|
||||
static UCogSampleTask_WaitAttributeChanged* ListenForAttributeChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayAttribute Attribute);
|
||||
|
||||
virtual void Activate() override;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void EndTask();
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY()
|
||||
UAbilitySystemComponent* AbilitySystemComponent = nullptr;
|
||||
|
||||
FGameplayAttribute AttributeToListenFor;
|
||||
|
||||
void AttributeChanged(const FOnAttributeChangeData& Data);
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user