Added basic bullet trails

This commit is contained in:
TjgL 2025-01-25 21:41:43 +01:00
parent ebfc6f0b61
commit a8c7de9f54
16 changed files with 182 additions and 24 deletions

BIN
Content/Legumix/Weapon/Ammo/BP_Tracer.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Weapon/Ammo/FXE_ShotGun_Trail.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Ammo/NE_Tracer.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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[] { });

View File

@ -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<ULMHitBox>(OutHit.Component))
{
UE_LOG(LogTemp, Warning, TEXT("Hit Hitbox"));
HitSomething = true;
HitBox->OnHit(Settings);
}

View File

@ -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<UNiagaraComponent>(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);
}

View File

@ -20,6 +20,9 @@ ALMWeaponBase::ALMWeaponBase()
WeaponMesh->SetupAttachment(RootComponent);
WeaponSocket = FName();
TracerOrigin = CreateDefaultSubobject<USceneComponent>(TEXT("Tracer Origin"));
TracerOrigin->SetupAttachment(RootComponent);
}
void ALMWeaponBase::BeginPlay()

View File

@ -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<ALMBulletTracer>(Data.BulletTracer))
{
Trace->SetActorLocationAndRotation(GetCurrentWeapon()->GetTracerOrigin(), Direction);
Trace->Initialize(EndLocation);
}
}
}
void ULMWeaponManager::Initialize(USkeletalMeshComponent* Mesh)
{
ArmsMesh = Mesh;

View File

@ -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<ALMBulletTracer> BulletTracer;
/**
* An utility method to add and
* @param Quantity The quantity of ammo to add.

View File

@ -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<UCameraComponent> 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;
};

View File

@ -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<UNiagaraComponent> TrailFx;
UPROPERTY(BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
bool bCanMove;
private:
FTimerHandle TimerHandle;
};

View File

@ -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<USkeletalMeshComponent> WeaponMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TObjectPtr<USceneComponent> TracerOrigin;
};

View File

@ -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"))