Keep shooting while left mouse button is pressed

Hi.

MY SITUATION…

I’m building a game that has many weapons, some of them are automatic weapons other ones are not.

With ‘automatic weapons’ i mean all those weapons that shoot automaticallywhile the LeftMouseButton is held down.

Now, ANY weapon has its own FireRate

For automatic weapons, the FireRate is the interval between a shot and another (while the button is held down).
For ‘manual’ weapons, the FireRate is the interval between a shot and another (but requires the Player to click the button again)

How can I introduce this concept in my game?

I’ve already created a boolean variable bIsAutomatic in order to distinguish an automatic weapons from a manual one.

Now, the base class of ANY weapon in the game is Weapon, and derives from AActor

The latter has a virtual method called Fire() which performs the fire action.

**

HERE IS THE PROBLEM NOW…

**

Now I’d like to know how to implement this concept.

Obviously there should be an If-Statement

if(bIsAutomatic)
{ … }

else
{ … }

Mhm, with that said: how can I make the automatic weapons shoot while the button is pressed with a delay of X and how can I make the manual weapons shoot once the button is pressed?

Thanks in advance!

I don’t know it could be a very lame answer but did you try accessing the button pressed and button released things?? (That could work for the automatic part)

It’s what I’m trying to achieve, but I don’t know how in C++ with UE

Can you not use blueprints instead ?? its really easy to acheive what you want using them

No, actually I’m going to make this game with most C++ code possible

Ooh dayyum bro, we in the same boat hahah. I am also struggling trying to make my code and UE work together

Hello Gedamial,

The easiest way to do this would be using Timers. To give you an example, I’ve put together some code that I just added to the FirstPersonShooter template to get the desired “automatic” firing.

First, we need to make our timer handler and some extra functions just to make it more simple, so in the .h file I added:

FTimerHandle MyHandle;

void CreatePellet();

void OnReleaseFire();

After that, I moved to the .cpp file and added another input event to track when the fire button has been released.

InputComponent->BindAction("Fire", IE_Released, this, &AMyProjectCharacter::OnReleaseFire);

I then took all logic from the “if (ProjectileClass != NULL)” in te OnFire function and cut/paste that into the implementation for our new CreatePellet() function.

void AMyProjectCharacter::CreatePellet()
{
	const FRotator SpawnRotation = GetControlRotation();
	// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
	const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

	UWorld* const World = GetWorld();
	if (World != NULL)
	{
		// spawn the projectile at the muzzle
		World->SpawnActor<AMyProjectProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
	}
}

In the “if” statement that we took this code out of, we need to replace it with a call to that function, but to do this we’ll set up a timer so that it repeats.

GetWorldTimerManager().SetTimer(MyHandle, this, &AMyProjectCharacter::CreatePellet, 0.5f, true);

And lastly, we’ll set up the release event which will simply clear the timer.

void AMyProjectCharacter::OnReleaseFire()
{
	GetWorldTimerManager().ClearTimer(MyHandle);
}

After this, you should be good to go! The only thing that will be odd is that the Recoil isn’t involved in this so only the pellet will be spawned after the initial fire, but you could move that code over as well if you wish as this was only for demonstration purposes. As for your rate of fire, the “0.5f” in the SetTimer function is the time between function calls, so you could replace that with your rate of fire.

Hope this helps!

1 Like

Not at the moment other than doing it manually by just translating your logic to C++. There is a feature that will be coming in the future that will allow you to do this but it will be a while before that is implemented.

Hello, thanks for the answer.

This is what I did before your answer:

I’d like to “convert” that blueprint algorithm in C++ code.

Is that possible? How?

Ok, I tried your solution and it works fine :smiley:

But will you explain me the exact task of these function calls?

GetWorldTimerManager().SetTimer(MyHandle, this, &AMyProjectCharacter::CreatePellet, 0.5f, true);

////////////////////////////////

GetWorldTimerManager().ClearTimer(MyHandle);

And why do we need a FTimerHandle?

Thanks!

These are used to set up Timers, which if you’ve used them in Blueprints, these are akin to the “Set Timer by Handle” node. The “Set Timer by Function Name” is more commonly used but I prefer using the “By Handle” in code as it allows the timer to be referred to by the handle, which could be passed to other functions/classes if needed. There are 5 different implementations of SetTimer in code, so choose which one works best for you.

To explain it simply, the SetTimer function is (in the order of the parameters shown) setting the timer to the handle “MyHandle”, calling the timer on “this”, everytime the timer executes it calls “CreatePellet”, which it does every 0.5 seconds, and the “true” makes it loop.

The ClearTimer function just clears the timer that is bound to the handle “MyHandle” so that it stops looping.

You can find more information here: