Hello,
I’m trying to make a base weapon class that contains a bunch of functions that every weapon could use.
Anyway, in it, I’m using timers to control the rate of fire, reload etc.
When I open UE4 for the first time and shoot everything works fine. When I want to change something in the code and then recompile everything, then go back into ue4 and start shooting the editor crashes. Sometimes the editor even crashes after recompiling. After restarting the editor everything works fine again.
The .CPP file:
// Fill out your copyright notice in the Description page of Project Settings.
#include "BaseWeaponClass.h"
#include "Engine/World.h"
#include "Components/SphereComponent.h"
// Sets default values
ABaseWeaponClass::ABaseWeaponClass()
{
// 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;
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Weapon Mesh"));
WeaponMesh->SetOnlyOwnerSee(true);
WeaponMesh->bCastDynamicShadow = false;
WeaponMesh->CastShadow = false;
WeaponMesh->SetupAttachment(RootComponent);
FireRate = 0.075f;
FireDelay = FireRate;
ReloadTime = 3.f;
MagazineSize = 30;
MagazineAmmo = 30;
SpareAmmo = 100;
Burst = 0;
}
// Called when the game starts or when spawned
void ABaseWeaponClass::BeginPlay()
{
Super::BeginPlay();
//WeaponMesh->SetSkeletalMesh(Model);
}
// Called every frame
void ABaseWeaponClass::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Resets the firing sequence
void ABaseWeaponClass::Reset()
{
GetWorldTimerManager().ClearTimer(FiringTimerHandle);
BurstAmt = 0;
IsFiring = false;
}
// Begins the firing sequence
void ABaseWeaponClass::BeginFire()
{
if (MagazineAmmo > 0 && !IsReloading)
{
if (BurstAmt == 0 && CanFire)
{
OnFire();
IsFiring = true;
}
if (FireRate > 0)
FireTimer();
if (FireDelay > 0)
{
CanFire = false;
DelayTimer();
}
}
else if (MagazineAmmo == 0 && !IsReloading) {
OnEmpty();
}
else if (MagazineAmmo == -1) {
OnFire();
IsFiring = true;
}
}
// Stops the firing sequence
void ABaseWeaponClass::StopFire()
{
if (Burst == 0)
{
Reset();
}
}
void ABaseWeaponClass::StartReload()
{
if (MagazineAmmo < MagazineSize && SpareAmmo > 0) {
ReloadTimer();
IsReloading = true;
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Reloading..."));
}
}
// Prevents the user from firing faster than the firing rate
void ABaseWeaponClass::ResetFire()
{
OnFire();
CanFire = true;
}
void ABaseWeaponClass::FireTimer()
{
GetWorldTimerManager().SetTimer(FiringTimerHandle, this, &ABaseWeaponClass::OnFire, FireRate, true);
}
void ABaseWeaponClass::ReloadTimer()
{
GetWorldTimerManager().SetTimer(ReloadTimerHandle, this, &ABaseWeaponClass::OnReloaded, ReloadTime, false);
}
void ABaseWeaponClass::DelayTimer()
{
GetWorldTimerManager().SetTimer(SingleFireTimerHandle, this, &ABaseWeaponClass::ResetFire, FireDelay, false);
}
// Called every time the gun fires
void ABaseWeaponClass::OnFire()
{
if (MagazineAmmo > 0) {
MagazineAmmo--;
BurstAmt++;
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Ammo: " + FString::FromInt(MagazineAmmo) + " BurstAmt: " + FString::FromInt(BurstAmt)));
}
else if (MagazineAmmo == 0) {
OnEmpty();
Reset();
}
// Resets the firing sequence if BurstAmt reaches Burst
if (GetWorld() && BurstAmt >= Burst && Burst > 0)
{
Reset();
}
}
// Called when the use fires, but there's no ammo
void ABaseWeaponClass::OnEmpty()
{
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Empty!"));
}
void ABaseWeaponClass::OnReloaded()
{
int ammoChange = MagazineSize - MagazineAmmo;
MagazineAmmo += ammoChange;
SpareAmmo -= ammoChange;
IsReloading = false;
if (GEngine)
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Reloaded!"));
}
Here’s the header:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BaseWeaponClass.generated.h"
UCLASS()
class EXIMOD_API ABaseWeaponClass : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABaseWeaponClass();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Model")
class USkeletalMesh* Model;
// How fast the weapon fires
UPROPERTY(EditAnywhere, Category = "Settings")
float FireRate;
// How fast can the weapon fire again
UPROPERTY(EditAnywhere, Category = "Settings")
float FireDelay;
// How fast can you reload
UPROPERTY(EditAnywhere, Category = "Settings")
float ReloadTime;
// How many bullets are in a magazine
UPROPERTY(EditAnywhere, Category = "Settings")
int MagazineSize;
// How many bullets are left in the magazine
UPROPERTY(EditAnywhere, Category = "Settings")
int MagazineAmmo;
// How many spare bullets are left
UPROPERTY(EditAnywhere, Category = "Settings")
int SpareAmmo;
// How long the weapons bursts (0 = full auto, 1 = semi auto, 3 = 3-round burst etc)
UPROPERTY(EditAnywhere, Category = "Settings")
int Burst;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every time the gun fires
virtual void OnFire();
// Called when the gun fires and there's no round in the chamber
virtual void OnEmpty();
// Called when the main looping timer needs to be stopped, and when certain variables need to be reset
virtual void Reset();
// Called when the gun has finished reloading
virtual void OnReloaded();
void ResetFire();
void FireTimer();
void ReloadTimer();
void DelayTimer();
// The actual mesh in the world
class USkeletalMeshComponent* WeaponMesh;
FTimerHandle FiringTimerHandle;
FTimerHandle SingleFireTimerHandle;
FTimerHandle ReloadTimerHandle;
bool CanFire;
bool IsFiring;
bool IsReloading;
int BurstAmt;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Call this function to fire the gun
virtual void BeginFire();
// Call this function to stop the gun from firing
virtual void StopFire();
// Called when the gun starts to reload
virtual void StartReload();
};
Please bare in mind that this is the first time I’m ever using C++. Other than that I’ve got quite some experience in other languages if that matters.