Punch Mechanic - Part 2

No punching while running
Enemy can fight back
Punch reaction animation
This commit is contained in:
charnet3d 2024-01-28 21:48:11 +01:00
parent dc7333b3a2
commit 549d4e590a
17 changed files with 114 additions and 60 deletions

View File

@ -355,23 +355,23 @@ bEnableDomStorage=False
-Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False) -Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
+Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision") +Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision")
+Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.") +Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.")
+Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ") +Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ")
+Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ") +Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ")
+Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic"),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.") +Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.")
+Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.") +Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.")
+Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors") +Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors")
+Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors") +Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors")
+Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.") +Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.")
+Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.") +Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.")
+Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.") +Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.")
+Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.") +Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.")
+Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.") +Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.")
+Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="Enemy") +DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="Fighting")
-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall") -ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn") -ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic") -ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
@ -390,4 +390,5 @@ bEnableDomStorage=False
+CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") +CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
+CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") +CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn") +CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
+CollisionChannelRedirects=(OldName="Enemy",NewName="Fighting")

Binary file not shown.

BIN
Content/SideScroller/Animations/Combat/PunchReaction1.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,7 @@
#include "EnemyCharacter.h" #include "EnemyCharacter.h"
#include "EnhancedInputComponent.h"
AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer) AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -10,18 +11,19 @@ AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer)
void AEnemyCharacter::BeginPlay() void AEnemyCharacter::BeginPlay()
{ {
/*GetWorldTimerManager().SetTimer(AutoPunch, this, &AEnemyCharacter::StartPunch, // Call the base class
1.f);*/ Super::BeginPlay();
GetWorldTimerManager().SetTimer(AutoPunch, this, &AEnemyCharacter::StartPunch,
1.f);
} }
void AEnemyCharacter::Tick(float DeltaTime) void AEnemyCharacter::Tick(float DeltaTime)
{ {
Super::Tick(DeltaTime);
} }
void AEnemyCharacter::StartPunch() void AEnemyCharacter::StartPunch()
{ {
if (CanAttack)
UE_LOG(LogTemp, Warning, TEXT("Enemy StartPunch()"));
Super::StartPunch(); Super::StartPunch();
GetWorldTimerManager().SetTimer(AutoPunch, this, &AEnemyCharacter::StartPunch, GetWorldTimerManager().SetTimer(AutoPunch, this, &AEnemyCharacter::StartPunch,
1.f); 1.f);

View File

@ -20,7 +20,6 @@ class FUNNYPRINCE_API AEnemyCharacter : public AFunnyPrinceCharacter
public: public:
AEnemyCharacter(const FObjectInitializer& ObjectInitializer); AEnemyCharacter(const FObjectInitializer& ObjectInitializer);
protected: protected:
// To add mapping context // To add mapping context
virtual void BeginPlay() override; virtual void BeginPlay() override;

View File

@ -3,10 +3,9 @@
#include "FunnyPrinceCharacter.h" #include "FunnyPrinceCharacter.h"
#include "SSTCharacterMovementComponent.h" #include "SSTCharacterMovementComponent.h"
#include "Components/InputComponent.h" #include "EnhancedInputComponent.h"
#include "Components/ArrowComponent.h" #include "Components/ArrowComponent.h"
#include "EnhancedInputComponent.h" #include "EnhancedInputComponent.h"
#include "InputActionValue.h"
#include "Engine/DamageEvents.h" #include "Engine/DamageEvents.h"
#include "EnemyCharacter.h" #include "EnemyCharacter.h"
@ -17,14 +16,24 @@ DEFINE_LOG_CATEGORY(LogTemplateFunnyPrinceCharacter);
// AFunnyPrinceCharacter // AFunnyPrinceCharacter
AFunnyPrinceCharacter::AFunnyPrinceCharacter(const FObjectInitializer& ObjectInitializer) AFunnyPrinceCharacter::AFunnyPrinceCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer),
MoveAction2(nullptr),
PunchAction(nullptr),
PunchMontage(nullptr),
StartAttack(nullptr),
EndAttack(nullptr),
CanAttack(true),
MaxHealth(100),
Health(100),
PunchDamage(10),
CanMove(true)
{ {
StartAttack = CreateDefaultSubobject<UArrowComponent>("StartAttack"); StartAttack = CreateDefaultSubobject<UArrowComponent>("StartAttack");
StartAttack->SetupAttachment(RootComponent); StartAttack->SetupAttachment(RootComponent);
StartAttack->SetRelativeLocation(FVector(60.f, 0.f, 40.f)); StartAttack->SetRelativeLocation(FVector(60.f, 0.f, 40.f));
StartAttack->SetArrowSize(0.5f); StartAttack->SetArrowSize(0.5f);
StartAttack->SetArrowLength(30.f); StartAttack->SetArrowLength(30.f);
EndAttack = CreateDefaultSubobject<UArrowComponent>("EndAttack"); EndAttack = CreateDefaultSubobject<UArrowComponent>("EndAttack");
EndAttack->SetupAttachment(RootComponent); EndAttack->SetupAttachment(RootComponent);
@ -50,6 +59,9 @@ void AFunnyPrinceCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInp
// Set up action bindings // Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) { if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
//Moving
EnhancedInputComponent->BindAction(MoveAction2, ETriggerEvent::Triggered, this, &AFunnyPrinceCharacter::Move);
// Punching // Punching
EnhancedInputComponent->BindAction(PunchAction, ETriggerEvent::Started, this, &AFunnyPrinceCharacter::StartPunch); EnhancedInputComponent->BindAction(PunchAction, ETriggerEvent::Started, this, &AFunnyPrinceCharacter::StartPunch);
} }
@ -117,11 +129,8 @@ void AFunnyPrinceCharacter::StartPunch()
if (AnimInstance && PunchMontage) if (AnimInstance && PunchMontage)
{ {
UE_LOG(LogTemp, Warning, TEXT("StartPunch()")); UE_LOG(LogTemp, Warning, TEXT("StartPunch()"));
//CanAttack = false; CanAttack = false;
if (Enemy && Enemy->GetMesh()->GetAnimInstance()) CanMove = false;
{
Enemy->GetMesh()->GetAnimInstance()->Montage_Play(Enemy->PunchMontage);
}
AnimInstance->Montage_Play(PunchMontage); AnimInstance->Montage_Play(PunchMontage);
//AnimInstance->Montage_JumpToSection(FName("StartFire")); //AnimInstance->Montage_JumpToSection(FName("StartFire"));
} }
@ -130,6 +139,7 @@ void AFunnyPrinceCharacter::StartPunch()
void AFunnyPrinceCharacter::FinishPunching() void AFunnyPrinceCharacter::FinishPunching()
{ {
CanMove = true;
CanAttack = true; CanAttack = true;
} }
@ -142,16 +152,25 @@ void AFunnyPrinceCharacter::PunchHitTrace()
FVector start = StartAttack->GetSocketLocation(FName()); FVector start = StartAttack->GetSocketLocation(FName());
FVector end = EndAttack->GetSocketLocation(FName()); FVector end = EndAttack->GetSocketLocation(FName());
FCollisionQueryParams Params; /*FCollisionQueryParams Params;
Params.AddIgnoredActor(this); Params.AddIgnoredActor(this);*/
bool bSuccess = GetWorld()->LineTraceSingleByChannel(PunchTraceHit, start, end, ECollisionChannel::ECC_GameTraceChannel1, Params); bool bSuccess = GetWorld()->LineTraceSingleByChannel(PunchTraceHit, start, end, ECollisionChannel::ECC_GameTraceChannel1);
if (bSuccess) if (bSuccess)
{ {
AActor* HitActor = PunchTraceHit.GetActor(); AFunnyPrinceCharacter* HitEnemy = Cast<AFunnyPrinceCharacter>(PunchTraceHit.GetActor());
if (HitActor) if (HitEnemy)
{ {
FPointDamageEvent DamageEvent(PunchDamage, PunchTraceHit, end - start, nullptr); FPointDamageEvent DamageEvent(PunchDamage, PunchTraceHit, end - start, nullptr);
HitActor->TakeDamage(PunchDamage, DamageEvent, GetController(), this); HitEnemy->TakeDamage(PunchDamage, DamageEvent, GetController(), this);
UAnimInstance* AnimInstance = HitEnemy->GetMesh()->GetAnimInstance();
if (AnimInstance && PunchReactionMontage)
{
UE_LOG(LogTemp, Warning, TEXT("Punch Reaction"));
HitEnemy->CanAttack = false;
HitEnemy->CanMove = false;
AnimInstance->Montage_Play(PunchReactionMontage);
}
} }
} }
/*UE_LOG(LogTemp, Warning, TEXT("TraceHit from %f %f %f to %f %f %f"), /*UE_LOG(LogTemp, Warning, TEXT("TraceHit from %f %f %f to %f %f %f"),
@ -162,7 +181,21 @@ void AFunnyPrinceCharacter::PunchHitTrace()
end.Y, end.Y,
end.Z);*/ end.Z);*/
// (World, Start, End, Color, Persistent Lines, Life Time, Depth Priority, Thickness) // (World, Start, End, Color, Persistent Lines, Life Time, Depth Priority, Thickness)
DrawDebugLine(GetWorld(), start, end, FColor(255, 0, 0), false, 1, 0, 5); //DrawDebugLine(GetWorld(), start, end, FColor(255, 0, 0), false, 1, 0, 5);
} }
} }
void AFunnyPrinceCharacter::FinishPunchReaction()
{
CanMove = true;
CanAttack = true;
}
void AFunnyPrinceCharacter::Move(const FInputActionValue& Value)
{
if (CanMove)
{
Super::Move(Value);
}
}

View File

@ -44,6 +44,8 @@ protected:
virtual bool CanJumpInternal_Implementation() const override; virtual bool CanJumpInternal_Implementation() const override;
void Move(const struct FInputActionValue& Value);
virtual void StartPunch(); virtual void StartPunch();
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
@ -52,41 +54,52 @@ protected:
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
void PunchHitTrace(); void PunchHitTrace();
UFUNCTION(BlueprintCallable)
void FinishPunchReaction();
/** Move Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = true))
TObjectPtr<class UInputAction> MoveAction2;
/** Punch Input Action */ /** Punch Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = true)) UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = true))
TObjectPtr<class UInputAction> PunchAction = nullptr; TObjectPtr<class UInputAction> PunchAction;
/** Punch Montage */ /** Punch Montage */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
UAnimMontage* PunchMontage = nullptr; UAnimMontage* PunchMontage;
/** Punch Reaction Montage */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
UAnimMontage* PunchReactionMontage;
/** Punch Start Position */ /** Punch Start Position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
UArrowComponent* StartAttack = nullptr; UArrowComponent* StartAttack;
/** Punch End Position */ /** Punch End Position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
UArrowComponent* EndAttack = nullptr; UArrowComponent* EndAttack;
/** Punch Input Action */ /** Punch Input Action */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true))
bool CanAttack = true; bool CanAttack;
UPROPERTY(EditDefaultsOnly) UPROPERTY(EditAnywhere)
float MaxHealth = 100; float MaxHealth;
/** Current Health */ /** Current Health */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true))
float Health = 100; float Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true)) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
float PunchDamage = 10; float PunchDamage;
/** Punch End Position */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Combat, meta = (AllowPrivateAccess = true))
TSoftObjectPtr<AEnemyCharacter> Enemy = nullptr;
/** Whether the player can move */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true))
bool CanMove;
private: private:
public: public:
}; };