Compare commits
2 Commits
Environmen
...
894f7c60c4
| Author | SHA1 | Date | |
|---|---|---|---|
| 894f7c60c4 | |||
| 736a48476f |
@@ -6,5 +6,4 @@ bUseDistanceScaledCameraSpeed=True
|
||||
[ContentBrowser]
|
||||
ContentBrowserTab1.SourcesExpanded=True
|
||||
|
||||
[/Script/AdvancedPreviewScene.SharedProfiles]
|
||||
|
||||
|
||||
@@ -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.
BIN
Content/Input/IA_Fire.uasset
LFS
BIN
Content/Input/IA_Fire.uasset
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Input/IA_Movement.uasset
LFS
BIN
Content/Input/IA_Movement.uasset
LFS
Binary file not shown.
BIN
Content/Input/IA_Shoot.uasset
LFS
BIN
Content/Input/IA_Shoot.uasset
LFS
Binary file not shown.
BIN
Content/Input/IA_Throttle.uasset
LFS
BIN
Content/Input/IA_Throttle.uasset
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Main.umap
LFS
BIN
Content/Main.umap
LFS
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.
16
README.md
16
README.md
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
Reference in New Issue
Block a user