Creating a overheating weapon

Hello everyone,

So im looking to create a weapon on my ship that essentially can shoot up to X seconds then needs to cool down and you can begin shooting again, I am just having a hard time I guess “Conceptualizing” how I should go about doing this? Should I use timers? What should I be checking? I have done a bit of work but im not too sure if I am on the right path or not, some examples would be awesome if possible, it would really help me to understand the flow.


/* Weapon Properties */
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon")
		FName MuzzleSocketName;
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon")
		float WeaponFireRate;
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon")
		float WeaponCurrentFiringTime;
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Weapon")
		float WeaponMaxFiringTime;
	UPROPERTY(EditDefaultsOnly, Category = "Weapon")
		class AAuroraBaseProjectile* ProjectileClass;
		bool isExhausted;


void AAuroraBaseShip::OnFireStart()
{
	// Location and Rotation of firing socket
	FVector muzzleLocation = Mesh->GetSocketLocation(MuzzleSocketName);
	FRotator muzzleRotation = Mesh->GetSocketRotation(MuzzleSocketName);

	// Firing
	if (ProjectileClass != NULL && !isExhausted)
	{
		UWorld* const World = GetWorld();
		if (World)
		{
			FActorSpawnParameters SpawnParams;
			SpawnParams.Owner = this;
			SpawnParams.Instigator = Instigator;

			World->SpawnActor<AAuroraBaseProjectile>(ProjectileClass, muzzleLocation, muzzleRotation, SpawnParams);
			GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Green, TEXT("Firing Weapon!"));
		}
	}
}

I’d probably create:

float Heat
bool bIsCoolingDown

Don’t fire if (bIsCoolingDown)
When you do fire, increment Heat. If Heat is > 1.0 then bIsCoolingDown = true;
In your tick I’d decrement Heat like Heat -= CoolDownRate * DeltaSeconds;
then check if (Heat < 0.0) then bIsCoolingDown = false;

There’s probably a variety of ways to do this, however to give some basic pseudo code from AusPaco’s idea:


void Tick()
{
	// Gun exhausted, decrease Heat
	if (isExhausted)
	{
		Heat -= someHeatTime * DeltaSeconds;
		if (Heat <= 0.f)
			isExhausted = false;
	}
	else
		FiringGun();
}

void FiringGun()
{
    Heat += someHeatTime * DeltaSeconds;
    if (Heat > 1.0f)
        isExhausted = true;
}

I replied too late, I second this way, as simple and clean as it gets.

What about creating a weapon that shoots in full auto? Is my function in my OP suited for it im assuming I need a timer of some sorts?

You could use a timer… I tend to do things manually in the Tick function. You could do something similar to the Heat variable but have it as Reload, so before firing you’d check !bIsCoolingDown and !bIsReloading fex.

Alright so I got my firing function now (Without overheating, that im doing later) but spawning my projectile is not working, is anyone seeing anything im doing wrong all the references I am going to is telling me to do it this way even the FPS templete in UE4


void AAuroraBaseShip::OnWeaponFire()
{
	FVector MuzzleLocation = GetMesh()->GetSocketLocation(MuzzleSocketName);
	FRotator MuzzleRotation = GetMesh()->GetSocketRotation(MuzzleSocketName);

	if (ProjectileClass != NULL)
	{
		FActorSpawnParameters SpawnParams;
		SpawnParams.Instigator = Instigator;
		SpawnParams.Owner = this;
		GetWorld()->GetTimerManager().SetTimer(timeHandler, this, &AAuroraBaseShip::OnWeaponFire, WeaponFireRate, false);
		GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Green, TEXT("Firing"));
		UWorld* const World = GetWorld();
		World->SpawnActor<AAuroraBaseProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
	}
}

void AAuroraBaseShip::OnWeaponFireStop()
{
	GetWorld()->GetTimerManager().ClearTimer(timeHandler);
}

I keep getting this error


Error	1	error C2664: 'T *UWorld::SpawnActor<AAuroraBaseProjectile>(UClass *,const FVector &,const FRotator &,const FActorSpawnParameters &)' : cannot convert argument 1 from 'AAuroraBaseProjectile *' to 'UClass *'

What is your definition of ProjectileClass ?

Im at work currently so I cant see exactly what I did but im almost 99.8% sure its this


UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = General)
class AAuroraBaseProjectile* ProjectileClass;

That’s your issue then. The SpawnActor function is expecting the first argument to be a pointer to a type of UClass, but you’re passing it a pointer to an object (not the class of the object)

I’d try changing your definition to be something like:

TSubclassOf<AAuroraBaseProjectile> ProjectileClass;

Or otherwise you could try using something like ProjectileClass::StaticClass()