Started working on a new weapon system

This commit is contained in:
TjgL 2025-01-22 17:14:37 +01:00
parent 5524705f60
commit f639b7e3a9
9 changed files with 304 additions and 43 deletions

View File

@ -0,0 +1,33 @@
#pragma once
#include "Weapon/LMAmmoType.h"
#include "LMBulletInfo.generated.h"
USTRUCT(BlueprintType)
struct FLMBulletInfo
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int BulletCount;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Origin;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Direction;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Spread;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MaxDistance;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FFloatCurve Falloff;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EAmmoType AmmoType;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Damage;
};

View File

@ -3,6 +3,8 @@
#include "Player/LMPlayer.h"
#include "KismetTraceUtils.h"
#include "LMBulletInfo.h"
#include "Camera/CameraComponent.h"
#include "Weapon/LMAmmo.h"
#include "Weapon/LMWeaponManager.h"
@ -51,6 +53,16 @@ void ALMPlayer::SetWeaponManager(ULMWeaponManager* Manager)
WeaponManager->Initialize(ArmsMesh);
}
void ALMPlayer::PlayAnimation(UAnimMontage* Animation)
{
}
void ALMPlayer::FireBullets(const FLMBulletInfo Settings)
{
FVector EndLocation = Settings.Origin + (Settings.Direction * Settings.MaxDistance);
TArray<FHitResult> Hits;
DrawDebugLineTraceMulti(GetWorld(), Settings.Origin, EndLocation, EDrawDebugTrace::ForDuration, true, Hits, FColor::Green, FColor::Red, 10.f);
}
void ALMPlayer::Tick(float DeltaTime)
{

View File

@ -0,0 +1,39 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMShotgun.h"
#include "Player/LMBulletInfo.h"
#include "Player/LMPlayer.h"
ALMShotgun::ALMShotgun()
{
PrimaryActorTick.bCanEverTick = true;
}
void ALMShotgun::PrimaryFire()
{
ALMPlayer* Player = Cast<ALMPlayer>(GetOuter());
if (!Player)
return;
PlaySound(Data.FireSound);
PlayAnimation(PrimaryFireAnimation);
FVector Origin = Player->GetWeaponFiringOrigin();
FVector Direction = Player->GetAimVector();
ClipAmmo--;
FLMBulletInfo ShotInfo = FLMBulletInfo(PelletCount, Origin, Direction, WeaponSpread, MaxDistance, DamageFalloff, AmmoType, Damage);
Player->FireBullets(ShotInfo);
}
void ALMShotgun::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}

View File

@ -0,0 +1,56 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMWeaponBase.h"
#include "Components/AudioComponent.h"
ALMWeaponBase::ALMWeaponBase()
{
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("Audio"));
AudioComponent->SetupAttachment(RootComponent);
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
WeaponMesh->SetupAttachment(RootComponent);
WeaponSocket = FName();
}
void ALMWeaponBase::BeginPlay()
{
Super::BeginPlay();
}
void ALMWeaponBase::Reload()
{
}
void ALMWeaponBase::PrimaryFire()
{
}
void ALMWeaponBase::PlaySound(USoundWave* Sound, const bool Replacing)
{
if (AudioComponent->IsPlaying() && !Replacing)
return;
AudioComponent->Stop();
AudioComponent->SetSound(Sound);
AudioComponent->Play();
}
void ALMWeaponBase::PlayAnimation(UAnimMontage* Animation)
{
UAnimInstance* AnimInstance = WeaponMesh->GetAnimInstance();
if (Animation && AnimInstance)
{
AnimInstance->Montage_Play(Animation);
}
}

View File

@ -3,7 +3,7 @@
#include "Weapon/LMWeaponManager.h"
#include "Weapon/LMWeapon.h"
#include "Weapon/LMWeaponBase.h"
ULMWeaponManager::ULMWeaponManager()
@ -18,17 +18,25 @@ void ULMWeaponManager::BeginPlay()
void ULMWeaponManager::Initialize(USkeletalMeshComponent* Mesh)
{
SetWeaponMeshComponent(Mesh);
ArmsMesh = Mesh;
for (auto Weapon : StartingWeapons)
for (auto WeaponTemplate : StartingWeapons)
{
if (Weapon)
{
ULMWeapon* Instance = NewObject<ULMWeapon>(this, Weapon);
if (!WeaponTemplate)
continue;
ALMWeaponBase* Instance = GetWorld()->SpawnActor<ALMWeaponBase>(WeaponTemplate);
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 2.f, FColor::Blue, TEXT("Spawing"));
Instance->SetActorHiddenInGame(true);
Weapons.Add(Instance);
Instance->Initialize(Mesh->GetRelativeLocation());
}
FAttachmentTransformRules Rules = FAttachmentTransformRules(EAttachmentRule::SnapToTarget,
EAttachmentRule::KeepRelative,
EAttachmentRule::KeepRelative,
false);
Instance->AttachToComponent(ArmsMesh, Rules);
}
if (!Weapons.IsEmpty())
@ -42,28 +50,22 @@ void ULMWeaponManager::AddAmmoType(EAmmoType AmmoType, int AmmoCount)
FString Debug = FString::Printf(TEXT("Adding %i ammo of type %i"), AmmoCount, AmmoType);
GEngine->AddOnScreenDebugMessage(1, 1.f, FColor::Cyan, Debug);
for (const auto Weapon : Weapons)
{
if (Weapon->WeaponDataStructure.AmmoType != AmmoType)
continue;
Weapon->AddAmmo(AmmoCount);
}
}
void ULMWeaponManager::Fire()
{
ULMWeapon* Weapon = GetCurrentWeapon();
ALMWeaponBase* Weapon = GetCurrentWeapon();
GEngine->AddOnScreenDebugMessage(2, 1.f, FColor::Cyan, "Fire");
Weapon->Fire();
Weapon->PrimaryFire();
}
void ULMWeaponManager::Reload()
{
GEngine->AddOnScreenDebugMessage(3, 1.f, FColor::Cyan, "Reloading");
ULMWeapon* Weapon = GetCurrentWeapon();
ALMWeaponBase* Weapon = GetCurrentWeapon();
Weapon->Reload();
}
@ -91,13 +93,8 @@ void ULMWeaponManager::SetWeapon(const int Index)
return;
}
GetCurrentWeapon()->SetActorHiddenInGame(true);
CurrentWeaponIndex = Index;
if (WeaponMeshComponent)
{
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5, FColor::Red, "Has Mesh");
WeaponMeshComponent->SetSkeletalMeshAsset(GetCurrentWeapon()->WeaponDataStructure.MeshWeapon);
}
GetCurrentWeapon()->SetActorHiddenInGame(false);
}

View File

@ -3,6 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Character.h"
#include "LMPlayer.generated.h"
@ -36,6 +37,18 @@ public:
UFUNCTION(BlueprintCallable)
void SetWeaponManager(ULMWeaponManager* Manager);
UFUNCTION(BlueprintCallable)
void PlayAnimation(UAnimMontage* Animation);
UFUNCTION(BlueprintCallable)
void FireBullets(const FLMBulletInfo Settings);
UFUNCTION(BlueprintCallable)
FVector GetWeaponFiringOrigin() const { return Camera->GetComponentLocation(); }
UFUNCTION(BlueprintCallable)
FVector GetAimVector() const { return Camera->GetForwardVector(); }
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true))
TObjectPtr<ULMWeaponManager> WeaponManager;

View File

@ -0,0 +1,23 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LMWeaponBase.h"
#include "LMShotgun.generated.h"
UCLASS()
class LEGUMEMIX_API ALMShotgun : public ALMWeaponBase
{
GENERATED_BODY()
public:
ALMShotgun();
virtual void Tick(float DeltaTime) override;
virtual void PrimaryFire() override;
private:
/** The number of pellets fired by the shotgun. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta = (AllowPrivateAccess = true))
int PelletCount = 8;
};

View File

@ -0,0 +1,87 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LMAmmo.h"
#include "LMWeaponDataStructure.h"
#include "GameFramework/Actor.h"
#include "GameFramework/SpringArmComponent.h"
#include "LMWeaponBase.generated.h"
UCLASS()
class LEGUMEMIX_API ALMWeaponBase : public AActor
{
GENERATED_BODY()
public:
ALMWeaponBase();
virtual void BeginPlay() override;
public:
UFUNCTION(BlueprintCallable)
virtual void Reload();
UFUNCTION(BlueprintCallable)
virtual void PrimaryFire();
UFUNCTION(BlueprintCallable)
void PlaySound(USoundWave* Sound, bool Replacing = false);
UFUNCTION(BlueprintCallable)
void PlayAnimation(UAnimMontage* Animation);
/** The socket to attach the weapon to.
* @return The socket.
*/
UFUNCTION(BlueprintCallable)
FName GetAttachmentSocketName() const { return WeaponSocket; }
protected: /* Weapon Data */
/** The weapon static data. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
FLMWeaponDataStructure Data;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Animations", meta=(AllowPrivateAccess=true))
TObjectPtr<UAnimMontage> PrimaryFireAnimation;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Legumix|Animations", meta=(AllowPrivateAccess=true))
TObjectPtr<UAnimMontage> ReloadAnimation;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float Damage = 10.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
FVector WeaponSpread = FVector::ZeroVector;
/** The max distance (cm) between the origin and the target before doing minimal damage. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float MaxDistance = 100000.f;
/** The damage falloff distance in a 0-1 scale. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
FFloatCurve DamageFalloff;
/** The type of ammo used by this weapon. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
EAmmoType AmmoType;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
int ClipAmmo;
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
FDataTableRowHandle DataTableRow;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
FName WeaponSocket;
private: /* Components */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TObjectPtr<UAudioComponent> AudioComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TObjectPtr<USkeletalMeshComponent> WeaponMesh;
};

View File

@ -8,35 +8,36 @@
#include "LMWeaponManager.generated.h"
class ALMWeaponBase;
class ULMWeapon;
UCLASS(Blueprintable, BlueprintType, ClassGroup="Legumix", meta=(BlueprintSpawnableComponent))
UCLASS(Blueprintable, BlueprintType, ClassGroup=Legumix, meta=(BlueprintSpawnableComponent))
class LEGUMEMIX_API ULMWeaponManager : public UActorComponent
{
GENERATED_BODY()
public:
ULMWeaponManager();
void SetWeaponMeshComponent(USkeletalMeshComponent* Mesh) { WeaponMeshComponent = Mesh; }
void SetArmsMesh(USkeletalMeshComponent* Mesh) { ArmsMesh = Mesh; }
public:
/**
* Get the Weapon currently equipped.
* @return The Current Weapon.
*/
UFUNCTION(BlueprintCallable, Category="Legumix")
ULMWeapon* GetCurrentWeapon() { return Weapons[CurrentWeaponIndex]; }
UFUNCTION(BlueprintCallable, Category=Legumix)
ALMWeaponBase* GetCurrentWeapon() { return Weapons[CurrentWeaponIndex]; }
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void SetWeapon(int Index);
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void AddAmmoType(EAmmoType AmmoType, int AmmoCount);
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void Fire();
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void Reload();
void SwitchWeapon(int Direction);
@ -46,16 +47,16 @@ protected:
virtual void BeginPlay() override;
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta = (AllowPrivateAccess = "true"))
TObjectPtr<USkeletalMeshComponent> WeaponMeshComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta = (AllowPrivateAccess = "true"))
TObjectPtr<USkeletalMeshComponent> ArmsMesh;
/** The weapons the player starts with. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta=(AllowPrivateAccess=true))
TArray<TSubclassOf<ULMWeapon>> StartingWeapons;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
TArray<TSubclassOf<ALMWeaponBase>> StartingWeapons;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix", meta=(AllowPrivateAccess=true))
TArray<TObjectPtr<ULMWeapon>> Weapons;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TArray<TObjectPtr<ALMWeaponBase>> Weapons;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta=(AllowPrivateAccess=true))
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
int CurrentWeaponIndex = 0;
};