Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Fill out your copyright notice in the Description page of Project Settings.
- #include "Enemy/Enemy.h"
- #include "AIController.h"
- #include "Components/SkeletalMeshComponent.h"
- #include "Components/CapsuleComponent.h"
- #include "Components/AttributeComponent.h"
- #include "HUD/HealthBarComponent.h"
- #include "GameFramework/CharacterMovementComponent.h"
- #include "Perception/PawnSensingComponent.h"
- #include "Items/Weapons/Weapon.h"
- #include "Kismet/KismetSystemLibrary.h"
- #include "Kismet/GameplayStatics.h"
- #include "Slash/DebugMacros.h"
- // Sets default values
- AEnemy::AEnemy()
- {
- // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
- PrimaryActorTick.bCanEverTick = true;
- GetMesh()->SetCollisionObjectType(ECollisionChannel::ECC_WorldDynamic);
- GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Visibility, ECollisionResponse::ECR_Block);
- GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
- GetMesh()->SetGenerateOverlapEvents(true);
- GetCapsuleComponent()->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore);
- HealthBarWidget = CreateDefaultSubobject<UHealthBarComponent>(TEXT("Helth Bar Widget"));
- HealthBarWidget->SetupAttachment(GetRootComponent());
- GetCharacterMovement()->bOrientRotationToMovement = true;
- bUseControllerRotationPitch = false;
- bUseControllerRotationYaw = false;
- bUseControllerRotationRoll = false;
- PawnSensing = CreateDefaultSubobject<UPawnSensingComponent>(TEXT("Pawn Sensing"));
- PawnSensing->SightRadius = 2048.f;
- PawnSensing->SetPeripheralVisionAngle(45.f);
- }
- void AEnemy::PatrolTimerFinished()
- {
- MoveToTarget(PatrolTarget);
- }
- void AEnemy::BeginPlay()
- {
- Super::BeginPlay();
- if (HealthBarWidget)
- {
- HealthBarWidget->SetVisibility(false);
- }
- EnemyController = Cast<AAIController>(GetController());
- MoveToTarget(PatrolTarget);
- if (PawnSensing)
- {
- PawnSensing->OnSeePawn.AddDynamic(this, &AEnemy::PawnSeen);
- }
- UWorld* World = GetWorld();
- if (World && WeaponClass)
- {
- AWeapon* DefultWeapon = World->SpawnActor<AWeapon>(WeaponClass);
- DefultWeapon->Equip(GetMesh(), FName("RightHandSocket"), this, this);
- EquippedWeapon = DefultWeapon;
- }
- /*
- if (EnemyController && PatrolTarget)
- {
- FAIMoveRequest MoveRequest;
- MoveRequest.SetGoalActor(PatrolTarget);
- MoveRequest.SetAcceptanceRadius(15.f);
- FNavPathSharedPtr NavPath;
- EnemyController->MoveTo(MoveRequest, &NavPath);
- TArray<FNavPathPoint>& PathPoints = NavPath->GetPathPoints();
- for (auto& Point : PathPoints)
- {
- const FVector& Location = Point.Location;
- DrawDebugSphere(GetWorld(), Location, 12.f, 12, FColor::Green, false, 10.f);
- }
- }
- */
- }
- void AEnemy::ClearPatrolTimer()
- {
- GetWorldTimerManager().ClearTimer(PatrolTimer);
- }
- void AEnemy::PawnSeen(APawn* SeenPawn)
- {
- const bool bShouldChaseTarget =
- EnemyState != EEnemyState::EES_Dead &&
- EnemyState != EEnemyState::EES_Chasing &&
- EnemyState < EEnemyState::EES_Attacking &&
- SeenPawn->ActorHasTag(FName("SlashCharacter"));
- if (bShouldChaseTarget)
- {
- CombatTarget = SeenPawn;
- ClearPatrolTimer();
- ChaseTarget();
- }
- }
- void AEnemy::Die()
- {
- UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
- if (AnimInstance && DeathMontage)
- {
- AnimInstance->Montage_Play(DeathMontage);
- const int32 Selection = FMath::RandRange(0, 4);
- FName SectionName = FName();
- switch (Selection)
- {
- case 0:
- SectionName = FName("Death1");
- DeathPose = EDeathPose::EDP_Death1;
- break;
- case 1:
- SectionName = FName("Death2");
- DeathPose = EDeathPose::EDP_Death2;
- break;
- case 2:
- SectionName = FName("Death3");
- DeathPose = EDeathPose::EDP_Death3;
- break;
- case 3:
- SectionName = FName("Death4");
- DeathPose = EDeathPose::EDP_Death4;
- break;
- case 4:
- SectionName = FName("Death5");
- DeathPose = EDeathPose::EDP_Death5;
- break;
- default:
- break;
- }
- AnimInstance->Montage_JumpToSection(SectionName, DeathMontage);
- }
- GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
- SetLifeSpan(20.f);
- if (HealthBarWidget)
- {
- HealthBarWidget->SetVisibility(false);
- }
- }
- bool AEnemy::InTargetRange(AActor* Target, double Radius)
- {
- if (Target == nullptr) return false;
- const double DistanceToTarget = (Target->GetActorLocation() - GetActorLocation()).Size();
- //DRAW_SPHERE_SingleFrame(GetActorLocation());
- //DRAW_SPHERE_SingleFrame(Target->GetActorLocation());
- return DistanceToTarget <= Radius;
- }
- void AEnemy::MoveToTarget(AActor* Target)
- {
- if (EnemyController == nullptr || Target == nullptr) return;
- FAIMoveRequest MoveRequest;
- MoveRequest.SetGoalActor(Target);
- MoveRequest.SetAcceptanceRadius(50.f);
- EnemyController->MoveTo(MoveRequest);
- }
- AActor* AEnemy::ChoosePatrolTarget()
- {
- TArray<AActor*> ValitdTargets;
- for (AActor* Target : PatrolTargets)
- {
- if (Target != PatrolTarget)
- {
- ValitdTargets.AddUnique(Target);
- }
- }
- const int32 NumPatrolTargets = ValitdTargets.Num();
- if (NumPatrolTargets > 0)
- {
- const int32 TargetSelecection = FMath::RandRange(0, NumPatrolTargets - 1);
- return ValitdTargets[TargetSelecection];
- }
- return nullptr;
- }
- void AEnemy::Attack()
- {
- Super::Attack();
- PlayAttackMontage();
- }
- void AEnemy::PlayAttackMontage()
- {
- Super::PlayAttackMontage();
- UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
- if (AnimInstance && AttackMontage)
- {
- AnimInstance->Montage_Play(AttackMontage);
- const int32 Selection = FMath::RandRange(0, 2);
- FName SlectionName = FName();
- switch (Selection)
- {
- case 0:
- SlectionName = FName("Attack1");
- break;
- case 1:
- SlectionName = FName("Attack2");
- break;
- default:
- break;
- }
- AnimInstance->Montage_JumpToSection(SlectionName, AttackMontage);
- }
- }
- void AEnemy::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- if (EnemyState > EEnemyState::EES_Patrolling)
- {
- CheckCombatTarget();
- }
- else
- {
- CheckPatrolTarget();
- }
- /*
- if (PatrolTarget && EnemyController)
- {
- if (InTargetRange(PatrolTarget, PatrollRadius))
- {
- TArray<AActor*> ValitdTargets;
- for (AActor* Target : PatrolTargets)
- {
- if (Target != PatrolTarget)
- {
- ValitdTargets.AddUnique(Target);
- }
- }
- const int32 NumPatrolTargets = PatrolTargets.Num();
- if (NumPatrolTargets > 0)
- {
- const int32 TargetSelecection = FMath::RandRange(0, NumPatrolTargets - 1);
- AActor* Target = ValitdTargets[TargetSelecection];
- PatrolTarget = Target;
- FAIMoveRequest MoveRequest;
- MoveRequest.SetGoalActor(PatrolTarget);
- MoveRequest.SetAcceptanceRadius(15.f);
- EnemyController->MoveTo(MoveRequest);
- }
- }
- }
- */
- }
- void AEnemy::CheckPatrolTarget()
- {
- if (InTargetRange(PatrolTarget, PatrollRadius))
- {
- PatrolTarget = ChoosePatrolTarget();
- //MoveToTarget(PatrolTarget);
- const int32 PatrolWaitTime = FMath::RandRange(WaitMaxMin.X, WaitMaxMin.Y);
- GetWorldTimerManager().SetTimer(PatrolTimer, this, &AEnemy::PatrolTimerFinished, PatrolWaitTime);
- }
- }
- void AEnemy::HideHealthBar()
- {
- if (HealthBarWidget)
- {
- HealthBarWidget->SetVisibility(false);
- }
- }
- void AEnemy::ShowHealthBar()
- {
- if (HealthBarWidget)
- {
- HealthBarWidget->SetVisibility(true);
- }
- }
- void AEnemy::LoosInterest()
- {
- CombatTarget = nullptr;
- HideHealthBar();
- }
- void AEnemy::StartPatrolling()
- {
- EnemyState = EEnemyState::EES_Patrolling;
- GetCharacterMovement()->MaxWalkSpeed = PatrollingSpeed;
- MoveToTarget(PatrolTarget);
- UE_LOG(LogTemp, Warning, TEXT("Loos intrest"));
- }
- void AEnemy::ChaseTarget()
- {
- //Outside attack range, chase character
- EnemyState = EEnemyState::EES_Chasing;
- GetCharacterMovement()->MaxWalkSpeed = chasingSpeed;
- MoveToTarget(CombatTarget);
- UE_LOG(LogTemp, Warning, TEXT("Chase player"));
- }
- bool AEnemy::IsOutsideCombatRadius()
- {
- return !InTargetRange(CombatTarget, CombatRadius);
- }
- bool AEnemy::IsOutsideAttackRadius()
- {
- return !InTargetRange(CombatTarget, CombatRadius);
- }
- bool AEnemy::IsInsideAttackRadius()
- {
- return InTargetRange(CombatTarget, AttackRadius);
- }
- bool AEnemy::IsChasing()
- {
- return EnemyState == EEnemyState::EES_Chasing;
- }
- bool AEnemy::IsAttacking()
- {
- return EnemyState == EEnemyState::EES_Attacking;
- }
- void AEnemy::StartAttackTimer()
- {
- EnemyState = EEnemyState::EES_Attacking;
- const float AttackTime = FMath::RandRange(AttackMinMaxTime.X,AttackMinMaxTime.Y);
- GetWorldTimerManager().SetTimer(AttackTimer, this, &AEnemy::Attack, AttackTime);
- }
- void AEnemy::CheckCombatTarget()
- {
- if (IsOutsideCombatRadius())
- {
- LoosInterest();
- StartPatrolling();
- }
- else if (IsOutsideAttackRadius() && !IsChasing())
- {
- ChaseTarget();
- }
- else if (IsInsideAttackRadius() && !IsAttacking())
- {
- StartAttackTimer();
- /*
- //Inside attacking range, attack charechter
- EnemyState = EEnemyState::EES_Attacking;
- Attack();
- */
- UE_LOG(LogTemp, Warning, TEXT("Attacking"));
- }
- }
- void AEnemy::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
- {
- Super::SetupPlayerInputComponent(PlayerInputComponent);
- }
- void AEnemy::GetHit_Implementation(const FVector& ImpactPoint)
- {
- //DRAW_SPHERE_COLOR(ImpactPoint, FColor::Orange);
- if (HealthBarWidget)
- {
- HealthBarWidget->SetVisibility(true);
- }
- if (Attibutes && Attibutes->IsAlive())
- {
- DirectionalHitReact(ImpactPoint);
- }
- else
- {
- Die();
- }
- if (HitSound)
- {
- UGameplayStatics::PlaySoundAtLocation
- (
- this,
- HitSound,
- ImpactPoint
- );
- }
- if (HitParticles)
- {
- UGameplayStatics::SpawnEmitterAtLocation
- (
- GetWorld(),
- HitParticles,
- ImpactPoint
- );
- }
- }
- float AEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
- {
- //UE_LOG(LogTemp, Warning, TEXT("Attacking %s"), DamageCauser->GetFName());
- if (Attibutes && HealthBarWidget)
- {
- Attibutes->ReceiveDamage(DamageAmount);
- HealthBarWidget->SetHealthPercent(Attibutes->GetHealthPercent());
- }
- CombatTarget = EventInstigator->GetPawn();
- EnemyState = EEnemyState::EES_Chasing;
- GetCharacterMovement()->MaxWalkSpeed = 300.f;
- MoveToTarget(CombatTarget);
- return DamageAmount;
- }
- void AEnemy::Destroyed()
- {
- if (EquippedWeapon)
- {
- EquippedWeapon->Destroy();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement