diff --git a/Content/Assets/FX/RocketTrail/NS_TrailSmoke_Grenade.uasset b/Content/Assets/FX/RocketTrail/NS_TrailSmoke_Grenade.uasset new file mode 100644 index 0000000..7be54c3 Binary files /dev/null and b/Content/Assets/FX/RocketTrail/NS_TrailSmoke_Grenade.uasset differ diff --git a/Content/Blueprints/Weapon/BP_GenadeLauncher.uasset b/Content/Blueprints/Weapon/BP_GenadeLauncher.uasset index 12663ea..98a4c26 100644 Binary files a/Content/Blueprints/Weapon/BP_GenadeLauncher.uasset and b/Content/Blueprints/Weapon/BP_GenadeLauncher.uasset differ diff --git a/Content/Blueprints/Weapon/Projectiles/BP_ProjectileGrenade.uasset b/Content/Blueprints/Weapon/Projectiles/BP_ProjectileGrenade.uasset new file mode 100644 index 0000000..57073de Binary files /dev/null and b/Content/Blueprints/Weapon/Projectiles/BP_ProjectileGrenade.uasset differ diff --git a/Source/Blaster/Character/BlasterCharacter.cpp b/Source/Blaster/Character/BlasterCharacter.cpp index 20721b7..e41efe5 100644 --- a/Source/Blaster/Character/BlasterCharacter.cpp +++ b/Source/Blaster/Character/BlasterCharacter.cpp @@ -137,7 +137,7 @@ void ABlasterCharacter::MulticastEliminated_Implementation() GetActorLocation() ); } - if (IsLocallyControlled() && GetEquippedWeapon()->GetWeaponType() == EWeaponType::EWT_SniperRifle && IsAiming()) + if (IsLocallyControlled() && GetEquippedWeapon() && GetEquippedWeapon()->GetWeaponType() == EWeaponType::EWT_SniperRifle && IsAiming()) { ShowSniperScopeWidget(false); } diff --git a/Source/Blaster/Weapon/Projectile.cpp b/Source/Blaster/Weapon/Projectile.cpp index 1c1dee7..6fa72a1 100644 --- a/Source/Blaster/Weapon/Projectile.cpp +++ b/Source/Blaster/Weapon/Projectile.cpp @@ -3,6 +3,7 @@ #include "Projectile.h" +#include "NiagaraFunctionLibrary.h" #include "Blaster/Blaster.h" #include "Components/BoxComponent.h" #include "Kismet/GameplayStatics.h" @@ -50,6 +51,27 @@ void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimi Destroy(); } + +void AProjectile::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +void AProjectile::StartDestroyTimer() +{ + GetWorldTimerManager().SetTimer( + DestroyTimer, + this, + &AProjectile::DestroyTimerFinished, + DestroyTime +); +} + +void AProjectile::DestroyTimerFinished() +{ + Destroy(); +} + void AProjectile::Destroyed() { Super::Destroyed(); @@ -65,7 +87,43 @@ void AProjectile::Destroyed() } } -void AProjectile::Tick(float DeltaTime) +void AProjectile::SpawnTrailSystem() { - Super::Tick(DeltaTime); + if (TrailSystem) + { + TrailSystemComponent = UNiagaraFunctionLibrary::SpawnSystemAttached( + TrailSystem, + GetRootComponent(), + FName(), + GetActorLocation(), + GetActorRotation(), + EAttachLocation::KeepWorldPosition, + false + ); + } +} + +void AProjectile::ExplodeDamage() +{ + APawn* FiringPawn = GetInstigator(); + if (FiringPawn && HasAuthority()) + { + AController* FiringController = FiringPawn->GetController(); + if (FiringController) + { + UGameplayStatics::ApplyRadialDamageWithFalloff( + this, + Damage, + 10.f, + GetActorLocation(), + DamageInnerRadius, + DamageOuterRadius, + 1.f, + UDamageType::StaticClass(), + TArray(), + this, + FiringController + ); + } + } } diff --git a/Source/Blaster/Weapon/Projectile.h b/Source/Blaster/Weapon/Projectile.h index c3f0cd3..e21c680 100644 --- a/Source/Blaster/Weapon/Projectile.h +++ b/Source/Blaster/Weapon/Projectile.h @@ -18,6 +18,10 @@ public: protected: virtual void BeginPlay() override; + void StartDestroyTimer(); + void DestroyTimerFinished(); + void SpawnTrailSystem(); + void ExplodeDamage(); UFUNCTION() virtual void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit); @@ -37,6 +41,21 @@ protected: UPROPERTY(VisibleAnywhere) class UProjectileMovementComponent* ProjectileMovementComponent; + + UPROPERTY(EditAnywhere) + class UNiagaraSystem* TrailSystem; + + UPROPERTY() + class UNiagaraComponent* TrailSystemComponent; + + UPROPERTY(VisibleAnywhere) + UStaticMeshComponent* ProjectileMesh; + + UPROPERTY(EditAnywhere) + float DamageInnerRadius = 200.f; + + UPROPERTY(EditAnywhere) + float DamageOuterRadius = 500.f; private: @@ -45,4 +64,9 @@ private: UPROPERTY() class UParticleSystemComponent* TracerComponent; + + FTimerHandle DestroyTimer; + + UPROPERTY(EditAnywhere) + float DestroyTime = 3.f; }; diff --git a/Source/Blaster/Weapon/ProjectileGrenade.cpp b/Source/Blaster/Weapon/ProjectileGrenade.cpp new file mode 100644 index 0000000..23c5f27 --- /dev/null +++ b/Source/Blaster/Weapon/ProjectileGrenade.cpp @@ -0,0 +1,67 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "ProjectileGrenade.h" + +#include "Blaster/Character/BlasterCharacter.h" +#include "GameFramework/ProjectileMovementComponent.h" +#include "Kismet/GameplayStatics.h" +#include "Sound/SoundCue.h" + +AProjectileGrenade::AProjectileGrenade() +{ + ProjectileMesh = CreateDefaultSubobject(TEXT("Grenade Mesh")); + ProjectileMesh->SetupAttachment(RootComponent); + ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + ProjectileMovementComponent = CreateDefaultSubobject(TEXT("ProjectileMovementComponent")); + ProjectileMovementComponent->bRotationFollowsVelocity = true; + ProjectileMovementComponent->SetIsReplicated(true); + ProjectileMovementComponent->bShouldBounce = true; +} + +void AProjectileGrenade::BeginPlay() +{ + AActor::BeginPlay(); + + SpawnTrailSystem(); + StartDestroyTimer(); + ProjectileMovementComponent->OnProjectileBounce.AddDynamic(this, &AProjectileGrenade::OnBounce); +} + +void AProjectileGrenade::OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity) +{ + if (ABlasterCharacter* BlasterCharacter = Cast(ImpactResult.GetActor())) + { + const APawn* FiringPawn = GetInstigator(); + if (FiringPawn && HasAuthority()) + { + AController* InstigatorController = FiringPawn->GetController(); + if (InstigatorController) + { + UGameplayStatics::ApplyDamage( + BlasterCharacter, + Damage / 4, + InstigatorController, + this, + UDamageType::StaticClass() + ); + } + } + } + + if (BounceSound) + { + UGameplayStatics::PlaySoundAtLocation( + this, + BounceSound, + GetActorLocation() + ); + } +} + +void AProjectileGrenade::Destroyed() +{ + ExplodeDamage(); + Super::Destroyed(); +} \ No newline at end of file diff --git a/Source/Blaster/Weapon/ProjectileGrenade.h b/Source/Blaster/Weapon/ProjectileGrenade.h new file mode 100644 index 0000000..81a8946 --- /dev/null +++ b/Source/Blaster/Weapon/ProjectileGrenade.h @@ -0,0 +1,33 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Projectile.h" +#include "ProjectileGrenade.generated.h" + +/** + * + */ +UCLASS() +class BLASTER_API AProjectileGrenade : public AProjectile +{ + GENERATED_BODY() + +public: + + AProjectileGrenade(); + virtual void Destroyed() override; + +protected: + + virtual void BeginPlay() override; + + UFUNCTION() + void OnBounce(const FHitResult& ImpactResult, const FVector& ImpactVelocity); + +private: + + UPROPERTY(EditAnywhere) + USoundCue* BounceSound; +}; diff --git a/Source/Blaster/Weapon/ProjectileRocket.cpp b/Source/Blaster/Weapon/ProjectileRocket.cpp index 529fec1..61c28a2 100644 --- a/Source/Blaster/Weapon/ProjectileRocket.cpp +++ b/Source/Blaster/Weapon/ProjectileRocket.cpp @@ -4,7 +4,6 @@ #include "ProjectileRocket.h" #include "Kismet/GameplayStatics.h" -#include "NiagaraFunctionLibrary.h" #include "NiagaraComponent.h" #include "RocketMovementComponent.h" #include "Components/AudioComponent.h" @@ -13,9 +12,9 @@ AProjectileRocket::AProjectileRocket() { - RocketMesh = CreateDefaultSubobject(TEXT("Rocket Mesh")); - RocketMesh->SetupAttachment(RootComponent); - RocketMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); + ProjectileMesh = CreateDefaultSubobject(TEXT("Rocket Mesh")); + ProjectileMesh->SetupAttachment(RootComponent); + ProjectileMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); RocketMovementComponent = CreateDefaultSubobject("RocketMovementComponent"); RocketMovementComponent->bRotationFollowsVelocity = true; @@ -35,18 +34,8 @@ void AProjectileRocket::BeginPlay() CollisionBox->OnComponentHit.AddDynamic(this, &AProjectileRocket::OnHit); } - if (TrailSystem) - { - TrailSystemComponent = UNiagaraFunctionLibrary::SpawnSystemAttached( - TrailSystem, - GetRootComponent(), - FName(), - GetActorLocation(), - GetActorRotation(), - EAttachLocation::KeepWorldPosition, - false - ); - } + SpawnTrailSystem(); + if (ProjectileLoop && LoopingSoundAttenuation) { ProjectileLoopComponent = UGameplayStatics::SpawnSoundAttached( @@ -66,45 +55,15 @@ void AProjectileRocket::BeginPlay() } } -void AProjectileRocket::DestroyTimerFinished() -{ - Destroy(); -} - void AProjectileRocket::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) { if (OtherActor == GetOwner()) { return; } - APawn* FiringPawn = GetInstigator(); - if (FiringPawn && HasAuthority()) - { - AController* FiringController = FiringPawn->GetController(); - if (FiringController) - { - UGameplayStatics::ApplyRadialDamageWithFalloff( - this, - Damage, - 10.f, - GetActorLocation(), - 200.f, - 500.f, - 1.f, - UDamageType::StaticClass(), - TArray(), - this, - FiringController - ); - } - } + ExplodeDamage(); - GetWorldTimerManager().SetTimer( - DestroyTimer, - this, - &AProjectileRocket::DestroyTimerFinished, - DestroyTime - ); + StartDestroyTimer(); if (ImpactParticles) { @@ -114,9 +73,9 @@ void AProjectileRocket::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, { UGameplayStatics::PlaySoundAtLocation(this, ImpactSound, GetActorLocation()); } - if (RocketMesh) + if (ProjectileMesh) { - RocketMesh->SetVisibility(false); + ProjectileMesh->SetVisibility(false); } if (CollisionBox) { diff --git a/Source/Blaster/Weapon/ProjectileRocket.h b/Source/Blaster/Weapon/ProjectileRocket.h index 94af218..3b9010f 100644 --- a/Source/Blaster/Weapon/ProjectileRocket.h +++ b/Source/Blaster/Weapon/ProjectileRocket.h @@ -20,14 +20,7 @@ protected: virtual void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) override; virtual void BeginPlay() override; - void DestroyTimerFinished(); - UPROPERTY(EditAnywhere) - class UNiagaraSystem* TrailSystem; - - UPROPERTY() - class UNiagaraComponent* TrailSystemComponent; - UPROPERTY(EditAnywhere) USoundCue* ProjectileLoop; @@ -40,13 +33,4 @@ protected: UPROPERTY(VisibleAnywhere) class URocketMovementComponent* RocketMovementComponent; -private: - - UPROPERTY(VisibleAnywhere) - UStaticMeshComponent* RocketMesh; - - FTimerHandle DestroyTimer; - - UPROPERTY(EditAnywhere) - float DestroyTime = 3.f; };