#include "EnemySpaceship.h" #include "SpaceshipPawn.h" #include "SpaceshipProjectile.h" #include "Kismet/GameplayStatics.h" AEnemySpaceship::AEnemySpaceship() { PrimaryActorTick.bCanEverTick = true; ShipMesh = CreateDefaultSubobject(TEXT("ShipMesh")); RootComponent = ShipMesh; CurrentHealth = MaxHealth; } void AEnemySpaceship::BeginPlay() { Super::BeginPlay(); PlayerPawn = Cast(UGameplayStatics::GetPlayerPawn(GetWorld(), 0)); GetWorldTimerManager().SetTimer(FireTimerHandle, this, &AEnemySpaceship::FireAtPlayer, FireRate, true); } void AEnemySpaceship::Tick(float DeltaTime) { Super::Tick(DeltaTime); if (PlayerPawn) { // Calculate distance to player float DistanceToPlayer = FVector::Dist(GetActorLocation(), PlayerPawn->GetActorLocation()); if (DistanceToPlayer <= DetectionRange) { // Look at player FVector Direction = PlayerPawn->GetActorLocation() - GetActorLocation(); FRotator NewRotation = Direction.Rotation(); SetActorRotation(FMath::RInterpTo(GetActorRotation(), NewRotation, DeltaTime, 2.0f)); // Move towards player while maintaining some distance float TargetDistance = 1000.0f; if (DistanceToPlayer > TargetDistance) { FVector NewLocation = GetActorLocation() + (Direction.GetSafeNormal() * MovementSpeed * DeltaTime); SetActorLocation(NewLocation); } else if (DistanceToPlayer < TargetDistance - 100.0f) { FVector NewLocation = GetActorLocation() - (Direction.GetSafeNormal() * MovementSpeed * DeltaTime); SetActorLocation(NewLocation); } } } } void AEnemySpaceship::FireAtPlayer() { if (PlayerPawn && FVector::Dist(GetActorLocation(), PlayerPawn->GetActorLocation()) <= DetectionRange) { UWorld* World = GetWorld(); if (World) { FVector SpawnLocation = GetActorLocation() + (GetActorForwardVector() * 100.0f); FRotator SpawnRotation = GetActorRotation(); FActorSpawnParameters SpawnParams; SpawnParams.Owner = this; SpawnParams.Instigator = GetInstigator(); ASpaceshipProjectile* Projectile = World->SpawnActor( ASpaceshipProjectile::StaticClass(), SpawnLocation, SpawnRotation, SpawnParams ); } } } float AEnemySpaceship::TakeDamage(float Damage, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) { float ActualDamage = Super::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser); CurrentHealth -= ActualDamage; if (CurrentHealth <= 0) { // Destroy the enemy ship Destroy(); } return ActualDamage; }