From 741a41ddfaf5b7313111ce239a6ca0a5fbfebe73 Mon Sep 17 00:00:00 2001 From: baz Date: Mon, 13 Jan 2025 20:57:08 +0000 Subject: [PATCH] Make projectiles pooled and use DataAssets --- Content/Gamemode/BP_DefaultGamemode.uasset | 4 +- Content/Levels/Level.umap | 4 +- Content/Pickups/C_Pickup.uasset | 4 +- Content/Pickups/DA_ExamplePickup.uasset | 3 + Content/Player/BP_PlayerCharacter.uasset | 4 +- Content/Weapons/BP_ExampleWeapon.uasset | 4 +- Content/Weapons/DA_ExampleWeapon.uasset | 3 + .../Weapons/FireWand/BP_FireWandWeapon.uasset | 4 +- Content/Weapons/Garlic/BP_GarlicWeapon.uasset | 4 +- Content/Weapons/Knife/BP_KnifeWeapon.uasset | 4 +- .../MagicWand/BP_MagicWandProjectile.uasset | 4 +- .../MagicWand/BP_MagicWandWeapon.uasset | 4 +- .../BP_PhieraDerTuphelloWeapon.uasset | 4 +- .../Weapons/TestProjectileDataAsset.uasset | 3 + Source/vampires/Interfaces/Pools.cpp | 7 ++ Source/vampires/Interfaces/Pools.h | 31 +++++++ Source/vampires/Interfaces/Projectilable.cpp | 7 ++ Source/vampires/Interfaces/Projectilable.h | 34 +++++++ Source/vampires/Pickup.h | 23 +++-- Source/vampires/PickupDataAsset.cpp | 4 + Source/vampires/PickupDataAsset.h | 37 ++++++++ Source/vampires/Projectile.cpp | 58 ++++++++++-- Source/vampires/Projectile.h | 24 +++-- Source/vampires/ProjectileDataAsset.cpp | 4 + Source/vampires/ProjectileDataAsset.h | 23 +++++ Source/vampires/VampireGameMode.cpp | 20 +++- Source/vampires/VampireGameMode.h | 15 ++- Source/vampires/Weapon.h | 6 +- Source/vampires/Weapons/FireWandWeapon.cpp | 42 ++++++--- Source/vampires/Weapons/GunWeapon.cpp | 91 +++++++++++-------- Source/vampires/Weapons/GunWeapon.h | 3 + Source/vampires/Weapons/KnifeWeapon.cpp | 35 ++++--- Source/vampires/Weapons/MagicWandWeapon.cpp | 39 +++++--- Source/vampires/Weapons/ProjectileWeapon.h | 3 +- Source/vampires/Weapons/WeaponDataAsset.cpp | 4 + Source/vampires/Weapons/WeaponDataAsset.h | 50 ++++++++++ 36 files changed, 480 insertions(+), 133 deletions(-) create mode 100644 Content/Pickups/DA_ExamplePickup.uasset create mode 100644 Content/Weapons/DA_ExampleWeapon.uasset create mode 100644 Content/Weapons/TestProjectileDataAsset.uasset create mode 100644 Source/vampires/Interfaces/Pools.cpp create mode 100644 Source/vampires/Interfaces/Pools.h create mode 100644 Source/vampires/Interfaces/Projectilable.cpp create mode 100644 Source/vampires/Interfaces/Projectilable.h create mode 100644 Source/vampires/PickupDataAsset.cpp create mode 100644 Source/vampires/PickupDataAsset.h create mode 100644 Source/vampires/ProjectileDataAsset.cpp create mode 100644 Source/vampires/ProjectileDataAsset.h create mode 100644 Source/vampires/Weapons/WeaponDataAsset.cpp create mode 100644 Source/vampires/Weapons/WeaponDataAsset.h diff --git a/Content/Gamemode/BP_DefaultGamemode.uasset b/Content/Gamemode/BP_DefaultGamemode.uasset index 82d5e9b..2463e90 100644 --- a/Content/Gamemode/BP_DefaultGamemode.uasset +++ b/Content/Gamemode/BP_DefaultGamemode.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94e59ead95ffb4f9a230fa05df1e608852c96e459d1caea091b031156997e65d -size 21323 +oid sha256:8563c5c397f458b5cde8f1aebd6df3521c8428b35952b2bcc67ce568a8b5d4e7 +size 21547 diff --git a/Content/Levels/Level.umap b/Content/Levels/Level.umap index 3715dc2..1159ea9 100644 --- a/Content/Levels/Level.umap +++ b/Content/Levels/Level.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57e9809df71dd8a6f84d3a3c805b3efb9664dfd975b7175455f202e1d9448e91 -size 67999 +oid sha256:8aee1ba236c4179bace48821443f423d8f2b167ba1002e02f5356ac3a67b67c7 +size 66870 diff --git a/Content/Pickups/C_Pickup.uasset b/Content/Pickups/C_Pickup.uasset index f358659..2987145 100644 --- a/Content/Pickups/C_Pickup.uasset +++ b/Content/Pickups/C_Pickup.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb85e03bcb86bb75675d2749393b043578e765b1cdbac01b53d1e06c1efcebb0 -size 4936 +oid sha256:28a6599953024b26503b69219cf94d39e2ba082a833b9b5f8d202cd03be92970 +size 5054 diff --git a/Content/Pickups/DA_ExamplePickup.uasset b/Content/Pickups/DA_ExamplePickup.uasset new file mode 100644 index 0000000..a6e47a5 --- /dev/null +++ b/Content/Pickups/DA_ExamplePickup.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f82338f6fa94772627aa1c7dec9185be1e730dcfedd942af6ea05ddc9f7d4ee3 +size 1372 diff --git a/Content/Player/BP_PlayerCharacter.uasset b/Content/Player/BP_PlayerCharacter.uasset index ad5b78e..fde2c69 100644 --- a/Content/Player/BP_PlayerCharacter.uasset +++ b/Content/Player/BP_PlayerCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f478120b4647e5fc9969295ba4cad8cb7d586111cbb4650cb58a54f469e5b29 -size 53379 +oid sha256:dcd559a09fd6529bc6fc696b9bd5bedf07764aff8a9d625981a9b35fa19613cf +size 53468 diff --git a/Content/Weapons/BP_ExampleWeapon.uasset b/Content/Weapons/BP_ExampleWeapon.uasset index 92dda7b..ff05d93 100644 --- a/Content/Weapons/BP_ExampleWeapon.uasset +++ b/Content/Weapons/BP_ExampleWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28701ef93e62244d2ff09ec921709ada9a8f58e15a687efb29a85a373fede1dc -size 26156 +oid sha256:7e582f0ba7d3759a083ded8672a6440c7e45b1583a60f081c461b57967a99505 +size 23774 diff --git a/Content/Weapons/DA_ExampleWeapon.uasset b/Content/Weapons/DA_ExampleWeapon.uasset new file mode 100644 index 0000000..227c151 --- /dev/null +++ b/Content/Weapons/DA_ExampleWeapon.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60f21d7e88b0949d2cc050358268c4a948e557ae240f447102cb43a275fab848 +size 1372 diff --git a/Content/Weapons/FireWand/BP_FireWandWeapon.uasset b/Content/Weapons/FireWand/BP_FireWandWeapon.uasset index 046fd15..b2dc8d0 100644 --- a/Content/Weapons/FireWand/BP_FireWandWeapon.uasset +++ b/Content/Weapons/FireWand/BP_FireWandWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:943b78e4be7f7ac8bb53898027ccc2d2146d4c2c75e9a8cd273b7f3d9d7378f8 -size 24017 +oid sha256:e64a0d18d7a13219d78e8bd814ef6666c42540970dce210c28c84cfdb0edff96 +size 23725 diff --git a/Content/Weapons/Garlic/BP_GarlicWeapon.uasset b/Content/Weapons/Garlic/BP_GarlicWeapon.uasset index aa22eb6..f6cf90f 100644 --- a/Content/Weapons/Garlic/BP_GarlicWeapon.uasset +++ b/Content/Weapons/Garlic/BP_GarlicWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec04a3f6e9b16f1f01dfea2ad5b85633f3b0314f2b69ffff3021f663b1eeb063 -size 22992 +oid sha256:94c9616a6d058483bbcf98680ac21d312ba7d60916afb778878e77f2183648fd +size 23370 diff --git a/Content/Weapons/Knife/BP_KnifeWeapon.uasset b/Content/Weapons/Knife/BP_KnifeWeapon.uasset index 0688269..8183ac4 100644 --- a/Content/Weapons/Knife/BP_KnifeWeapon.uasset +++ b/Content/Weapons/Knife/BP_KnifeWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bc215712fb409b6ce7212c817b472cc7d67d09c215717e9fe56275811b69f77 -size 23904 +oid sha256:9e12e220e099360a33df42183f2c0d5f9201d234094a7369c8f15bdb1a6d88f0 +size 23612 diff --git a/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset b/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset index a3dae4f..0a9a550 100644 --- a/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset +++ b/Content/Weapons/MagicWand/BP_MagicWandProjectile.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eaa8647597a45cde00d8ad66e0a4a119835ac76a9112f808ddf6bb62dc59a5d2 -size 30952 +oid sha256:2f8809a6fcba494cd880a6d71881d9b298e573ee7e7b180832e3c304f6beb111 +size 33337 diff --git a/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset b/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset index 7b729cb..3bef405 100644 --- a/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset +++ b/Content/Weapons/MagicWand/BP_MagicWandWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bb764c15d2edb74f0894c6b51ff18114b333f3a0dfb3877cdcb79463b1ac1f3 -size 24084 +oid sha256:f6d239489ee4ab4a06e8dab397936b6d135249ce696aae7d1379b9d536f4b940 +size 23792 diff --git a/Content/Weapons/PhieraDerTuphello/BP_PhieraDerTuphelloWeapon.uasset b/Content/Weapons/PhieraDerTuphello/BP_PhieraDerTuphelloWeapon.uasset index 1da2ed3..75d1e36 100644 --- a/Content/Weapons/PhieraDerTuphello/BP_PhieraDerTuphelloWeapon.uasset +++ b/Content/Weapons/PhieraDerTuphello/BP_PhieraDerTuphelloWeapon.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c6a7ab728482871de79a5bc7c079f9fa525ea2348b1c12e69f4b0fea8ce9f52 -size 24212 +oid sha256:f62b5620daf880504b986fd9d796f23686c2fae0c5d4ca7950ecf73073d8953e +size 23920 diff --git a/Content/Weapons/TestProjectileDataAsset.uasset b/Content/Weapons/TestProjectileDataAsset.uasset new file mode 100644 index 0000000..432342b --- /dev/null +++ b/Content/Weapons/TestProjectileDataAsset.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06a1036c0c310ca0212845b11d3f725471597793cee31e5508f6c8a7d4f3028a +size 1647 diff --git a/Source/vampires/Interfaces/Pools.cpp b/Source/vampires/Interfaces/Pools.cpp new file mode 100644 index 0000000..adaf537 --- /dev/null +++ b/Source/vampires/Interfaces/Pools.cpp @@ -0,0 +1,7 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Pools.h" + + +// Add default functionality here for any IPools functions that are not pure virtual. diff --git a/Source/vampires/Interfaces/Pools.h b/Source/vampires/Interfaces/Pools.h new file mode 100644 index 0000000..bc99e61 --- /dev/null +++ b/Source/vampires/Interfaces/Pools.h @@ -0,0 +1,31 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Interface.h" +#include "Pools.generated.h" + +class AObjectPoolManager; +// This class does not need to be modified. +UINTERFACE() +class UPools : public UInterface +{ + GENERATED_BODY() +}; + +/** + * + */ +class VAMPIRES_API IPools +{ + GENERATED_BODY() + + // Add interface functions to this class. This is the class that will be inherited to implement this interface. +public: + UFUNCTION(BlueprintNativeEvent) + AObjectPoolManager* GetEnemyObjectPoolManager(); + + UFUNCTION(BlueprintNativeEvent) + AObjectPoolManager* GetProjectileObjectPoolManager(); +}; diff --git a/Source/vampires/Interfaces/Projectilable.cpp b/Source/vampires/Interfaces/Projectilable.cpp new file mode 100644 index 0000000..379ece4 --- /dev/null +++ b/Source/vampires/Interfaces/Projectilable.cpp @@ -0,0 +1,7 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Projectilable.h" + + +// Add default functionality here for any IProjectilable functions that are not pure virtual. diff --git a/Source/vampires/Interfaces/Projectilable.h b/Source/vampires/Interfaces/Projectilable.h new file mode 100644 index 0000000..bad1621 --- /dev/null +++ b/Source/vampires/Interfaces/Projectilable.h @@ -0,0 +1,34 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Interface.h" +#include "Projectilable.generated.h" + +class UProjectileDataAsset; +// This class does not need to be modified. +UINTERFACE() +class UProjectilable : public UInterface +{ + GENERATED_BODY() +}; + +/** + * + */ +class VAMPIRES_API IProjectilable +{ + GENERATED_BODY() + + // Add interface functions to this class. This is the class that will be inherited to implement this interface. +public: + UFUNCTION(BlueprintNativeEvent) + void LoadDataFromDataAsset(UProjectileDataAsset* projectileDataAsset); + + UFUNCTION(BlueprintNativeEvent) + void ResetData(); + + UFUNCTION(BlueprintNativeEvent) + void SetTargetDirection(FVector direction); +}; diff --git a/Source/vampires/Pickup.h b/Source/vampires/Pickup.h index 078f5d7..f8973bb 100644 --- a/Source/vampires/Pickup.h +++ b/Source/vampires/Pickup.h @@ -7,6 +7,7 @@ #include "GameFramework/Actor.h" #include "Pickup.generated.h" +class UPickupDataAsset; class UTimelineComponent; class USphereComponent; class UPaperSpriteComponent; @@ -17,19 +18,21 @@ class VAMPIRES_API APickup : public AActor GENERATED_BODY() public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) + TObjectPtr PickupDataAsset; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) double PickupMovementRange = 500; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) double PickupMovementSpeed = 1000; - + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) USphereComponent* InnerSphereComponent = nullptr; - + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) USphereComponent* OuterSphereComponent = nullptr; - + UPROPERTY(EditAnywhere) UPaperSpriteComponent* SpriteComponent = nullptr; @@ -47,8 +50,8 @@ private: FOnTimelineEventStatic onTimelineFinishedCallback; FVector PickupLocation; - -public: + +public: // Sets default values for this actor's properties APickup(); @@ -58,13 +61,13 @@ protected: UFUNCTION() virtual void OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, - UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, - const FHitResult& SweepResult); - + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult); + UFUNCTION() virtual void OnOuterBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, - UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, - const FHitResult& SweepResult); + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult); UFUNCTION() void TimelineCallback(float val); diff --git a/Source/vampires/PickupDataAsset.cpp b/Source/vampires/PickupDataAsset.cpp new file mode 100644 index 0000000..07a4748 --- /dev/null +++ b/Source/vampires/PickupDataAsset.cpp @@ -0,0 +1,4 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "PickupDataAsset.h" diff --git a/Source/vampires/PickupDataAsset.h b/Source/vampires/PickupDataAsset.h new file mode 100644 index 0000000..7e699c1 --- /dev/null +++ b/Source/vampires/PickupDataAsset.h @@ -0,0 +1,37 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/DataAsset.h" +#include "PickupDataAsset.generated.h" + +class UTimelineComponent; +class UPaperSprite; +/** + * + */ +UCLASS(BlueprintType) +class VAMPIRES_API UPickupDataAsset : public UDataAsset +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + int PickupValue = 1; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + double PickupMovementRange = 500; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + double PickupMovementSpeed = 1000; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + TObjectPtr WeaponSprite = nullptr; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + TObjectPtr PickupSoundBase = nullptr; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") + TObjectPtr CurveFloat = nullptr; +}; diff --git a/Source/vampires/Projectile.cpp b/Source/vampires/Projectile.cpp index 15dc3ba..28a3fe8 100644 --- a/Source/vampires/Projectile.cpp +++ b/Source/vampires/Projectile.cpp @@ -4,8 +4,13 @@ #include "Projectile.h" #include "EnemyCharacter.h" +#include "ObjectPoolManager.h" +#include "ProjectileDataAsset.h" #include "Components/SphereComponent.h" +#include "GameFramework/GameModeBase.h" #include "GameFramework/ProjectileMovementComponent.h" +#include "Interfaces/Pools.h" +#include "Kismet/GameplayStatics.h" #include "Weapons/ProjectileWeapon.h" // Sets default values @@ -19,22 +24,55 @@ AProjectile::AProjectile() ProjectileMovement->ProjectileGravityScale = 0.0f; ProjectileMovement->Friction = 0.0f; ProjectileMovement->bIsSliding = true; + ProjectileMovement->InitialSpeed = 0; + ProjectileMovement->MaxSpeed = 0; + + StaticMeshComponent = CreateDefaultSubobject(TEXT("Static Mesh Component")); + StaticMeshComponent->AttachToComponent(SphereComponent, FAttachmentTransformRules::KeepRelativeTransform); + StaticMeshComponent->SetEnableGravity(false); + StaticMeshComponent->SetGenerateOverlapEvents(false); + StaticMeshComponent->SetCollisionProfileName(TEXT("NoCollision")); } // Called when the game starts or when spawned void AProjectile::BeginPlay() { Super::BeginPlay(); - + SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &AProjectile::OnProjectileBeginOverlap); +} + +void AProjectile::SetActorHiddenInGame(bool bNewHidden) +{ + Super::SetActorHiddenInGame(bNewHidden); + + if (bNewHidden) + { + ResetData_Implementation(); + } +} + +void AProjectile::SetTargetDirection_Implementation(FVector direction) +{ + SetActorLocation(UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetCharacter()->GetActorLocation()); + SetActorRotation(FRotator(0, 0, 0)); + TargetDirection = direction; + ProjectileMovement->SetVelocityInLocalSpace(TargetDirection * ProjectileSpeed); +} + +void AProjectile::LoadDataFromDataAsset_Implementation(UProjectileDataAsset* projectileDataAsset) +{ + ProjectileSpeed = projectileDataAsset->ProjectileSpeed; + StaticMeshComponent->SetStaticMesh(projectileDataAsset->StaticMesh); + ProjectileSpeed = projectileDataAsset->ProjectileSpeed; ProjectileMovement->InitialSpeed = ProjectileSpeed; ProjectileMovement->MaxSpeed = ProjectileSpeed; } -void AProjectile::SetTargetDirection(FVector direction) +void AProjectile::ResetData_Implementation() { - TargetDirection = direction; - ProjectileMovement->SetVelocityInLocalSpace(TargetDirection * ProjectileSpeed); + ProjectileSpeed = NULL; + StaticMeshComponent->SetStaticMesh(nullptr); } void AProjectile::OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, @@ -52,11 +90,19 @@ void AProjectile::OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedCompon { ownerController = character->GetController(); } - + AProjectileWeapon* ownerWeapon = Cast(GetOwner()); EnemyHealthComponent->TakeDamage(Enemy, ownerWeapon->Damage, nullptr, ownerController, this); - OverlappedComponent->GetAttachmentRootActor()->Destroy(); + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); + + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + objectPoolManager->ReturnObject(this); + } + } } } } diff --git a/Source/vampires/Projectile.h b/Source/vampires/Projectile.h index 7699976..4c1e42e 100644 --- a/Source/vampires/Projectile.h +++ b/Source/vampires/Projectile.h @@ -4,13 +4,15 @@ #include "CoreMinimal.h" #include "GameFramework/Actor.h" +#include "Interfaces/Projectilable.h" #include "Projectile.generated.h" class UProjectileMovementComponent; class USphereComponent; +class UProjectileDataAsset; UCLASS() -class VAMPIRES_API AProjectile : public AActor +class VAMPIRES_API AProjectile : public AActor, public IProjectilable { GENERATED_BODY() @@ -20,13 +22,15 @@ public: UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) UProjectileMovementComponent* ProjectileMovement = nullptr; - + FVector TargetDirection = FVector::ZeroVector; UPROPERTY(EditAnywhere, BlueprintReadWrite) float ProjectileSpeed = 500.0f; - -public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + UStaticMeshComponent* StaticMeshComponent = nullptr; + // Sets default values for this actor's properties AProjectile(); @@ -34,12 +38,18 @@ protected: // Called when the game starts or when spawned virtual void BeginPlay() override; -public: +public: + virtual void SetActorHiddenInGame(bool bNewHidden) override; - void SetTargetDirection(FVector direction); + virtual void SetTargetDirection_Implementation(FVector direction) override; + + virtual void LoadDataFromDataAsset_Implementation(UProjectileDataAsset* projectileDataAsset) override; + + virtual void ResetData_Implementation() override; private: UFUNCTION() void OnProjectileBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, - UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, + const FHitResult& SweepResult); }; diff --git a/Source/vampires/ProjectileDataAsset.cpp b/Source/vampires/ProjectileDataAsset.cpp new file mode 100644 index 0000000..0aaefed --- /dev/null +++ b/Source/vampires/ProjectileDataAsset.cpp @@ -0,0 +1,4 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "ProjectileDataAsset.h" diff --git a/Source/vampires/ProjectileDataAsset.h b/Source/vampires/ProjectileDataAsset.h new file mode 100644 index 0000000..263caa6 --- /dev/null +++ b/Source/vampires/ProjectileDataAsset.h @@ -0,0 +1,23 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/DataAsset.h" +#include "ProjectileDataAsset.generated.h" + +/** + * + */ +UCLASS() +class VAMPIRES_API UProjectileDataAsset : public UDataAsset +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere) + float ProjectileSpeed = 500.0f; + + UPROPERTY(EditAnywhere) + TObjectPtr StaticMesh; +}; diff --git a/Source/vampires/VampireGameMode.cpp b/Source/vampires/VampireGameMode.cpp index 3e28a09..9d27a86 100644 --- a/Source/vampires/VampireGameMode.cpp +++ b/Source/vampires/VampireGameMode.cpp @@ -7,6 +7,7 @@ #include "HealthComponent.h" #include "ObjectPoolManager.h" #include "PlayerCharacter.h" +#include "Projectile.h" #include "VampirePlayerController.h" #include "Components/CapsuleComponent.h" #include "Kismet/GameplayStatics.h" @@ -77,7 +78,7 @@ void AVampireGameMode::SpawnEnemy() FActorSpawnParameters SpawnParameters; SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - if (AActor* object = GetEnemyObjectPoolManager()->GetObject()) + if (AActor* object = GetEnemyObjectPoolManager_Implementation()->GetObject()) { AEnemyCharacter* Actor = Cast(object); Actor->SetActorTransform(Transform); @@ -91,16 +92,15 @@ void AVampireGameMode::SpawnEnemy() { Actor->SpawnDefaultController(); } - + if (!Actor->GetHealthComponent()->OnDeath.IsAlreadyBound(this, &AVampireGameMode::HandleOnEnemyDeath)) { Actor->GetHealthComponent()->OnDeath.AddDynamic(this, &AVampireGameMode::HandleOnEnemyDeath); } - } } -AObjectPoolManager* AVampireGameMode::GetEnemyObjectPoolManager() +AObjectPoolManager* AVampireGameMode::GetEnemyObjectPoolManager_Implementation() { if (EnemyObjectPoolManager == nullptr) { @@ -112,6 +112,18 @@ AObjectPoolManager* AVampireGameMode::GetEnemyObjectPoolManager() return EnemyObjectPoolManager; } +AObjectPoolManager* AVampireGameMode::GetProjectileObjectPoolManager_Implementation() +{ + if (ProjectileObjectPoolManager == nullptr) + { + ProjectileObjectPoolManager = GetWorld()->SpawnActor(); + TSubclassOf projectileTemplate = ProjectileTemplate; + ProjectileObjectPoolManager->InitializeObjectPool(projectileTemplate); + } + + return ProjectileObjectPoolManager; +} + void AVampireGameMode::IncrementEnemyDeathCount() { EnemyDeathCount++; diff --git a/Source/vampires/VampireGameMode.h b/Source/vampires/VampireGameMode.h index c2aab5b..b43e80b 100644 --- a/Source/vampires/VampireGameMode.h +++ b/Source/vampires/VampireGameMode.h @@ -5,8 +5,10 @@ #include "CoreMinimal.h" #include "HealthComponent.h" #include "GameFramework/GameMode.h" +#include "Interfaces/Pools.h" #include "VampireGameMode.generated.h" +class AProjectile; class AObjectPoolManager; class AVampirePlayerController; class APlayerCharacter; @@ -15,7 +17,7 @@ class AEnemyCharacter; DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnEnemyDeathCountIncrementDelegate, int, level); UCLASS() -class VAMPIRES_API AVampireGameMode : public AGameMode +class VAMPIRES_API AVampireGameMode : public AGameMode, public IPools { GENERATED_BODY() @@ -23,6 +25,9 @@ public: UPROPERTY(EditDefaultsOnly) TSubclassOf EnemyTemplate; + UPROPERTY(EditDefaultsOnly) + TSubclassOf ProjectileTemplate; + FOnEnemyDeathCountIncrementDelegate OnEnemyDeathCountIncrementDelegate; private: @@ -36,6 +41,8 @@ private: TObjectPtr EnemyObjectPoolManager = nullptr; + TObjectPtr ProjectileObjectPoolManager = nullptr; + protected: virtual void BeginPlay() override; @@ -45,11 +52,13 @@ public: UFUNCTION() void HandleOnEnemyDeath(FDamageInfo damageInfo); - + UFUNCTION() void IncrementEnemyDeathCount(); - AObjectPoolManager* GetEnemyObjectPoolManager(); + virtual AObjectPoolManager* GetEnemyObjectPoolManager_Implementation() override; + + virtual AObjectPoolManager* GetProjectileObjectPoolManager_Implementation() override; protected: UFUNCTION() diff --git a/Source/vampires/Weapon.h b/Source/vampires/Weapon.h index 58c8780..f054a38 100644 --- a/Source/vampires/Weapon.h +++ b/Source/vampires/Weapon.h @@ -6,6 +6,8 @@ #include "GameFramework/Actor.h" #include "Weapon.generated.h" +class UWeaponDataAsset; + UCLASS() class VAMPIRES_API AWeapon : public AActor { @@ -18,6 +20,9 @@ public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties") float Damage; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Properties") + TObjectPtr WeaponDataAsset; + private: FTimerHandle WeaponTimerHandle; @@ -30,7 +35,6 @@ protected: virtual void BeginPlay() override; public: - UFUNCTION(BlueprintNativeEvent) void FireWeaponAction(); virtual void FireWeaponAction_Implementation(); diff --git a/Source/vampires/Weapons/FireWandWeapon.cpp b/Source/vampires/Weapons/FireWandWeapon.cpp index 4f6f5f3..058e435 100644 --- a/Source/vampires/Weapons/FireWandWeapon.cpp +++ b/Source/vampires/Weapons/FireWandWeapon.cpp @@ -3,7 +3,11 @@ #include "FireWandWeapon.h" +#include "GameFramework/GameModeBase.h" +#include "Kismet/GameplayStatics.h" #include "Kismet/KismetMathLibrary.h" +#include "vampires/ObjectPoolManager.h" +#include "vampires/Interfaces/Pools.h" #include "vampires/Projectile.h" AFireWandWeapon::AFireWandWeapon() @@ -18,23 +22,31 @@ void AFireWandWeapon::BeginPlay() void AFireWandWeapon::FireWeaponAction_Implementation() { Super::FireWeaponAction_Implementation(); - - if (IsValid(ProjectileTemplate) && OverlappedEnemies.Num() > 0) + + if (ProjectileTemplate && OverlappedEnemies.Num() > 0) { - FActorSpawnParameters actorSpawnParameters; - actorSpawnParameters.Owner = this; - actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot; - - AProjectile* projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); - AActor* target = OverlappedEnemies[FMath::RandRange(0, OverlappedEnemies.Num() - 1)]; - FVector direction = UKismetMathLibrary::GetDirectionUnitVector( - GetActorLocation(), target->GetActorLocation()); - direction.Z = 0.0; - direction.Normalize(); + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + AActor* projectile = objectPoolManager->GetObject(); - projectile->SetTargetDirection(direction); + if (UKismetSystemLibrary::DoesImplementInterface(projectile, UProjectilable::StaticClass())) + { + IProjectilable::Execute_LoadDataFromDataAsset(projectile, ProjectileTemplate); + projectile->SetOwner(this); + + AActor* target = OverlappedEnemies[FMath::RandRange(0, OverlappedEnemies.Num() - 1)]; + FVector direction = UKismetMathLibrary::GetDirectionUnitVector( + GetActorLocation(), target->GetActorLocation()); + direction.Z = 0.0; + direction.Normalize(); + + IProjectilable::Execute_SetTargetDirection(projectile, direction); + } + } + } } } diff --git a/Source/vampires/Weapons/GunWeapon.cpp b/Source/vampires/Weapons/GunWeapon.cpp index 97bac61..1122392 100644 --- a/Source/vampires/Weapons/GunWeapon.cpp +++ b/Source/vampires/Weapons/GunWeapon.cpp @@ -3,11 +3,14 @@ #include "GunWeapon.h" +#include "GameFramework/GameModeBase.h" #include "Kismet/GameplayStatics.h" #include "Kismet/KismetMathLibrary.h" +#include "vampires/ObjectPoolManager.h" #include "vampires/PlayerCharacter.h" #include "vampires/Projectile.h" #include "vampires/VampirePlayerController.h" +#include "vampires/Interfaces/Pools.h" AGunWeapon::AGunWeapon() { @@ -22,50 +25,58 @@ void AGunWeapon::FireWeaponAction_Implementation() { Super::FireWeaponAction_Implementation(); - if (IsValid(ProjectileTemplate)) + if (ProjectileTemplate && OverlappedEnemies.Num() > 0) { - FVector2d ViewportSize; - GEngine->GameViewport->GetViewportSize(ViewportSize); + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); - APlayerCharacter* PlayerCharacter = Cast(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0)); - AVampirePlayerController* PlayerController = Cast( - UGameplayStatics::GetPlayerController(PlayerCharacter, 0)); - - FVector TopLeft, TopLeftDir; - FVector TopRight, TopRightDir; - FVector BottomLeft, BottomLeftDir; - FVector BottomRight, BottomRightDir; + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + FVector2d ViewportSize; + GEngine->GameViewport->GetViewportSize(ViewportSize); - PlayerController->DeprojectScreenPositionToWorld(0, 0, TopLeft, TopLeftDir); - PlayerController->DeprojectScreenPositionToWorld(ViewportSize.X, 0, TopRight, TopRightDir); - PlayerController->DeprojectScreenPositionToWorld(0, ViewportSize.Y, BottomLeft, BottomLeftDir); - PlayerController->DeprojectScreenPositionToWorld(ViewportSize.X, ViewportSize.Y, BottomRight, BottomRightDir); - - FVector actorLocation = GetActorLocation(); - TopLeft.Z = actorLocation.Z; - TopRight.Z = actorLocation.Z; - BottomLeft.Z = actorLocation.Z; - BottomRight.Z = actorLocation.Z; - - FActorSpawnParameters actorSpawnParameters; - actorSpawnParameters.Owner = this; - actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot; - - AProjectile* projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); - projectile->SetTargetDirection(UKismetMathLibrary::GetDirectionUnitVector(actorLocation, TopLeft)); + APlayerCharacter* PlayerCharacter = Cast( + UGameplayStatics::GetPlayerCharacter(GetWorld(), 0)); + AVampirePlayerController* PlayerController = Cast( + UGameplayStatics::GetPlayerController(PlayerCharacter, 0)); - projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); - projectile->SetTargetDirection(UKismetMathLibrary::GetDirectionUnitVector(actorLocation, TopRight)); + FVector TopLeft, TopLeftDir; + FVector TopRight, TopRightDir; + FVector BottomLeft, BottomLeftDir; + FVector BottomRight, BottomRightDir; - projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); - projectile->SetTargetDirection(UKismetMathLibrary::GetDirectionUnitVector(actorLocation, BottomLeft)); + PlayerController->DeprojectScreenPositionToWorld(0, 0, TopLeft, TopLeftDir); + PlayerController->DeprojectScreenPositionToWorld(ViewportSize.X, 0, TopRight, TopRightDir); + PlayerController->DeprojectScreenPositionToWorld(0, ViewportSize.Y, BottomLeft, BottomLeftDir); + PlayerController->DeprojectScreenPositionToWorld(ViewportSize.X, ViewportSize.Y, BottomRight, + BottomRightDir); - projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); - projectile->SetTargetDirection(UKismetMathLibrary::GetDirectionUnitVector(actorLocation, BottomRight)); + FVector actorLocation = GetActorLocation(); + TopLeft.Z = actorLocation.Z; + TopRight.Z = actorLocation.Z; + BottomLeft.Z = actorLocation.Z; + BottomRight.Z = actorLocation.Z; + + AActor* projectile = objectPoolManager->GetObject(); + SpawnProjectile(projectile, UKismetMathLibrary::GetDirectionUnitVector(actorLocation, TopLeft)); + projectile = objectPoolManager->GetObject(); + SpawnProjectile(projectile, UKismetMathLibrary::GetDirectionUnitVector(actorLocation, TopRight)); + projectile = objectPoolManager->GetObject(); + SpawnProjectile(projectile, UKismetMathLibrary::GetDirectionUnitVector(actorLocation, BottomLeft)); + projectile = objectPoolManager->GetObject(); + SpawnProjectile(projectile, UKismetMathLibrary::GetDirectionUnitVector(actorLocation, BottomRight)); + } + } } -} \ No newline at end of file +} + +void AGunWeapon::SpawnProjectile(AActor* projectile, FVector direction) +{ + if (UKismetSystemLibrary::DoesImplementInterface(projectile, UProjectilable::StaticClass())) + { + IProjectilable::Execute_LoadDataFromDataAsset(projectile, ProjectileTemplate); + projectile->SetOwner(this); + IProjectilable::Execute_SetTargetDirection(projectile, direction); + } +} diff --git a/Source/vampires/Weapons/GunWeapon.h b/Source/vampires/Weapons/GunWeapon.h index 0dc6777..1884703 100644 --- a/Source/vampires/Weapons/GunWeapon.h +++ b/Source/vampires/Weapons/GunWeapon.h @@ -22,4 +22,7 @@ protected: public: virtual void FireWeaponAction_Implementation() override; + +private: + void SpawnProjectile(AActor* projectile, FVector direction); }; diff --git a/Source/vampires/Weapons/KnifeWeapon.cpp b/Source/vampires/Weapons/KnifeWeapon.cpp index 6c91039..2ece205 100644 --- a/Source/vampires/Weapons/KnifeWeapon.cpp +++ b/Source/vampires/Weapons/KnifeWeapon.cpp @@ -3,9 +3,12 @@ #include "KnifeWeapon.h" +#include "GameFramework/GameModeBase.h" #include "Kismet/GameplayStatics.h" +#include "vampires/ObjectPoolManager.h" #include "vampires/PlayerCharacter.h" #include "vampires/Projectile.h" +#include "vampires/Interfaces/Pools.h" AKnifeWeapon::AKnifeWeapon() { @@ -22,19 +25,29 @@ void AKnifeWeapon::FireWeaponAction_Implementation() if (UKismetSystemLibrary::DoesImplementInterface(GetOwner(), UInputable::StaticClass())) { - if (IsValid(ProjectileTemplate)) + if (ProjectileTemplate && OverlappedEnemies.Num() > 0) { - FActorSpawnParameters actorSpawnParameters; - actorSpawnParameters.Owner = this; - actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot; + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); - AProjectile* projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + AActor* projectile = objectPoolManager->GetObject(); - FVector direction = FVector(IInputable::Execute_Input_GetPreviousMovementDirection(GetOwner()), 0.0); - direction.Normalize(); - projectile->SetTargetDirection(direction); + if (UKismetSystemLibrary::DoesImplementInterface(projectile, UProjectilable::StaticClass())) + { + IProjectilable::Execute_LoadDataFromDataAsset(projectile, ProjectileTemplate); + projectile->SetOwner(this); + + FVector direction = FVector(IInputable::Execute_Input_GetPreviousMovementDirection(GetOwner()), + 0.0); + direction.Normalize(); + + IProjectilable::Execute_SetTargetDirection(projectile, direction); + } + } + } } - } + } } diff --git a/Source/vampires/Weapons/MagicWandWeapon.cpp b/Source/vampires/Weapons/MagicWandWeapon.cpp index 93e3a49..8502f67 100644 --- a/Source/vampires/Weapons/MagicWandWeapon.cpp +++ b/Source/vampires/Weapons/MagicWandWeapon.cpp @@ -3,9 +3,12 @@ #include "MagicWandWeapon.h" +#include "GameFramework/GameModeBase.h" #include "Kismet/GameplayStatics.h" #include "Kismet/KismetMathLibrary.h" +#include "vampires/ObjectPoolManager.h" #include "vampires/Projectile.h" +#include "vampires/Interfaces/Pools.h" AMagicWandWeapon::AMagicWandWeapon() { @@ -20,25 +23,35 @@ void AMagicWandWeapon::FireWeaponAction_Implementation() { Super::FireWeaponAction_Implementation(); - if (IsValid(ProjectileTemplate)) + if (ProjectileTemplate && OverlappedEnemies.Num() > 0) { float distance = 0.0f; AActor* nearestActor = UGameplayStatics::FindNearestActor(GetActorLocation(), OverlappedEnemies, distance); if (nearestActor) { - FActorSpawnParameters actorSpawnParameters; - actorSpawnParameters.Owner = this; - actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot; - - AProjectile* projectile = GetWorld()->SpawnActor(ProjectileTemplate, GetOwner()->GetTransform(), - actorSpawnParameters); - FVector direction = UKismetMathLibrary::GetDirectionUnitVector( - GetActorLocation(), nearestActor->GetActorLocation()); - direction.Z = 0.0; - direction.Normalize(); - projectile->SetTargetDirection(direction); + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); + + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + AActor* projectile = objectPoolManager->GetObject(); + + if (UKismetSystemLibrary::DoesImplementInterface(projectile, UProjectilable::StaticClass())) + { + IProjectilable::Execute_LoadDataFromDataAsset(projectile, ProjectileTemplate); + projectile->SetOwner(this); + + FVector direction = UKismetMathLibrary::GetDirectionUnitVector( + GetActorLocation(), nearestActor->GetActorLocation()); + direction.Z = 0.0; + direction.Normalize(); + + IProjectilable::Execute_SetTargetDirection(projectile, direction); + } + } + } } } } diff --git a/Source/vampires/Weapons/ProjectileWeapon.h b/Source/vampires/Weapons/ProjectileWeapon.h index 4ded999..95dce0f 100644 --- a/Source/vampires/Weapons/ProjectileWeapon.h +++ b/Source/vampires/Weapons/ProjectileWeapon.h @@ -6,6 +6,7 @@ #include "vampires/Weapon.h" #include "ProjectileWeapon.generated.h" +class UProjectileDataAsset; class AProjectile; class UBoxComponent; @@ -22,7 +23,7 @@ public: UBoxComponent* BoxComponent = nullptr; UPROPERTY(EditAnywhere, Category = "Weapon Properties") - TSubclassOf ProjectileTemplate = nullptr; + TObjectPtr ProjectileTemplate = nullptr; protected: TArray OverlappedEnemies = TArray(); diff --git a/Source/vampires/Weapons/WeaponDataAsset.cpp b/Source/vampires/Weapons/WeaponDataAsset.cpp new file mode 100644 index 0000000..0d6c5db --- /dev/null +++ b/Source/vampires/Weapons/WeaponDataAsset.cpp @@ -0,0 +1,4 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "WeaponDataAsset.h" diff --git a/Source/vampires/Weapons/WeaponDataAsset.h b/Source/vampires/Weapons/WeaponDataAsset.h new file mode 100644 index 0000000..4ee3c8e --- /dev/null +++ b/Source/vampires/Weapons/WeaponDataAsset.h @@ -0,0 +1,50 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/DataAsset.h" +#include "WeaponDataAsset.generated.h" + +class UPaperSprite; +class AProjectile; + +USTRUCT(BlueprintType) +struct FWeaponLevelUpgrades +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float WeaponCooldownMultiplier; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float WeaponDamageMultiplier; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float WeaponRangeMultiplier; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FText WeaponUpgradeText; +}; + +/** + * + */ +UCLASS(BlueprintType) +class VAMPIRES_API UWeaponDataAsset : public UDataAsset +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, Category = "Weapon Properties") + TSubclassOf ProjectileTemplate = nullptr; + + UPROPERTY(EditDefaultsOnly, Category = "Weapon Properties") + USoundBase* WeaponActivatedSoundBase = nullptr; + + UPROPERTY(EditDefaultsOnly, Category = "Weapon Properties") + TObjectPtr WeaponSprite = nullptr; + + UPROPERTY(EditDefaultsOnly, Category = "Weapon Upgrades") + TArray WeaponLevelUpgrades = TArray(); +};