Compare commits
20 Commits
894f7c60c4
...
Environmen
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e7712f0ac | |||
| 939e851c37 | |||
| 4b588e8667 | |||
| b815c07878 | |||
| df2a9520e4 | |||
| efce317da1 | |||
| 7653d26934 | |||
| 5ac7b648b9 | |||
| 561a9de8dd | |||
| 833edd7d8f | |||
| b3bbca282d | |||
| 482f386975 | |||
| 49895ec6a6 | |||
| 2519db2ced | |||
| 6fb1b648ec | |||
| 32365c408c | |||
| 4ee95ea366 | |||
| 536a938d55 | |||
| bb4d1bef59 | |||
| 07ed6f8876 |
@@ -6,4 +6,5 @@ bUseDistanceScaledCameraSpeed=True
|
|||||||
[ContentBrowser]
|
[ContentBrowser]
|
||||||
ContentBrowserTab1.SourcesExpanded=True
|
ContentBrowserTab1.SourcesExpanded=True
|
||||||
|
|
||||||
|
[/Script/AdvancedPreviewScene.SharedProfiles]
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ bOffsetPlayerGamepadIds=False
|
|||||||
GameInstanceClass=/Script/Engine.GameInstance
|
GameInstanceClass=/Script/Engine.GameInstance
|
||||||
GameDefaultMap=/Engine/Maps/Templates/OpenWorld.OpenWorld
|
GameDefaultMap=/Engine/Maps/Templates/OpenWorld.OpenWorld
|
||||||
ServerDefaultMap=/Engine/Maps/Entry.Entry
|
ServerDefaultMap=/Engine/Maps/Entry.Entry
|
||||||
GlobalDefaultGameMode=/Game/StarterContent/Blueprints/Deathmatch.Deathmatch_C
|
GlobalDefaultGameMode=/Game/Blueprints/BP_SpaceShooterGameMode.BP_SpaceShooterGameMode_C
|
||||||
GlobalDefaultServerGameMode=None
|
GlobalDefaultServerGameMode=None
|
||||||
|
|
||||||
[/Script/UnrealEd.UnrealEdEngine]
|
[/Script/UnrealEd.UnrealEdEngine]
|
||||||
@@ -148,3 +148,61 @@ ConnectionType=USBOnly
|
|||||||
bUseManualIPAddress=False
|
bUseManualIPAddress=False
|
||||||
ManualIPAddress=
|
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")
|
||||||
|
|
||||||
|
|||||||
BIN
Content/Blueprints/BP_EnemySpaceship.uasset
LFS
Normal file
BIN
Content/Blueprints/BP_EnemySpaceship.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Blueprints/BP_SpaceShooterGameMode.uasset
LFS
Normal file
BIN
Content/Blueprints/BP_SpaceShooterGameMode.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Blueprints/BP_SpaceshipPawn.uasset
LFS
Normal file
BIN
Content/Blueprints/BP_SpaceshipPawn.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Blueprints/BP_SpaceshipProjectile.uasset
LFS
Normal file
BIN
Content/Blueprints/BP_SpaceshipProjectile.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_Fire.uasset
LFS
Normal file
BIN
Content/Input/IA_Fire.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_MouseControl.uasset
LFS
Normal file
BIN
Content/Input/IA_MouseControl.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_MouseLook.uasset
LFS
Normal file
BIN
Content/Input/IA_MouseLook.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_Movement.uasset
LFS
Normal file
BIN
Content/Input/IA_Movement.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_Shoot.uasset
LFS
Normal file
BIN
Content/Input/IA_Shoot.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IA_Throttle.uasset
LFS
Normal file
BIN
Content/Input/IA_Throttle.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Input/IMC_Spaceship.uasset
LFS
Normal file
BIN
Content/Input/IMC_Spaceship.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Main.umap
LFS
BIN
Content/Main.umap
LFS
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_Blue.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_Blue.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_Green.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_Green.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_Grey.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_Grey.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_Purple.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_Purple.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_Red.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_Red.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Materials/M_StarSparrow_White.uasset
LFS
Normal file
BIN
Content/Materials/M_StarSparrow_White.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Meshes/SM_StarSparrow01.uasset
LFS
Normal file
BIN
Content/Meshes/SM_StarSparrow01.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Meshes/SM_StarSparrow02.uasset
LFS
Normal file
BIN
Content/Meshes/SM_StarSparrow02.uasset
LFS
Normal file
Binary file not shown.
20
README.md
20
README.md
@@ -1,4 +1,4 @@
|
|||||||
# Simulator Project
|
# Simulator Game Project
|
||||||
|
|
||||||
## Overview
|
## 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.
|
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,9 +7,8 @@ A spaceship simulator game developed in Unreal Engine 5, focusing on realistic p
|
|||||||
- Realistic zero-gravity space flight physics
|
- Realistic zero-gravity space flight physics
|
||||||
- Comprehensive power management system
|
- Comprehensive power management system
|
||||||
- Dynamic damage and shield mechanics
|
- Dynamic damage and shield mechanics
|
||||||
- Advanced navigation and autopilot capabilities
|
|
||||||
- Detailed ship systems simulation
|
- Detailed ship systems simulation
|
||||||
- Interactive cockpit and HUD
|
- Interactive HUD
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
- Unreal Engine 5.2 or higher
|
- Unreal Engine 5.2 or higher
|
||||||
@@ -22,7 +21,7 @@ A spaceship simulator game developed in Unreal Engine 5, focusing on realistic p
|
|||||||
### Installation
|
### Installation
|
||||||
1. Clone the repository:
|
1. Clone the repository:
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/YourUsername/SpaceshipSimulator.git
|
git clone https://git.cinis.cf/Ludusphere/Yamato.git
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Initialize and update Git LFS:
|
2. Initialize and update Git LFS:
|
||||||
@@ -38,13 +37,13 @@ git lfs pull
|
|||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
```
|
```
|
||||||
├── Config/ # Engine configuration
|
├── Config/ # Engine configuration
|
||||||
├── Content/
|
├── Content/
|
||||||
│ ├── Core/ # Base game systems
|
│ ├── Core/ # Base game systems
|
||||||
│ ├── Ships/ # Ship-related assets
|
│ ├── Ships/ # Ship-related assets
|
||||||
│ ├── Environment/ # Space environment
|
│ ├── Environment/ # Space environment
|
||||||
│ ├── UI/ # HUD and menus
|
│ ├── UI/ # HUD and menus
|
||||||
│ └── VFX/ # Visual effects
|
│ └── VFX/ # Visual effects
|
||||||
├── Source/ # C++ source code
|
├── Source/ # C++ source code
|
||||||
└── Documentation/ # Additional documentation
|
└── Documentation/ # Additional documentation
|
||||||
```
|
```
|
||||||
@@ -95,11 +94,8 @@ git checkout -b feature/your-feature-name
|
|||||||
5. Create a Pull Request
|
5. Create a Pull Request
|
||||||
|
|
||||||
## Project Team
|
## Project Team
|
||||||
- Person A: Core Systems Developer
|
- Aiden Correya: Core Systems Developer
|
||||||
- Person B: Content and Design Developer
|
- Shashank Kumar: Content and Design Developer
|
||||||
|
|
||||||
## License
|
|
||||||
- To be decided
|
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
- Unreal Engine
|
- Epic Games (Unreal Engine)
|
||||||
|
|||||||
78
Source/MyProject3/EnemySpaceship.cpp
Normal file
78
Source/MyProject3/EnemySpaceship.cpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#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();
|
||||||
|
}
|
||||||
40
Source/MyProject3/EnemySpaceship.h
Normal file
40
Source/MyProject3/EnemySpaceship.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#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();
|
||||||
|
};
|
||||||
99
Source/MyProject3/SpaceShooterGameMode.cpp
Normal file
99
Source/MyProject3/SpaceShooterGameMode.cpp
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
38
Source/MyProject3/SpaceShooterGameMode.h
Normal file
38
Source/MyProject3/SpaceShooterGameMode.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#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();
|
||||||
|
};
|
||||||
338
Source/MyProject3/SpaceshipPawn.cpp
Normal file
338
Source/MyProject3/SpaceshipPawn.cpp
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
111
Source/MyProject3/SpaceshipPawn.h
Normal file
111
Source/MyProject3/SpaceshipPawn.h
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#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();
|
||||||
|
};
|
||||||
75
Source/MyProject3/SpaceshipProjectile.cpp
Normal file
75
Source/MyProject3/SpaceshipProjectile.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#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();
|
||||||
|
}
|
||||||
33
Source/MyProject3/SpaceshipProjectile.h
Normal file
33
Source/MyProject3/SpaceshipProjectile.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#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