I am trying to implement a weapon class to a project of mine. So I created a class, derived from AActor, called it Weapon. In there I created an enum EBulletTypes so I can keep track of what kind of bullets my weapons will have (PistolBullet, RifleBullet, RocketLauncherBullet, …). I also created a struct so I can store different attributes in there like MaxAmmo, Damage, and so on. In my Weapon class I created two functions StartFiringWeapon and StopFiringWeapon which atm should just AddOnScreenDebugMessages to see if everything runs how it should. The StartFiringWeapon and StopFiringWeapon functions are being executed within my character class when the left mouse button is pressed. I want to print to the screen the type of bullet that is currently been selected. I set the BulletType in the AWeapon constructor to be equal to the first BulletType of my enum. But if I perform if statements and print something dependent on what BulletType is set in StartFiringWeapon the engine crashes when I press the left mouse button. If I don’t check for the enums in StartFiringWeapon the engine does not crash and the message is being added.
Weapon.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/Actor.h"
#include "Weapon.generated.h"
UENUM(BlueprintType)
enum class EBulletType : uint8
{
EKnifeBullet,
EPistolBullet,
EShotgunBullet,
ERifleBullet,
ESniperRifleBullet,
EGrenadeLauncherBullet,
ERocketLauncherBullet
};
USTRUCT()
struct FWeaponAttributes
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Attributes")
int32 n32MaxAmmo;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Attributes")
int32 n32CurrentAmmo;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Attributes")
int32 n32MaxClip;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Attributes")
int32 n32CurrentClip;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Weapon Attributes")
float fDamage;
};
UCLASS()
class MYPROJECT_API AWeapon : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AWeapon();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
// Create WeaponAttributes
UPROPERTY(EditDefaultsOnly, Category = "Weapon Attributes")
FWeaponAttributes WeaponsAttributes;
// Create bullet types
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon Attributes")
EBulletType BulletType;
// Fire weapon function declaration
UFUNCTION()
void StartFiringWeapon();
UFUNCTION()
void StopFiringWeapon();
};
Weapon.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyProject.h"
#include "Weapon.h"
// Sets default values
AWeapon::AWeapon()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
AWeapon::WeaponsAttributes.fDamage = 0.0f;
AWeapon::WeaponsAttributes.n32MaxAmmo = 0;
AWeapon::WeaponsAttributes.n32CurrentAmmo = AWeapon::WeaponsAttributes.n32MaxAmmo;
AWeapon::WeaponsAttributes.n32MaxClip = 0;
AWeapon::WeaponsAttributes.n32CurrentClip = AWeapon::WeaponsAttributes.n32MaxClip;
BulletType = EBulletType::EKnifeBullet;
}
// Called when the game starts or when spawned
void AWeapon::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AWeapon::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
void AWeapon::StartFiringWeapon()
{
// This is where it crashes
// If I delete the if-statements
// And if I just call GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("Function ran"));
// Than the engine will not crash
if (BulletType == EBulletType::EKnifeBullet)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("Knife"));
}
}
else if (BulletType == EBulletType::EPistolBullet)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("Pistol"));
}
}
else if (BulletType == EBulletType::EShotgunBullet)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("Shotgun"));
}
}
}
void AWeapon::StopFiringWeapon()
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Cyan, TEXT("StopFiringWeapon()"));
}
}
Character.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Weapon.h"
#include "GameFramework/Character.h"
#include "Character_Simpl0S.generated.h"
UCLASS()
class MYPROJECT_API ACharacter_Simpl0S : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ACharacter_Simpl0S();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// Some code here
AWeapon *pWeapon;
// Fire Weapon
UFUNCTION()
void StartFiringWeapon();
UFUNCTION()
void StopFiringWeapon();
// more code here
};
Character.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyProject.h"
#include "Character_Simpl0S.h"
// Sets default values
ACharacter_Simpl0S::ACharacter_Simpl0S()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ACharacter_Simpl0S::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACharacter_Simpl0S::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void ACharacter_Simpl0S::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
Super::SetupPlayerInputComponent(InputComponent);
// Some Bindings here
// Bind action to fire weapon
InputComponent->BindAction("FireWeapon", IE_Pressed, this, &ACharacter_Simpl0S::StartFiringWeapon);
InputComponent->BindAction("FireWeapon", IE_Released, this, &ACharacter_Simpl0S::StopFiringWeapon);
// More bindings here
}
// Some code here
// Firing weapon definition
void ACharacter_Simpl0S::StartFiringWeapon()
{
pWeapon->StartFiringWeapon();
}
void ACharacter_Simpl0S::StopFiringWeapon()
{
pWeapon->StopFiringWeapon();
}
// More code here