diff --git a/Content/Legumix/Weapon/Ammo/BP_Tracer.uasset b/Content/Legumix/Weapon/Ammo/BP_Tracer.uasset new file mode 100644 index 0000000..2fb1047 --- /dev/null +++ b/Content/Legumix/Weapon/Ammo/BP_Tracer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e8b34577715d3da608ab11dd0da3163ab575d350f103eb66039d932b29f5461 +size 63433 diff --git a/Content/Legumix/Weapon/Ammo/DT_Munitions.uasset b/Content/Legumix/Weapon/Ammo/DT_Munitions.uasset index 4e1a0d1..95efef4 100644 --- a/Content/Legumix/Weapon/Ammo/DT_Munitions.uasset +++ b/Content/Legumix/Weapon/Ammo/DT_Munitions.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b8a4e01b6a9b5e9ac6893103961ed7f3bfc48ffae60b90a24a5c98d21798a13 -size 2597 +oid sha256:13d6c8dca737ba1acb38515e4bfa5beabd5da5644fbbca53d9db5b1f5395c9f7 +size 2852 diff --git a/Content/Legumix/Weapon/Ammo/FXE_ShotGun_Trail.uasset b/Content/Legumix/Weapon/Ammo/FXE_ShotGun_Trail.uasset new file mode 100644 index 0000000..a812dc0 --- /dev/null +++ b/Content/Legumix/Weapon/Ammo/FXE_ShotGun_Trail.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51cae881f0f3868fe424e19680e917ff769b9f2f2ca1f2fc39ce49ae8df589b7 +size 342697 diff --git a/Content/Legumix/Weapon/Ammo/NE_Tracer.uasset b/Content/Legumix/Weapon/Ammo/NE_Tracer.uasset new file mode 100644 index 0000000..a910569 --- /dev/null +++ b/Content/Legumix/Weapon/Ammo/NE_Tracer.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60d0c0b996573a1d151bd639a6b5d8afbe7b468357cacfe5431407414d72c450 +size 164871 diff --git a/Content/Legumix/Weapon/BP_WeaponManager.uasset b/Content/Legumix/Weapon/BP_WeaponManager.uasset index 1766bc8..0881e35 100644 --- a/Content/Legumix/Weapon/BP_WeaponManager.uasset +++ b/Content/Legumix/Weapon/BP_WeaponManager.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d89abfa10726185ffc32e9647ed361ef386ffb4bee6fab3a5608f4333e6422d -size 7487 +oid sha256:0cb2825648bf94c2b0208da9f69db70a7521f55cf8181d03cb9c4855bd2ce415 +size 7710 diff --git a/Content/Legumix/Weapon/Shotgun/BP_Shotgun.uasset b/Content/Legumix/Weapon/Shotgun/BP_Shotgun.uasset index 9ed606c..f0669ee 100644 --- a/Content/Legumix/Weapon/Shotgun/BP_Shotgun.uasset +++ b/Content/Legumix/Weapon/Shotgun/BP_Shotgun.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9ebec6fb3bea1fe8ff3a35ad5eb7f7dfe5f963d9e37cd7463694494425d21144 -size 55787 +oid sha256:0589a631e5202de33eb64f9a78b88c03f40a0fb798318f509117f980e3e29ad7 +size 56456 diff --git a/Source/LegumeMix/LegumeMix.Build.cs b/Source/LegumeMix/LegumeMix.Build.cs index 2e2537b..d0ead3b 100644 --- a/Source/LegumeMix/LegumeMix.Build.cs +++ b/Source/LegumeMix/LegumeMix.Build.cs @@ -8,7 +8,7 @@ public class LegumeMix : ModuleRules { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" }); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Niagara" }); PrivateDependencyModuleNames.AddRange(new string[] { }); diff --git a/Source/LegumeMix/Private/Player/LMPlayer.cpp b/Source/LegumeMix/Private/Player/LMPlayer.cpp index f4e6c03..8a3a8af 100644 --- a/Source/LegumeMix/Private/Player/LMPlayer.cpp +++ b/Source/LegumeMix/Private/Player/LMPlayer.cpp @@ -82,26 +82,30 @@ void ALMPlayer::FireBullets(const FLMBulletInfo Settings) OnFire(); - DrawDebugLine(GetWorld(), Settings.Origin, Settings.Origin + (Settings.Direction * Settings.MaxDistance), FColor::Blue, false, 2.f); - +#if WITH_EDITOR + if (bDrawBulletDebug) + DrawDebugLine(GetWorld(), Settings.Origin, Settings.Origin + (Settings.Direction * Settings.MaxDistance), FColor::Blue, false, 2.f); +#endif + for (int Shots = 0; Shots < Settings.BulletCount; Shots++) { ShotVector = UKismetMathLibrary::RandomUnitVectorInConeInDegreesFromStream(SpreadStream, Settings.Direction, Settings.Spread); EndLocation = Settings.Origin + (ShotVector * Settings.MaxDistance); const bool HasHit = GetWorld()->LineTraceSingleByChannel(OutHit, Settings.Origin, EndLocation, TRACE_BULLET); - DrawDebugLineTraceSingle(GetWorld(), Settings.Origin, EndLocation, EDrawDebugTrace::ForDuration, HasHit, OutHit, FColor::Green, FColor::Red, 2.f); + +#if WITH_EDITOR + if (bDrawBulletDebug) + DrawDebugLineTraceSingle(GetWorld(), Settings.Origin, EndLocation, EDrawDebugTrace::ForDuration, HasHit, OutHit, FColor::Green, FColor::Red, 2.f); +#endif + + WeaponManager->CreateTracer(Settings.AmmoType, HasHit ? OutHit.Location : EndLocation, ShotVector.Rotation()); if (!HasHit) continue; - FString Hit = FString::Printf(TEXT("Hit %s"), *OutHit.Component->GetName()); - // GEngine->AddOnScreenDebugMessage(INDEX_NONE, 2.f, FColor::Red, Hit); - UE_LOG(LogTemp, Display, TEXT("%s"), *Hit); - if (ULMHitBox* HitBox = Cast(OutHit.Component)) { - UE_LOG(LogTemp, Warning, TEXT("Hit Hitbox")); HitSomething = true; HitBox->OnHit(Settings); } diff --git a/Source/LegumeMix/Private/Weapon/LMBulletTracer.cpp b/Source/LegumeMix/Private/Weapon/LMBulletTracer.cpp new file mode 100644 index 0000000..0d1c308 --- /dev/null +++ b/Source/LegumeMix/Private/Weapon/LMBulletTracer.cpp @@ -0,0 +1,48 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Weapon/LMBulletTracer.h" +#include "NiagaraComponent.h" + + +ALMBulletTracer::ALMBulletTracer() +{ + PrimaryActorTick.bCanEverTick = true; + + TrailFx = CreateDefaultSubobject(TEXT("Tracer FX")); + RootComponent = TrailFx; +} + +void ALMBulletTracer::BeginPlay() +{ + Super::BeginPlay(); + TrailFx->SetVariableFloat("Lifetime", TrailLifeTime); +} + +void ALMBulletTracer::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +void ALMBulletTracer::Initialize(const FVector& Vector) +{ + const double Distance = FVector::Distance(Vector, GetActorLocation()); + float const LifeTime = Distance / Speed; + + OnIntialized(LifeTime); +} + +void ALMBulletTracer::DestinationReached() +{ + GetWorldTimerManager().ClearTimer(TimerHandle); + TrailFx->Deactivate(); + + OnDestinationReached(); + + GetWorldTimerManager().SetTimer(TimerHandle, [this] + { + GetWorldTimerManager().ClearTimer(TimerHandle); + Destroy(); + }, TrailLifeTime, false); +} + diff --git a/Source/LegumeMix/Private/Weapon/LMWeaponBase.cpp b/Source/LegumeMix/Private/Weapon/LMWeaponBase.cpp index 0fea6c3..3194799 100644 --- a/Source/LegumeMix/Private/Weapon/LMWeaponBase.cpp +++ b/Source/LegumeMix/Private/Weapon/LMWeaponBase.cpp @@ -20,6 +20,9 @@ ALMWeaponBase::ALMWeaponBase() WeaponMesh->SetupAttachment(RootComponent); WeaponSocket = FName(); + + TracerOrigin = CreateDefaultSubobject(TEXT("Tracer Origin")); + TracerOrigin->SetupAttachment(RootComponent); } void ALMWeaponBase::BeginPlay() diff --git a/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp b/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp index b158020..1e027a8 100644 --- a/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp +++ b/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp @@ -19,13 +19,15 @@ void ULMWeaponManager::BeginPlay() SetupAmmoData(); } -// void ULMWeaponManager::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) -// { -// Super::PostEditChangeProperty(PropertyChangedEvent); -// -// if (AmmoDataTable) -// SetupAmmoData(); -// } +#if WITH_EDITOR +void ULMWeaponManager::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) +{ + Super::PostEditChangeProperty(PropertyChangedEvent); + + if (AmmoDataTable) + SetupAmmoData(); +} +#endif void ULMWeaponManager::SetupAmmoData() { @@ -66,6 +68,22 @@ int ULMWeaponManager::RemoveAmmo(const EAmmoType Ammo, const int Count) return 0; } +void ULMWeaponManager::CreateTracer(const EAmmoType Ammo, const FVector EndLocation, const FRotator Direction) +{ + if (AmmoData.Contains(Ammo)) + { + const FLMAmmoData &Data = AmmoData[Ammo]; + if (!Data.BulletTracer) + return; + + if (ALMBulletTracer* Trace = GetWorld()->SpawnActor(Data.BulletTracer)) + { + Trace->SetActorLocationAndRotation(GetCurrentWeapon()->GetTracerOrigin(), Direction); + Trace->Initialize(EndLocation); + } + } +} + void ULMWeaponManager::Initialize(USkeletalMeshComponent* Mesh) { ArmsMesh = Mesh; diff --git a/Source/LegumeMix/Public/Ammo/LMAmmoData.h b/Source/LegumeMix/Public/Ammo/LMAmmoData.h index 06eb078..83bd00f 100644 --- a/Source/LegumeMix/Public/Ammo/LMAmmoData.h +++ b/Source/LegumeMix/Public/Ammo/LMAmmoData.h @@ -2,6 +2,7 @@ #include "LMAmmoType.h" #include "Kismet/KismetMathLibrary.h" +#include "Weapon/LMBulletTracer.h" #include "LMAmmoData.generated.h" @@ -19,6 +20,9 @@ struct FLMAmmoData : public FTableRowBase UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin=0, Uimin=0)) int AmmoCount = 8; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TSubclassOf BulletTracer; + /** * An utility method to add and * @param Quantity The quantity of ammo to add. diff --git a/Source/LegumeMix/Public/Player/LMPlayer.h b/Source/LegumeMix/Public/Player/LMPlayer.h index f671990..d8e4909 100644 --- a/Source/LegumeMix/Public/Player/LMPlayer.h +++ b/Source/LegumeMix/Public/Player/LMPlayer.h @@ -82,7 +82,6 @@ public: UFUNCTION(BlueprintImplementableEvent, Category=Legumix) void OnReload(); - private: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true)) @@ -94,6 +93,13 @@ private: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true)) TObjectPtr Camera; +private: +#if WITH_EDITORONLY_DATA + /** If set, bullet debug will be drawn. */ + UPROPERTY(EditAnywhere, Category=Legumix, meta = (AllowPrivateAccess = true)) + bool bDrawBulletDebug = false; +#endif + private: FRandomStream SpreadStream; }; diff --git a/Source/LegumeMix/Public/Weapon/LMBulletTracer.h b/Source/LegumeMix/Public/Weapon/LMBulletTracer.h new file mode 100644 index 0000000..dcb977c --- /dev/null +++ b/Source/LegumeMix/Public/Weapon/LMBulletTracer.h @@ -0,0 +1,54 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "LMBulletTracer.generated.h" + +class UNiagaraComponent; + +UCLASS(Blueprintable) +class LEGUMEMIX_API ALMBulletTracer : public AActor +{ + GENERATED_BODY() + +public: + ALMBulletTracer(); + void BeginPlay() override; + virtual void Tick(float DeltaTime) override; + + void Initialize(const FVector& Vector); +public: + UFUNCTION(BlueprintCallable, Category=Legumix) + void DestinationReached(); + + /** Called automatically when the bullet reaches it's destination: it hit something. + * The Actor is then automatically destroyed after *TrailLifetime* seconds. + */ + UFUNCTION(BlueprintImplementableEvent) + void OnDestinationReached(); + + /** Called automatically when the bullet has been given a direction. + * @param Lifetime The number of seconds before this object reaches it's destination. + */ + UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category=Legumix) + void OnIntialized(float Lifetime); + +private: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true)) + float Speed = 10000.f; + + /** The lifetime of a single particle emitted by the niagara system. */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true)) + float TrailLifeTime = 2.f; + + UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true)) + TObjectPtr TrailFx; + + UPROPERTY(BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true)) + bool bCanMove; + +private: + FTimerHandle TimerHandle; +}; diff --git a/Source/LegumeMix/Public/Weapon/LMWeaponBase.h b/Source/LegumeMix/Public/Weapon/LMWeaponBase.h index 5816319..8f45fec 100644 --- a/Source/LegumeMix/Public/Weapon/LMWeaponBase.h +++ b/Source/LegumeMix/Public/Weapon/LMWeaponBase.h @@ -46,6 +46,9 @@ public: UFUNCTION(BlueprintCallable, BlueprintImplementableEvent) void OnDefaultReload(); + + UFUNCTION(BlueprintCallable) + FVector GetTracerOrigin() const { return TracerOrigin->GetComponentLocation(); } protected: UFUNCTION(BlueprintCallable) @@ -131,5 +134,8 @@ private: /* Components */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) TObjectPtr WeaponMesh; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + TObjectPtr TracerOrigin; }; diff --git a/Source/LegumeMix/Public/Weapon/LMWeaponManager.h b/Source/LegumeMix/Public/Weapon/LMWeaponManager.h index 0c451c3..840e410 100644 --- a/Source/LegumeMix/Public/Weapon/LMWeaponManager.h +++ b/Source/LegumeMix/Public/Weapon/LMWeaponManager.h @@ -53,6 +53,9 @@ public: UFUNCTION(BlueprintCallable, Category="Legumix|Ammo") int RemoveAmmo(EAmmoType Ammo, int Count); + UFUNCTION(BlueprintCallable) + void CreateTracer(EAmmoType Ammo, FVector EndLocation, FRotator Direction); + public: UPROPERTY(BlueprintAssignable, BlueprintCallable, Category=Legumix) FOnWeaponFiredSignature WeaponFired; @@ -61,7 +64,10 @@ public: protected: virtual void BeginPlay() override; - // virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; + +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; +#endif private: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta = (AllowPrivateAccess = "true"))