[박치영] LockOn SYstem 추가

main
PCYPC\pcy35 2023-08-24 22:13:43 +09:00
parent d4283aef0d
commit 00b2ef6ab4
25 changed files with 457 additions and 48 deletions

View File

@ -130,4 +130,6 @@ ManualIPAddress=
[CoreRedirects]
+FunctionRedirects=(OldName="/Script/D1.CollisionComponent.EnableCollision",NewName="/Script/D1.CollisionComponent.ActivateCollision")
+FunctionRedirects=(OldName="/Script/D1.CollisionComponent.DisableCollision",NewName="/Script/D1.CollisionComponent.DeactivateCollision")
+PropertyRedirects=(OldName="/Script/D1.BaseDualWeapon.RightFoot",NewName="/Script/D1.BaseDualWeapon.RightFootCollisionComponent")
+PropertyRedirects=(OldName="/Script/D1.BaseDualWeapon.RightFoot",NewName="/Script/D1.BaseDualWeapon.RightFootCollisionComponent")
+PropertyRedirects=(OldName="/Script/D1.CombatCharacter.ToogleLockOnAction",NewName="/Script/D1.CombatCharacter.ToggleLockOnAction")
+ClassRedirects=(OldName="/Script/D1.UI_LockOnComponent",NewName="/Script/D1.LockOnWidgetComponent")

Binary file not shown.

View File

@ -2,6 +2,8 @@
#include "Animation/CombatAnimInstance.h"
#include "Components/CombatComponent.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/KismetMathLibrary.h"
@ -12,7 +14,14 @@ void UCombatAnimInstance::NativeInitializeAnimation()
Character = Cast<ACharacter>(TryGetPawnOwner());
if (Character)
{
CharacterMovementComponent = Character->GetCharacterMovement();
UCombatComponent* CombatComponent = Character->GetComponentByClass<UCombatComponent>();
ensure(CombatComponent);
if(IsValid(CombatComponent))
CombatComponent->OnCombatToggled.AddUObject(this, &UCombatAnimInstance::UpdateCombatEnabled);
}
}
void UCombatAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
@ -28,6 +37,8 @@ void UCombatAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
FVector2D vel = { Velocity.X, Velocity.Y };
GroundSpeed = vel.Length();
Direction = CalculateDirection(CharacterMovementComponent->Velocity, Character->GetActorRotation());
ShouldMove = (GroundSpeed > 3.f) && (CharacterMovementComponent->GetCurrentAcceleration().Length() != 0);
}

View File

@ -22,7 +22,9 @@ public:
public:
virtual void UpdateCombatType(ECombatType combatType) override;
virtual void UpdateCombatEnabled(bool combatEnabled) override;
public: //Delegate
void UpdateCombatEnabled(bool combatEnabled);
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="References", meta=(AllowPrivateAccess="true"))
@ -35,6 +37,8 @@ private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="EssentialMovementData", meta = (AllowPrivateAccess = "true"))
float GroundSpeed;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="EssentialMovementData", meta = (AllowPrivateAccess = "true"))
float Direction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="EssentialMovementData", meta = (AllowPrivateAccess = "true"))
bool ShouldMove;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="EssentialMovementData", meta = (AllowPrivateAccess = "true"))
bool IsFalling;

View File

@ -67,6 +67,7 @@ ACombatCharacter::ACombatCharacter()
// Setting CombatComponent
CombatComponent = CreateDefaultSubobject<UCombatComponent>(TEXT("CombatComponent"));
CombatComponent->OnCombatToggled.AddUObject(this, &ACombatCharacter::CharacterCombatToggled);
// Setting StateManagerComponent
StateManagerComponent = CreateDefaultSubobject<UStateManagerComponent>(TEXT("StateManagerComponent"));
@ -79,6 +80,9 @@ ACombatCharacter::ACombatCharacter()
StatsComponent = CreateDefaultSubobject<UStatsComponent>(TEXT("StatsComponent"));
StatsComponent->OnCurrentStatValueUpdated.AddUObject(this, &ACombatCharacter::CharacterCurrentStatValueUpdated);
//Setting TargetComponent
TargetingComponent = CreateDefaultSubobject<UTargetingComponent>(TEXT("TargetingComponent"));
//Setting MovementSpeed
MovementSpeedMode = EMovementSpeedMode::Jogging;
WalkingSpeed = 200.f;
@ -104,7 +108,7 @@ void ACombatCharacter::BeginPlay()
}
}
//Player에 무기를 처음부터 들고있게함. 아마도 임시코드
//Player have Weapon until first time : probably temp coding
FActorSpawnParameters spawnParam;
spawnParam.Owner = this;
spawnParam.Instigator = this;
@ -190,7 +194,6 @@ void ACombatCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerIn
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
//Jumping
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACombatCharacter::Jumping);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);
@ -223,7 +226,9 @@ void ACombatCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerIn
//Sprint
EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &ACombatCharacter::StartSprint);
EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Completed, this, &ACombatCharacter::StopSprint);
//ToggleLockOn
EnhancedInputComponent->BindAction(ToggleLockOnAction, ETriggerEvent::Started, this, &ACombatCharacter::ToggleLockOn);
}
}
@ -232,6 +237,30 @@ void ACombatCharacter::SetCanMove_Implementation(bool inputCanMove)
bCanMove = inputCanMove;
}
void ACombatCharacter::SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode)
{
if (NewSpeedMode == MovementSpeedMode)
return;
MovementSpeedMode = NewSpeedMode;
TargetingComponent->UpdateRotationMode();
switch (MovementSpeedMode)
{
case EMovementSpeedMode::Walking:
GetCharacterMovement()->MaxWalkSpeed = WalkingSpeed;
break;
case EMovementSpeedMode::Jogging:
GetCharacterMovement()->MaxWalkSpeed = JoggingSpeed;
break;
case EMovementSpeedMode::Sprinting:
GetCharacterMovement()->MaxWalkSpeed = SprintSpeed;
break;
default:
break;
}
}
void ACombatCharacter::Move(const FInputActionValue& Value)
{
if(!bCanMove) //Value changes SetCanMove Func Call to Animnotify
@ -266,8 +295,13 @@ void ACombatCharacter::Look(const FInputActionValue& Value)
if (Controller != nullptr)
{
// add yaw and pitch input to controller
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
if(!TargetingComponent->GetIsTargeting()) // Not Targeting
{
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
else // Targeting
AddControllerPitchInput(LookAxisVector.Y * 0.2f);
}
}
@ -366,7 +400,7 @@ void ACombatCharacter::Dodge(const FInputActionValue& Value)
void ACombatCharacter::ToggleWalk(const FInputActionValue& Value)
{
if (GetMovementSpeedMode() != EMovementSpeedMode::Walking)
if (GetCombatMovementSpeedMode() != EMovementSpeedMode::Walking)
SetMovementSpeedMode(EMovementSpeedMode::Walking);
else
SetMovementSpeedMode(EMovementSpeedMode::Jogging);
@ -389,6 +423,13 @@ void ACombatCharacter::StopSprint(const FInputActionValue& Value)
DisableSprint();
}
void ACombatCharacter::ToggleLockOn(const FInputActionValue& Value)
{
if(!CombatComponent->GetCombatEnabled() && !TargetingComponent->GetIsTargeting())
return;
TargetingComponent->ToggleLockOn();
}
void ACombatCharacter::CharacterStateBegin(FGameplayTag CharState)
{
if (FGameplayTag::EmptyTag == CharState)
@ -479,6 +520,12 @@ void ACombatCharacter::CharacterCurrentStatValueUpdated(EStats statType, float v
StateManagerComponent->SetCurrentState(FCombatGameplayTags::Get().Character_State_Dead);
}
void ACombatCharacter::CharacterCombatToggled(bool IsCombatEnabled)
{
if(IsValid(TargetingComponent))
TargetingComponent->UpdateRotationMode();
}
void ACombatCharacter::ToggleCombatEvent()
{
ABaseWeapon* baseWeapon = CombatComponent->GetMainWeapon();
@ -530,28 +577,6 @@ void ACombatCharacter::EnableRagdoll()
GetMesh()->SetAllBodiesBelowPhysicsBlendWeight(PelvisBoneName, 1.f);
}
void ACombatCharacter::SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode)
{
if (NewSpeedMode == MovementSpeedMode)
return;
MovementSpeedMode = NewSpeedMode;
switch (MovementSpeedMode)
{
case EMovementSpeedMode::Walking:
GetCharacterMovement()->MaxWalkSpeed = WalkingSpeed;
break;
case EMovementSpeedMode::Jogging:
GetCharacterMovement()->MaxWalkSpeed = JoggingSpeed;
break;
case EMovementSpeedMode::Sprinting:
GetCharacterMovement()->MaxWalkSpeed = SprintSpeed;
break;
default:
break;
}
}
bool ACombatCharacter::ResetChargeAttack()
{
AttackHeldTime = 0.f;
@ -570,7 +595,7 @@ void ACombatCharacter::DisableSprint()
if (World)
World->GetTimerManager().ClearTimer(StaminaTimerHandle);
if (GetMovementSpeedMode() == EMovementSpeedMode::Sprinting)
if (GetCombatMovementSpeedMode() == EMovementSpeedMode::Sprinting)
SetMovementSpeedMode(EMovementSpeedMode::Jogging);
}
@ -785,7 +810,7 @@ FGameplayTag ACombatCharacter::GetDesiredAttackType()
if (GetCharacterMovement()->IsFalling())
return FCombatGameplayTags::Get().Character_Action_Attack_FallingAttack;
if (GetMovementSpeedMode() == EMovementSpeedMode::Sprinting)
if (GetCombatMovementSpeedMode() == EMovementSpeedMode::Sprinting)
return FCombatGameplayTags::Get().Character_Action_Attack_SprintAttack;
if (IsHeavyAttack)

View File

@ -9,6 +9,7 @@
#include "Interface/CombatInterface.h"
#include "Components/StateManagerComponent.h"
#include "Components/StatsComponent.h"
#include "Components/TargetingComponent.h"
#include "Definitions/GameEnums.h"
#include "CombatCharacter.generated.h"
@ -65,6 +66,9 @@ class ACombatCharacter : public ACharacter, public ICombatInterface
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* SprintAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* ToggleLockOnAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Input, meta = (AllowPrivateAccess = "true"))
float ChargeAttackTime;
public:
@ -103,6 +107,12 @@ public:
void SetCanMove(bool inputCanMove);
virtual void SetCanMove_Implementation(bool inputCanMove) override;
virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); }
public:
void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode);
FORCEINLINE EMovementSpeedMode GetMovementSpeedMode() const { return MovementSpeedMode; }
protected:
//Input Funcs
void Move(const FInputActionValue& Value);
@ -117,7 +127,8 @@ protected:
void ToggleWalk(const FInputActionValue& Value);
void StartSprint(const FInputActionValue& Value);
void StopSprint(const FInputActionValue& Value);
void ToggleLockOn(const FInputActionValue& Value);
private://Delegate
void CharacterStateBegin(FGameplayTag CharState);
void CharacterStateEnd(FGameplayTag CharState);
@ -125,13 +136,12 @@ private://Delegate
void CharacterActionEnd(FGameplayTag CharAction);
void CharacterCurrentStatValueUpdated(EStats statType, float value);
void CharacterCombatToggled(bool IsCombatEnabled);
private:
void ToggleCombatEvent();
void AttackEvent();
void ApplyHitReactionPhysicsVelocity(float InitialSpeed);
void EnableRagdoll();
void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode);
FORCEINLINE EMovementSpeedMode GetMovementSpeedMode() const { return MovementSpeedMode; }
bool ResetChargeAttack();
void DisableSprint();
void SprintStaminaCost();
@ -161,6 +171,9 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<UStatsComponent> StatsComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<UTargetingComponent> TargetingComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Weapon", meta = (AllowPrivateAccess = "true"))
TSubclassOf<class ABaseEquippable> Weapon;

View File

@ -4,8 +4,6 @@
#include "Components/CombatComponent.h"
#include "Actor/BaseWeapon.h"
#include "Definitions/GameEnums.h"
#include "GameFramework/Character.h"
#include "Interface/IAnimInstance.h"
// Sets default values for this component's properties
UCombatComponent::UCombatComponent()
@ -21,13 +19,15 @@ void UCombatComponent::SetCombatEnabled(bool bInputCombat)
{
bCombatEnabled = bInputCombat;
ACharacter* character = Cast<ACharacter>(GetOwner());
if (character)
{
IIAnimInstance* Animinstance = Cast<IIAnimInstance>(character->GetMesh()->GetAnimInstance());
if (Animinstance)
Animinstance->UpdateCombatEnabled(bInputCombat);
}
OnCombatToggled.Broadcast(bInputCombat);
// ACharacter* character = Cast<ACharacter>(GetOwner());
// if (character)
// {
// IIAnimInstance* Animinstance = Cast<IIAnimInstance>(character->GetMesh()->GetAnimInstance());
// if (Animinstance)
// Animinstance->UpdateCombatEnabled(bInputCombat);
// }
}
void UCombatComponent::ResetAttack()

View File

@ -6,6 +6,7 @@
#include "Components/ActorComponent.h"
#include "CombatComponent.generated.h"
DECLARE_MULTICAST_DELEGATE_OneParam(FOnCombatToggled, bool);
class ABaseWeapon;
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
@ -46,5 +47,8 @@ private:
bool bIsAttackSaved;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
int32 AttackCount;
int32 AttackCount;
public: //Delegate
FOnCombatToggled OnCombatToggled;
};

View File

@ -0,0 +1,183 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Components/TargetingComponent.h"
#include "CombatComponent.h"
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Interface/CombatInterface.h"
#include "Interface/TargetingInterface.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"
// Sets default values for this component's properties
UTargetingComponent::UTargetingComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
TargetObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn));
TargetingDistance = 900.f;
TargetingRadius = 100.f;
TargetRotationInterpSpeed = 9.f;
DefaultRotationMode = ERotationMode::OrientToMovement;
}
// Called when the game starts
void UTargetingComponent::BeginPlay()
{
Super::BeginPlay();
ACharacter* character = Cast<ACharacter>(GetOwner());
if(IsValid(character))
{
OwnerCharacter = character;
OwnerController = OwnerCharacter->GetController();
FollowCamera = OwnerCharacter->GetComponentByClass<UCameraComponent>();
}
}
// Called every frame
void UTargetingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if(bIsTargeting)
UpdateTargetingControlRotation();
}
void UTargetingComponent::ToggleLockOn()
{
if(!bIsTargeting)
EnableLockOn();
else
DisableLockOn();
}
void UTargetingComponent::EnableLockOn()
{
AActor* FoundTarget;
if(FindTarget(&FoundTarget) && CanTargetActor(FoundTarget))
{
SetTargetActor(FoundTarget);
SetIsTargeting(true);
UpdateRotationMode();
}
}
void UTargetingComponent::DisableLockOn()
{
SetIsTargeting(false);
SetTargetActor(nullptr);
UpdateRotationMode();
}
void UTargetingComponent::SetIsTargeting(bool bEnableTargeting)
{
bIsTargeting = bEnableTargeting;
if(IsValid(TargetActor))
Cast<ITargetingInterface>(TargetActor)->OnTargeted(bEnableTargeting);
}
void UTargetingComponent::SetRotationMode(ERotationMode NewRotationMode)
{
if(!IsValid(OwnerCharacter))
return;
UCharacterMovementComponent* CharacterMovement = OwnerCharacter->GetCharacterMovement();
if(!IsValid(CharacterMovement))
return;
CurrentRotationMode = NewRotationMode;
switch (CurrentRotationMode)
{
case ERotationMode::OrientToCamera:
OwnerCharacter->bUseControllerRotationYaw = false;
CharacterMovement->bUseControllerDesiredRotation = true;
CharacterMovement->bOrientRotationToMovement = false;
break;
case ERotationMode::OrientToMovement:
OwnerCharacter->bUseControllerRotationYaw = false;
CharacterMovement->bUseControllerDesiredRotation = false;
CharacterMovement->bOrientRotationToMovement = true;
break;
default:
break;
}
}
bool UTargetingComponent::FindTarget(AActor** OutFoundTarget)
{
FVector StartLocation, EndLocation;
StartLocation = GetOwner()->GetActorLocation();
EndLocation = GetOwner()->GetActorLocation() + (FollowCamera->GetForwardVector() * TargetingDistance);
TArray<AActor*> ActorsToIgnore;
ActorsToIgnore.Add(GetOwner());
FHitResult OutHit;
bool CollisionResult = UKismetSystemLibrary::SphereTraceSingleForObjects(GetWorld(), StartLocation, EndLocation, TargetingRadius, TargetObjectTypes, false, ActorsToIgnore, EDrawDebugTrace::None, OutHit, true);
if(CollisionResult && IsValid(OutHit.GetActor()))
{
ITargetingInterface* targetingActor = Cast<ITargetingInterface>(OutHit.GetActor());
if(targetingActor)
{
*OutFoundTarget = OutHit.GetActor();
return true;
}
else
return false;
}
else
return false;
}
bool UTargetingComponent::CanTargetActor(AActor* InTargetActor)
{
if(!IsValid(InTargetActor))
return false;
if(!IsValid(GetOwner()))
return false;
ITargetingInterface* TargetActorInterface = Cast<ITargetingInterface>(InTargetActor);
if(!TargetActorInterface)
return false;
return ((GetOwner()->GetDistanceTo(TargetActor) < TargetingDistance) && TargetActorInterface->CanBeTargeted());
}
void UTargetingComponent::UpdateTargetingControlRotation()
{
if(!IsValid(OwnerController))
return;
if(!IsValid(TargetActor))
return;
if(CanTargetActor(TargetActor))
{
FVector TargetLocation;
TargetLocation = TargetActor->GetActorLocation() - FVector(0.f, 0.f, 100.f);
FRotator TargetRotation = UKismetMathLibrary::FindLookAtRotation(GetOwner()->GetActorLocation(), TargetLocation);
FRotator CameraRotation = FMath::RInterpTo(OwnerController->K2_GetActorRotation(), TargetRotation, UGameplayStatics::GetWorldDeltaSeconds(GetOwner()), TargetRotationInterpSpeed);
OwnerController->SetControlRotation(UKismetMathLibrary::MakeRotator(OwnerController->K2_GetActorRotation().Roll, CameraRotation.Pitch, CameraRotation.Yaw));
}
else
DisableLockOn();
}
void UTargetingComponent::UpdateRotationMode()
{
if(!IsValid(OwnerCombatComponent))
OwnerCombatComponent = OwnerCharacter->GetComponentByClass<UCombatComponent>();
bool result = OwnerCombatComponent->GetCombatEnabled();
result &= (Cast<ICombatInterface>(OwnerCharacter)->GetCombatMovementSpeedMode() != EMovementSpeedMode::Sprinting);
result &= GetIsTargeting();
if(result)
SetRotationMode(ERotationMode::OrientToCamera);
else
SetRotationMode(DefaultRotationMode);
}

View File

@ -0,0 +1,72 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "TargetingComponent.generated.h"
UENUM(BlueprintType)
enum class ERotationMode : uint8
{
OrientToCamera UMETA(DisplayName = "OrientToCamera"),
OrientToMovement UMETA(DisplayName = "OrientToMovement"),
};
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class D1_API UTargetingComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UTargetingComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
public:
void ToggleLockOn();
void EnableLockOn();
void DisableLockOn();
void SetIsTargeting(bool bEnableTargeting);
FORCEINLINE bool GetIsTargeting() { return bIsTargeting; }
FORCEINLINE void SetTargetActor(AActor* NewTargetActor) { TargetActor = NewTargetActor; }
FORCEINLINE AActor* GetTargetActor() { return TargetActor; }
void SetRotationMode(ERotationMode NewRotationMode);
FORCEINLINE ERotationMode GetRotationMode() { return CurrentRotationMode; }
bool FindTarget(AActor** OutFoundTarget);
bool CanTargetActor(AActor* InTargetActor);
void UpdateTargetingControlRotation();
void UpdateRotationMode();
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
TArray<TEnumAsByte<EObjectTypeQuery>> TargetObjectTypes;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
float TargetingDistance;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
float TargetingRadius;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
float TargetRotationInterpSpeed;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
ERotationMode DefaultRotationMode;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
TObjectPtr<class UCameraComponent> FollowCamera;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
TObjectPtr<class UCombatComponent> OwnerCombatComponent;
private:
TObjectPtr<ACharacter> OwnerCharacter;
TObjectPtr<AController> OwnerController;
TObjectPtr<AActor> TargetActor;
bool bIsTargeting;
ERotationMode CurrentRotationMode;
};

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Definitions/GameEnums.h"
#include "UObject/Interface.h"
#include "CombatInterface.generated.h"
@ -34,4 +35,6 @@ public:
bool CanReceiveDamage();
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void SetCanMove(bool inputCanMove);
virtual EMovementSpeedMode GetCombatMovementSpeedMode() = 0;
};

View File

@ -24,5 +24,4 @@ class D1_API IIAnimInstance
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
virtual void UpdateCombatType(ECombatType combatType) = 0;
virtual void UpdateCombatEnabled(bool combatEnabled) = 0;
};

View File

@ -0,0 +1,6 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Interface/TargetingInterface.h"
// Add default functionality here for any ITargetingInterface functions that are not pure virtual.

View File

@ -0,0 +1,27 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "TargetingInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UTargetingInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class D1_API ITargetingInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
virtual bool CanBeTargeted() = 0;
virtual void OnTargeted(bool bIsTargeted) = 0;
};

View File

@ -4,8 +4,20 @@
#include "TestDummyCharacter.h"
#include "Engine/DamageEvents.h"
#include "Actor/BaseEquippable.h"
#include "Components/WidgetComponent.h"
#include "Kismet/GameplayStatics.h"
ATestDummyCharacter::ATestDummyCharacter()
{
//Setting Widget class is Editor to Blueprint
LockOnWidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("LockOnWidget"));
LockOnWidgetComponent->SetWidgetSpace(EWidgetSpace::Screen);
LockOnWidgetComponent->SetDrawSize({20.f, 20.f});
LockOnWidgetComponent->SetupAttachment(RootComponent);
LockOnWidgetComponent->SetRelativeLocation(FVector(0.f, 0.f, 40.f));
LockOnWidgetComponent->SetVisibility(false);
}
void ATestDummyCharacter::BeginPlay()
{
ACharacter::BeginPlay();
@ -22,6 +34,19 @@ void ATestDummyCharacter::BeginPlay()
}
}
bool ATestDummyCharacter::CanBeTargeted()
{
FGameplayTagContainer inputContainer;
inputContainer.AddTag(FCombatGameplayTags::Get().Character_State_Dead);
return !StateManagerComponent->IsCurrentStateEqualToAny(inputContainer);
}
void ATestDummyCharacter::OnTargeted(bool bIsTargeted)
{
LockOnWidgetComponent->SetVisibility(bIsTargeted);
}
//float ATestDummyCharacter::TakeDamage(float Damage, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
//{
// float fDamage = ACharacter::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser);

View File

@ -4,20 +4,30 @@
#include "CoreMinimal.h"
#include "CombatCharacter.h"
#include "Interface/TargetingInterface.h"
#include "TestDummyCharacter.generated.h"
/**
*
*/
UCLASS()
class D1_API ATestDummyCharacter : public ACombatCharacter
class D1_API ATestDummyCharacter : public ACombatCharacter, public ITargetingInterface
{
GENERATED_BODY()
public:
ATestDummyCharacter();
public:
virtual void BeginPlay() override;
protected:
// Inherited via ITargetingInterface
virtual bool CanBeTargeted() override;
virtual void OnTargeted(bool bIsTargeted) override;
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TArray<TSubclassOf<class ABaseEquippable>> StartingEquipment;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="UI")
TObjectPtr<class UWidgetComponent> LockOnWidgetComponent;
};

View File

@ -0,0 +1,5 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "UI/UI_LockOn.h"

View File

@ -0,0 +1,20 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "UI_LockOn.generated.h"
/**
*
*/
UCLASS()
class D1_API UUI_LockOn : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
TObjectPtr<class UImage> LockOnPoint;
};