diff --git a/Source/Nakatomi/EnemyAIController.cpp b/Source/Nakatomi/EnemyAIController.cpp index 66fd18c..f7a37d3 100644 --- a/Source/Nakatomi/EnemyAIController.cpp +++ b/Source/Nakatomi/EnemyAIController.cpp @@ -160,7 +160,6 @@ void AEnemyAIController::OnPerceptionUpdated(const TArray& actors) else if (stimulus.Type == HearingID) { SensedHearing(actor, stimulus); - stimulus.StimulusLocation; } else if (stimulus.Type == DamageID) { diff --git a/Source/Nakatomi/EnemyCharacter.cpp b/Source/Nakatomi/EnemyCharacter.cpp index 41bf8bb..8018d9e 100644 --- a/Source/Nakatomi/EnemyCharacter.cpp +++ b/Source/Nakatomi/EnemyCharacter.cpp @@ -2,6 +2,7 @@ #include "EnemyCharacter.h" #include "EnemyAIController.h" +#include "EnemyHealthComponent.h" #include "InteractableComponent.h" #define COLLISION_WEAPON ECC_GameTraceChannel1 @@ -10,6 +11,10 @@ AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer) : { RandomWeaponParameters = CreateDefaultSubobject(TEXT("Random Weapon Parameters")); + auto healthComponent = CreateDefaultSubobject(TEXT("Health Component")); + SetHealthComponent(healthComponent); + GetHealthComponent()->OnDamaged.BindUFunction(this, "OnDamaged"); + GetHealthComponent()->OnDeath.BindUFunction(this, "OnDeath"); GetHealthComponent()->SetMaxHealth(100.0f); this->Tags.Add(FName("Enemy")); diff --git a/Source/Nakatomi/EnemyHealthComponent.cpp b/Source/Nakatomi/EnemyHealthComponent.cpp new file mode 100644 index 0000000..820c831 --- /dev/null +++ b/Source/Nakatomi/EnemyHealthComponent.cpp @@ -0,0 +1,36 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "EnemyHealthComponent.h" + +#include "EnemyAIController.h" +#include "EnemyCharacter.h" + +void UEnemyHealthComponent::BeginPlay() +{ + Super::BeginPlay(); +} + +void UEnemyHealthComponent::TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, + AController* instigatedBy, AActor* damageCauser) +{ + if (damagedActor == nullptr || IsDead || !CanDamage) + { + return; + } + + CurrentHealth -= damage; + + AEnemyCharacter* enemyCharacter = Cast(damagedActor); + UAISense_Damage::ReportDamageEvent(GetWorld(), damagedActor, damageCauser, 1, + damageCauser->GetTransform().GetLocation(), + damageCauser->GetTransform().GetLocation()); + + OnDamaged.ExecuteIfBound({damagedActor, damage, damageType, instigatedBy, damageCauser}); + + if (CurrentHealth <= 0.0f) + { + IsDead = true; + OnDeath.ExecuteIfBound({damagedActor, damage, damageType, instigatedBy, damageCauser}); + } +} diff --git a/Source/Nakatomi/EnemyHealthComponent.h b/Source/Nakatomi/EnemyHealthComponent.h new file mode 100644 index 0000000..fd7536c --- /dev/null +++ b/Source/Nakatomi/EnemyHealthComponent.h @@ -0,0 +1,22 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "HealthComponent.h" +#include "EnemyHealthComponent.generated.h" + +/** + * + */ +UCLASS() +class NAKATOMI_API UEnemyHealthComponent : public UHealthComponent +{ + GENERATED_BODY() + +protected: + virtual void BeginPlay() override; + + virtual void TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, AController* instigatedBy, AActor* damageCauser) override; + +}; diff --git a/Source/Nakatomi/HealthComponent.h b/Source/Nakatomi/HealthComponent.h index 8e15ccd..9ec0b1d 100644 --- a/Source/Nakatomi/HealthComponent.h +++ b/Source/Nakatomi/HealthComponent.h @@ -39,7 +39,7 @@ public: FOnDamageDelegate OnDamaged; FOnDeathDelegate OnDeath; -private: +protected: UPROPERTY(EditDefaultsOnly) float MaxHealth = 100.f; @@ -55,7 +55,7 @@ public: UHealthComponent(); UFUNCTION() - void TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, AController* instigatedBy, + virtual void TakeDamage(AActor* damagedActor, float damage, const UDamageType* damageType, AController* instigatedBy, AActor* damageCauser); UFUNCTION() diff --git a/Source/Nakatomi/NakatomiCharacter.cpp b/Source/Nakatomi/NakatomiCharacter.cpp index ec54fda..536c469 100644 --- a/Source/Nakatomi/NakatomiCharacter.cpp +++ b/Source/Nakatomi/NakatomiCharacter.cpp @@ -14,9 +14,12 @@ ANakatomiCharacter::ANakatomiCharacter(const FObjectInitializer& ObjectInitializ NakatomiCMC = Cast(GetCharacterMovement()); - HealthComponent = CreateDefaultSubobject(TEXT("Health Component")); - HealthComponent->OnDamaged.BindUFunction(this, "OnDamaged"); - HealthComponent->OnDeath.BindUFunction(this, "OnDeath"); + // if (!HealthComponent) + // { + // HealthComponent = CreateDefaultSubobject(TEXT("Health Component")); + // HealthComponent->OnDamaged.BindUFunction(this, "OnDamaged"); + // HealthComponent->OnDeath.BindUFunction(this, "OnDeath"); + // } } // Called when the game starts or when spawned diff --git a/Source/Nakatomi/PlayerCharacter.cpp b/Source/Nakatomi/PlayerCharacter.cpp index de607e9..3846d19 100644 --- a/Source/Nakatomi/PlayerCharacter.cpp +++ b/Source/Nakatomi/PlayerCharacter.cpp @@ -30,6 +30,10 @@ APlayerCharacter::APlayerCharacter(const FObjectInitializer& ObjectInitializer) //bUseControllerRotationYaw = true; //bUseControllerRotationRoll = false; + SetHealthComponent(CreateDefaultSubobject(TEXT("Health Component"))); + GetHealthComponent()->OnDamaged.BindUFunction(this, "OnDamaged"); + GetHealthComponent()->OnDeath.BindUFunction(this, "OnDeath"); + // Setup the camera boom CameraSpringArmComponent = CreateDefaultSubobject(TEXT("CameraSpringArmComponent")); CameraSpringArmComponent->SetupAttachment(RootComponent); @@ -398,6 +402,7 @@ void APlayerCharacter::ProcessHits(TArray hits) { healthComponent->TakeDamage(Hit.GetActor(), CurrentWeapon->GetWeaponProperties()->WeaponDamage, nullptr, GetController(), this); + if (!healthComponent->GetIsDead()) { OnEnemyHit.ExecuteIfBound(); @@ -437,6 +442,8 @@ void APlayerCharacter::ProcessHits(TArray hits) true); } } + + MakeNoise(1, this, Hit.Location); } } @@ -639,6 +646,8 @@ void APlayerCharacter::OnFire() CurrentWeapon->PlayFireSoundAtLocation(this->GetTransform().GetLocation()); + MakeNoise(1,this, this->GetTransform().GetLocation()); + PlayOnFireAnimations(); CurrentWeapon->SetCurrentWeaponStatus(Cooldown);