2 Commits

Author SHA1 Message Date
894f7c60c4 Modified Asteriod Movements 2025-02-17 14:14:51 +05:30
736a48476f Added Environment Assests 2025-02-17 14:04:50 +05:30
31 changed files with 15 additions and 939 deletions

View File

@@ -6,5 +6,4 @@ bUseDistanceScaledCameraSpeed=True
[ContentBrowser]
ContentBrowserTab1.SourcesExpanded=True
[/Script/AdvancedPreviewScene.SharedProfiles]

View File

@@ -64,7 +64,7 @@ bOffsetPlayerGamepadIds=False
GameInstanceClass=/Script/Engine.GameInstance
GameDefaultMap=/Engine/Maps/Templates/OpenWorld.OpenWorld
ServerDefaultMap=/Engine/Maps/Entry.Entry
GlobalDefaultGameMode=/Game/Blueprints/BP_SpaceShooterGameMode.BP_SpaceShooterGameMode_C
GlobalDefaultGameMode=/Game/StarterContent/Blueprints/Deathmatch.Deathmatch_C
GlobalDefaultServerGameMode=None
[/Script/UnrealEd.UnrealEdEngine]
@@ -148,61 +148,3 @@ ConnectionType=USBOnly
bUseManualIPAddress=False
ManualIPAddress=
[/Script/Engine.CollisionProfile]
-Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision",bCanModify=False)
-Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,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. ",bCanModify=False)
-Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,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. ",bCanModify=False)
-Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,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.",bCanModify=False)
-Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,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. ",bCanModify=False)
-Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ",bCanModify=False)
-Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic",Response=ECR_Block),(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.",bCanModify=False)
-Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,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.",bCanModify=False)
-Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors",bCanModify=False)
-Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors",bCanModify=False)
-Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.",bCanModify=False)
-Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.",bCanModify=False)
-Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,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.",bCanModify=False)
-Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,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.",bCanModify=False)
-Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.",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="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="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="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="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="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="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="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="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="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="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="Projectile",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Player",Response=ECR_Ignore)),HelpMessage="Needs description")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=False,bStaticObject=False,Name="Player")
-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
-ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
-ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
+ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
+ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
+ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
+ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
+ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
-CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
-CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
-CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
-CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
+CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
+CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
+CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
# Simulator Game Project
# Simulator Project
## Overview
A spaceship simulator game developed in Unreal Engine 5, focusing on realistic physics and comprehensive ship systems management. Players control a fully simulated spacecraft with integrated power, navigation, and damage systems.
@@ -7,8 +7,9 @@ A spaceship simulator game developed in Unreal Engine 5, focusing on realistic p
- Realistic zero-gravity space flight physics
- Comprehensive power management system
- Dynamic damage and shield mechanics
- Advanced navigation and autopilot capabilities
- Detailed ship systems simulation
- Interactive HUD
- Interactive cockpit and HUD
## Prerequisites
- Unreal Engine 5.2 or higher
@@ -21,7 +22,7 @@ A spaceship simulator game developed in Unreal Engine 5, focusing on realistic p
### Installation
1. Clone the repository:
```bash
git clone https://git.cinis.cf/Ludusphere/Yamato.git
git clone https://github.com/YourUsername/SpaceshipSimulator.git
```
2. Initialize and update Git LFS:
@@ -94,8 +95,11 @@ git checkout -b feature/your-feature-name
5. Create a Pull Request
## Project Team
- Aiden Correya: Core Systems Developer
- Shashank Kumar: Content and Design Developer
- Person A: Core Systems Developer
- Person B: Content and Design Developer
## License
- To be decided
## Acknowledgments
- Epic Games (Unreal Engine)
- Unreal Engine

View File

@@ -1,78 +0,0 @@
#include "EnemySpaceship.h"
#include "Kismet/GameplayStatics.h"
AEnemySpaceship::AEnemySpaceship()
{
PrimaryActorTick.bCanEverTick = true;
// Create and setup the enemy mesh
EnemyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("EnemyMesh"));
RootComponent = EnemyMesh;
// Disable gravity and physics simulation
EnemyMesh->SetSimulatePhysics(false);
EnemyMesh->SetEnableGravity(false);
// Set up collision for the enemy mesh
EnemyMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
EnemyMesh->SetCollisionObjectType(ECC_Pawn);
EnemyMesh->SetCollisionResponseToAllChannels(ECR_Block);
EnemyMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore); // Ignore other pawns
EnemyMesh->SetCollisionResponseToChannel(ECC_GameTraceChannel1, ECR_Ignore); // Ignore player
EnemyMesh->SetGenerateOverlapEvents(true);
}
void AEnemySpaceship::BeginPlay()
{
Super::BeginPlay();
// Find the player pawn
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
}
void AEnemySpaceship::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (PlayerPawn)
{
// Move towards the player
FVector Direction = (PlayerPawn->GetActorLocation() - GetActorLocation()).GetSafeNormal();
FVector NewLocation = GetActorLocation() + Direction * MovementSpeed * DeltaTime;
SetActorLocation(NewLocation);
// Face towards the player
FRotator NewRotation = Direction.Rotation();
SetActorRotation(NewRotation);
}
}
float AEnemySpaceship::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent,
AController* EventInstigator, AActor* DamageCauser)
{
float DamageToApply = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
CurrentHealth -= DamageToApply;
// Debug message
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red,
FString::Printf(TEXT("Enemy Health: %f"), CurrentHealth));
}
if (CurrentHealth <= 0)
{
Die();
}
return DamageToApply;
}
void AEnemySpaceship::Die()
{
// Add any death effects here
// Destroy the enemy
Destroy();
}

View File

@@ -1,40 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemySpaceship.generated.h"
UCLASS()
class MYPROJECT3_API AEnemySpaceship : public AActor
{
GENERATED_BODY()
public:
AEnemySpaceship();
protected:
virtual void BeginPlay() override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
UStaticMeshComponent* EnemyMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float MovementSpeed = 300.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
float MaxHealth = 100.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
float CurrentHealth = 100.0f;
public:
virtual void Tick(float DeltaTime) override;
// Override TakeDamage to handle damage taken
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent,
class AController* EventInstigator, AActor* DamageCauser) override;
private:
AActor* PlayerPawn;
void Die();
};

View File

@@ -1,99 +0,0 @@
#include "SpaceShooterGameMode.h"
#include "SpaceshipPawn.h"
#include "EnemySpaceship.h"
#include "Kismet/GameplayStatics.h"
ASpaceShooterGameMode::ASpaceShooterGameMode()
{
// Set default pawn class using the inherited DefaultPawnClass
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/Blueprints/BP_SpaceshipPawn"));
if (PlayerPawnBPClass.Class != nullptr)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
// Find enemy blueprint class
static ConstructorHelpers::FClassFinder<AEnemySpaceship> EnemyBPClass(TEXT("/Game/Blueprints/BP_EnemySpaceship"));
if (EnemyBPClass.Class != nullptr)
{
EnemyClass = EnemyBPClass.Class;
}
// Enable Tick()
PrimaryActorTick.bCanEverTick = true;
// Debug message
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("GameMode Constructor"));
}
}
void ASpaceShooterGameMode::StartPlay()
{
Super::StartPlay();
// Start spawning enemies
GetWorldTimerManager().SetTimer(EnemySpawnTimer, this, &ASpaceShooterGameMode::SpawnEnemy,
EnemySpawnInterval, true);
// Debug message
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("GameMode StartPlay"));
}
}
void ASpaceShooterGameMode::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ASpaceShooterGameMode::SpawnEnemy()
{
// Count current enemies
TArray<AActor*> FoundEnemies;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AEnemySpaceship::StaticClass(), FoundEnemies);
// Only spawn if we haven't reached the maximum
if (FoundEnemies.Num() < MaxEnemies)
{
UWorld* World = GetWorld();
if (World && EnemyClass)
{
FVector SpawnLocation = GetRandomSpawnLocation();
FRotator SpawnRotation = FRotator::ZeroRotator;
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
// Spawn using the Blueprint class instead of the C++ class directly
AEnemySpaceship* NewEnemy = World->SpawnActor<AEnemySpaceship>(EnemyClass, SpawnLocation,
SpawnRotation, SpawnParams);
}
}
}
FVector ASpaceShooterGameMode::GetRandomSpawnLocation()
{
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if (PlayerController && PlayerController->GetPawn())
{
FVector PlayerLocation = PlayerController->GetPawn()->GetActorLocation();
// Generate random angle
float Angle = FMath::RandRange(0.0f, 2.0f * PI);
// Generate random radius between min and max
float Radius = FMath::RandRange(MinSpawnRadius, MaxSpawnRadius);
// Calculate spawn position in a circle around the player
FVector SpawnLocation;
SpawnLocation.X = PlayerLocation.X + Radius * FMath::Cos(Angle);
SpawnLocation.Y = PlayerLocation.Y + Radius * FMath::Sin(Angle);
SpawnLocation.Z = PlayerLocation.Z;
return SpawnLocation;
}
return FVector::ZeroVector;
}

View File

@@ -1,38 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "SpaceShooterGameMode.generated.h"
UCLASS()
class MYPROJECT3_API ASpaceShooterGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ASpaceShooterGameMode();
virtual void StartPlay() override;
virtual void Tick(float DeltaTime) override;
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
TSubclassOf<class AEnemySpaceship> EnemyClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float EnemySpawnInterval = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
int32 MaxEnemies = 10;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float MinSpawnRadius = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float MaxSpawnRadius = 2000.0f;
private:
FTimerHandle EnemySpawnTimer;
void SpawnEnemy();
FVector GetRandomSpawnLocation();
};

View File

@@ -1,338 +0,0 @@
#include "SpaceshipPawn.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/StaticMeshComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "SpaceshipProjectile.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/GameUserSettings.h"
ASpaceshipPawn::ASpaceshipPawn()
{
PrimaryActorTick.bCanEverTick = true;
// Create ship mesh
ShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShipMesh"));
RootComponent = ShipMesh;
ShipMesh->SetSimulatePhysics(false);
ShipMesh->SetEnableGravity(false);
// Create projectile spawn point
ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("ProjectileSpawnPoint"));
ProjectileSpawnPoint->SetupAttachment(ShipMesh);
// Create camera spring arm
CameraSpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraSpringArm"));
CameraSpringArm->SetupAttachment(RootComponent);
CameraSpringArm->TargetArmLength = 400.0f;
CameraSpringArm->bEnableCameraLag = true;
CameraSpringArm->CameraLagSpeed = 10.0f;
CameraSpringArm->bEnableCameraRotationLag = true;
CameraSpringArm->CameraRotationLagSpeed = 10.0f;
CameraSpringArm->CameraLagMaxDistance = 7.0f;
CameraSpringArm->bUsePawnControlRotation = false; // Add this line
CameraSpringArm->bInheritPitch = true; // Add this line
CameraSpringArm->bInheritYaw = true; // Add this line
CameraSpringArm->bInheritRoll = false; // Add this line
// Create camera
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetupAttachment(CameraSpringArm, USpringArmComponent::SocketName);
// Initialize movement variables
CurrentThrust = 0.0f;
TargetThrust = 0.0f;
bThrottlePressed = false;
CurrentVelocity = FVector::ZeroVector;
CurrentPitch = 0.0f;
CurrentYaw = 0.0f;
TargetRotation = FRotator::ZeroRotator;
LastMouseDelta = FVector2D::ZeroVector;
if (ShipMesh)
{
ShipMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
ShipMesh->SetCollisionObjectType(ECC_GameTraceChannel1); // This is the "Player" channel
ShipMesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
ShipMesh->SetCollisionResponseToChannel(ECC_GameTraceChannel1, ECollisionResponse::ECR_Ignore);
ShipMesh->SetCollisionResponseToChannel(ECC_Pawn, ECollisionResponse::ECR_Ignore);
}
}
void ASpaceshipPawn::BeginPlay()
{
Super::BeginPlay();
// Debug messages for setup verification
if (GEngine)
{
if (ProjectileClass)
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("ProjectileClass is set"));
else
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("ProjectileClass is NOT set"));
if (ShootAction)
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("ShootAction is set"));
else
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("ShootAction is NOT set"));
if (ProjectileSpawnPoint)
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("ProjectileSpawnPoint is set"));
else
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("ProjectileSpawnPoint is NOT set"));
}
// Store player controller reference
PlayerControllerRef = Cast<APlayerController>(Controller);
if (PlayerControllerRef)
{
// Setup input mapping context
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerControllerRef->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
// Setup mouse capture and fullscreen
PlayerControllerRef->SetShowMouseCursor(false);
PlayerControllerRef->SetInputMode(FInputModeGameOnly());
// Request fullscreen mode using GameUserSettings
UGameUserSettings* GameUserSettings = UGameUserSettings::GetGameUserSettings();
if (GameUserSettings)
{
GameUserSettings->SetFullscreenMode(EWindowMode::Fullscreen);
GameUserSettings->SetScreenResolution(FIntPoint(1920, 1080)); // Adjust the resolution if needed
GameUserSettings->ApplySettings(false);
}
}
}
void ASpaceshipPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Debug info
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow,
FString::Printf(TEXT("Thrust: %.2f"), CurrentThrust));
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green,
FString::Printf(TEXT("Velocity: %.2f"), CurrentVelocity.Size()));
}
// Smooth mouse movement
MouseDeltaSmoothed = FMath::Vector2DInterpTo(
MouseDeltaSmoothed,
LastMouseDelta,
DeltaTime,
MouseSmoothingSpeed
);
// Update rotation based on smoothed mouse movement
CurrentYaw += MouseDeltaSmoothed.X * MouseSensitivity * DeltaTime * 60.0f; // Multiply by 60 to normalize for frame rate
CurrentPitch = FMath::ClampAngle(
CurrentPitch + (MouseDeltaSmoothed.Y * MouseSensitivity * DeltaTime * 60.0f),
-85.0f,
85.0f
);
// Set target rotation
TargetRotation = FRotator(CurrentPitch, CurrentYaw, 0.0f);
// Smoothly interpolate to target rotation using quaternions for better interpolation
FQuat CurrentQuat = GetActorQuat();
FQuat TargetQuat = TargetRotation.Quaternion();
FQuat NewQuat = FQuat::Slerp(CurrentQuat, TargetQuat, RotationSpeed * DeltaTime);
SetActorRotation(NewQuat);
// Get the current forward vector
FVector CurrentDirection = GetActorForwardVector();
float CurrentSpeed = CurrentVelocity.Size();
// Handle thrust and velocity direction
if (!bThrottlePressed)
{
// Decelerate when not thrusting
CurrentThrust = FMath::FInterpTo(CurrentThrust, 0.0f, DeltaTime, ThrustDeceleration);
bWasThrottlePressed = false;
// Maintain current velocity direction when not thrusting
DesiredVelocityDirection = CurrentVelocity.GetSafeNormal();
}
else
{
// Accelerate when thrusting
CurrentThrust = FMath::FInterpConstantTo(CurrentThrust, TargetThrust, DeltaTime, ThrustAcceleration);
if (!bWasThrottlePressed)
{
// Just started thrusting - blend between current and new direction
if (!CurrentVelocity.IsNearlyZero())
{
// Blend between current velocity direction and new direction
FVector CurrentDir = CurrentVelocity.GetSafeNormal();
DesiredVelocityDirection = FMath::Lerp(CurrentDir, CurrentDirection, 1.0f - DirectionalInertia);
DesiredVelocityDirection.Normalize();
}
else
{
// If nearly stationary, use new direction
DesiredVelocityDirection = CurrentDirection;
}
}
else
{
// Continuously blend towards current facing direction while thrusting
DesiredVelocityDirection = FMath::VInterpNormalRotationTo(
DesiredVelocityDirection,
CurrentDirection,
DeltaTime,
VelocityAlignmentSpeed
);
}
bWasThrottlePressed = true;
}
// Calculate thrust force
FVector ThrustForce = CurrentDirection * CurrentThrust;
// Apply drag
FVector DragForce = -CurrentVelocity * DragCoefficient;
// Update velocity with forces
CurrentVelocity += (ThrustForce + DragForce) * DeltaTime;
// Update position
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation, true);
// Update spring arm rotation to match ship with smooth interpolation
if (CameraSpringArm)
{
FRotator SpringArmRotation = CameraSpringArm->GetComponentRotation();
FRotator TargetSpringArmRotation = NewQuat.Rotator();
FRotator NewSpringArmRotation = FMath::RInterpTo(
SpringArmRotation,
TargetSpringArmRotation,
DeltaTime,
RotationSpeed
);
CameraSpringArm->SetWorldRotation(NewSpringArmRotation);
}
// Reset mouse delta for next frame
LastMouseDelta = FVector2D::ZeroVector;
// Debug info
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow,
FString::Printf(TEXT("Smoothed Mouse Delta: X=%.2f Y=%.2f"), MouseDeltaSmoothed.X, MouseDeltaSmoothed.Y));
GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green,
FString::Printf(TEXT("Current Rotation: P=%.2f Y=%.2f"), CurrentPitch, CurrentYaw));
}
}
void ASpaceshipPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
// Bind both Hold and Released events for throttle
EnhancedInputComponent->BindAction(ThrottleAction, ETriggerEvent::Started, this, &ASpaceshipPawn::HandleThrottleStarted);
EnhancedInputComponent->BindAction(ThrottleAction, ETriggerEvent::Completed, this, &ASpaceshipPawn::HandleThrottleReleased);
// Bind mouse control
EnhancedInputComponent->BindAction(MouseLookAction, ETriggerEvent::Triggered, this, &ASpaceshipPawn::HandleMouseLook);
// Add shooting binding
EnhancedInputComponent->BindAction(ShootAction, ETriggerEvent::Triggered, this, &ASpaceshipPawn::HandleShoot);
}
}
// Split the throttle handling into two functions
void ASpaceshipPawn::HandleThrottleStarted(const FInputActionValue& Value)
{
const float ThrottleValue = Value.Get<float>();
bThrottlePressed = true;
TargetThrust = ThrottleValue * MaxThrust;
}
void ASpaceshipPawn::HandleThrottleReleased(const FInputActionValue& Value)
{
bThrottlePressed = false;
}
void ASpaceshipPawn::HandleMouseLook(const FInputActionValue& Value)
{
const FVector2D MouseDelta = Value.Get<FVector2D>();
// Smoothly interpolate mouse delta
LastMouseDelta = MouseDelta;
}
void ASpaceshipPawn::HandleShoot(const FInputActionValue& Value)
{
// Debug message
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Yellow, TEXT("HandleShoot Called"));
if (bCanFire)
{
Fire();
}
}
void ASpaceshipPawn::Fire()
{
// Debug messages
if (!ProjectileClass)
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, TEXT("ProjectileClass not set!"));
return;
}
UWorld* World = GetWorld();
if (World)
{
FVector SpawnLocation = ProjectileSpawnPoint->GetComponentLocation();
FRotator SpawnRotation = GetActorRotation();
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator();
// Spawn the projectile
ASpaceshipProjectile* Projectile = World->SpawnActor<ASpaceshipProjectile>(
ProjectileClass,
SpawnLocation,
SpawnRotation,
SpawnParams
);
if (Projectile)
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Green, TEXT("Projectile Spawned"));
}
else
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, TEXT("Failed to spawn projectile"));
}
// Start fire rate timer
bCanFire = false;
GetWorldTimerManager().SetTimer(FireTimerHandle, this, &ASpaceshipPawn::ResetFire, FireRate, false);
}
}
void ASpaceshipPawn::ResetFire()
{
bCanFire = true;
}

View File

@@ -1,111 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "InputActionValue.h"
#include "SpaceshipPawn.generated.h"
UCLASS()
class MYPROJECT3_API ASpaceshipPawn : public APawn
{
GENERATED_BODY()
public:
ASpaceshipPawn();
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
protected:
virtual void BeginPlay() override;
// Components
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
class UStaticMeshComponent* ShipMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
class USpringArmComponent* CameraSpringArm;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
class UCameraComponent* Camera;
// Enhanced Input Components
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
class UInputMappingContext* DefaultMappingContext;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
class UInputAction* ThrottleAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
class UInputAction* MouseLookAction;
// Movement Parameters
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float MaxThrust = 2000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float ThrustAcceleration = 500.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float ThrustDeceleration = 500.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float RotationSpeed = 100.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float MouseSensitivity = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement")
float DragCoefficient = 0.05f;
// How quickly velocity aligns with new direction
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement", meta = (ClampMin = "0.0", ClampMax = "10.0"))
float VelocityAlignmentSpeed = 4.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement", meta = (ClampMin = "0.0", ClampMax = "1.0", ToolTip = "How much of the current velocity is maintained when changing direction (0 = none, 1 = full)"))
float DirectionalInertia = 0.3f;
// Shooting properties
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
TSubclassOf<class ASpaceshipProjectile> ProjectileClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
float FireRate = 0.2f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
USceneComponent* ProjectileSpawnPoint;
// Input action for shooting
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
class UInputAction* ShootAction;
// Input functions
void HandleThrottleStarted(const FInputActionValue& Value);
void HandleThrottleReleased(const FInputActionValue& Value);
void HandleMouseLook(const FInputActionValue& Value);
private:
// Movement state
float CurrentThrust;
float TargetThrust;
bool bThrottlePressed;
FVector CurrentVelocity;
FRotator TargetRotation;
float CurrentPitch;
float CurrentYaw;
APlayerController* PlayerControllerRef;
FVector2D MouseDeltaSmoothed;
FVector2D LastMouseDelta;
float MouseSmoothingSpeed = 10.0f;
bool bWasThrottlePressed;
FVector DesiredVelocityDirection;
FTimerHandle FireTimerHandle;
bool bCanFire = true;
void HandleShoot(const FInputActionValue& Value);
void Fire();
void ResetFire();
};

View File

@@ -1,75 +0,0 @@
#include "SpaceshipProjectile.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Components/StaticMeshComponent.h"
#include "EnemySpaceship.h"
ASpaceshipProjectile::ASpaceshipProjectile()
{
PrimaryActorTick.bCanEverTick = true;
// Create and setup the projectile mesh
ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileMesh"));
RootComponent = ProjectileMesh;
ProjectileMesh->SetCollisionProfileName(TEXT("Projectile"));
ProjectileMesh->OnComponentHit.AddDynamic(this, &ASpaceshipProjectile::OnHit);
// Set up collision
ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
ProjectileMesh->SetCollisionObjectType(ECC_WorldDynamic);
ProjectileMesh->SetCollisionResponseToAllChannels(ECR_Ignore);
ProjectileMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block); // Block pawns (enemies)
ProjectileMesh->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); // Block world static
ProjectileMesh->SetGenerateOverlapEvents(true);
// Bind hit event
ProjectileMesh->OnComponentHit.AddDynamic(this, &ASpaceshipProjectile::OnHit);
// Create and setup projectile movement
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovement"));
ProjectileMovement->UpdatedComponent = ProjectileMesh;
ProjectileMovement->InitialSpeed = ProjectileSpeed;
ProjectileMovement->MaxSpeed = ProjectileSpeed;
ProjectileMovement->bRotationFollowsVelocity = true;
ProjectileMovement->ProjectileGravityScale = 0.0f;
// Set lifetime
InitialLifeSpan = 3.0f;
}
void ASpaceshipProjectile::BeginPlay()
{
Super::BeginPlay();
}
void ASpaceshipProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
FVector NormalImpulse, const FHitResult& Hit)
{
// Debug message to verify hit detection
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Yellow,
FString::Printf(TEXT("Projectile hit: %s"), *OtherActor->GetName()));
}
if (OtherActor && OtherActor != this)
{
// Check if we hit an enemy
AEnemySpaceship* Enemy = Cast<AEnemySpaceship>(OtherActor);
if (Enemy)
{
// Apply damage
FDamageEvent DamageEvent;
Enemy->TakeDamage(DamageAmount, DamageEvent, nullptr, this);
// Debug message for damage
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red,
FString::Printf(TEXT("Dealt %f damage to enemy"), DamageAmount));
}
}
}
// Destroy the projectile
Destroy();
}

View File

@@ -1,33 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SpaceshipProjectile.generated.h"
UCLASS()
class MYPROJECT3_API ASpaceshipProjectile : public AActor
{
GENERATED_BODY()
public:
ASpaceshipProjectile();
protected:
virtual void BeginPlay() override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
class UStaticMeshComponent* ProjectileMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
class UProjectileMovementComponent* ProjectileMovement;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
float ProjectileSpeed = 3000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
float DamageAmount = 20.0f;
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,
FVector NormalImpulse, const FHitResult& Hit);
};