Flashlight Toggle

Hey everyone hope someone out there can help, I have a flashlight mechanic set up and it works but my problem is that the light doesn’t toggle on/off with a key press (F) I have to hold F for the light to turn on and once I let go the light will turn off.

In my SleepCharacter.h

   protected:
    
        /** Toggle Flashlight on*/
    	void FlashlightOn();
    
    	/** Toggle Flashlight off*/
    	void FlashlightOff();

public:
	ASleepCharacter();

    /** See if flashlight is currently on */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Character)
	bool IsFlashlightOn;

    /** Get the current amount of Flashlight battery available */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Character)
	float FlashlightPower;

In my SleepCharacter.cpp

// Set up Flashlight variables
	IsFlashlightOn = false;
	FlashlightPower = 100;

// Create a FlashLightComponent
	FlashLightComponent = CreateDefaultSubobject<USpotLightComponent>(TEXT("Flashlight"));
	FlashLightComponent->SetupAttachment(FirstPersonCameraComponent);
	FlashLightComponent->RelativeLocation = FVector(10, 0, 4.f);
	FlashLightComponent->AttenuationRadius = 1000.f;
	FlashLightComponent->bAffectsWorld = true;
	FlashLightComponent->SetMobility(EComponentMobility::Movable);

void ASleepCharacter::BeginPlay()
{
	// Call the base class  
	Super::BeginPlay();

	FlashlightOff(); // Start the game with the flashlight off
}

void ASleepCharacter::Tick(float DeltaTime)
{
	if (IsFlashlightOn)
	{
		if (FlashlightPower > 0)
		{
		FlashlightPower -= 0.3f;
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("ON"));
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::White, FString::FromInt(FlashlightPower));			// NEED TO CHANGE TO A TOGGLE PRESS
		}
	}

	else if (!IsFlashlightOn)
	{
		if (FlashlightPower < 100)
		{
			FlashlightPower += 0.5;
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Blue, TEXT("OFF"));
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Black, FString::FromInt(FlashlightPower));
		}
	}
	
	if (FlashlightPower <= 0)
	{
		FlashlightOff();
	}
}

void ASleepCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	// set up gameplay key bindings
	check(InputComponent);
InputComponent->BindAction("Flashlight", IE_Pressed, this, &ASleepCharacter::FlashlightOn);
	InputComponent->BindAction("Flashlight", IE_Released, this, &ASleepCharacter::FlashlightOff);
}

void ASleepCharacter::FlashlightOn()
{
		IsFlashlightOn = true;
		FlashLightComponent->ToggleVisibility("Flashlight");
}

void ASleepCharacter::FlashlightOff()
{
		IsFlashlightOn = false;
		FlashLightComponent->ToggleVisibility("Flashlight");

}

That is all the code relating to the Flashlight, I have been stumped for a few days now, when I hold F the flashlight will come on and when I release it will turn off. But like I said before I want it to toggle so when you press F once the flashlight will come on and the FlashlightPower will decrease, if you press F again then the light will turn off and recharge.

I hope the question is clear and the code is easy to read, I hope someone can help with this too :slight_smile:

Thanks for taking a look.

In your input instead of doing when you press and when you release do when you press you call a function that toggles the flashlight…

//In input
InputComponent->BindAction("Flashlight", IE_Pressed, this, &ASleepCharacter::FlashlightToggle);

void ASleepCharacter::FlashlightToggle()
{
     IsFlashlightOn = !IsFlashlightOn;
     FlashLightComponent->ToggleVisibility("Flashlight");
}

Or something close to that.
That way your not looking at a release event when it doesn’t matter if they release the key or not.

Your input bindings are calling this functions on the Flashlight Action Event. FlashlightOn() is called on IE_Pressed (when the key first goes down) and FlashlightOff() is called on IE_Released (when the key comes back up). Thus you’re getting exactly what you’re code says.

To do a toggle instead, you can remove your on/off bindings and replace them with a single binding for flashlight toggle, wherein you toggle the state of IsFlashlightOn

void ASleepCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
  // ...
   InputComponent->BindAction("Flashlight", IE_Pressed, this, &ASleepCharacter::FlashlightToggle);
   //...
}


 void ASleepCharacter::FlashlightToggle()
 {
         IsFlashlightOn = !IsFlashlightOn
         //FlashLightComponent->ToggleVisibility("Flashlight"); 
         //May need to move this ^ to Tick() or timer; it could work here, but haven't tested
 }

@ChunkinFlubber Thank you this worked perfectly, yours and @DesertEagle_PWN are nearly exactly the same so I will have accept yours as the answer since you answered first, I was trying to flip the IsFlashlightOn bool earlier with no success but this worked perfectly, again thank you so much :slight_smile: EDIT: Sorry got mixed up! brain is still scattered.

@DesertEagle_PWN Thank you this worked perfectly, yours and @ChunkinFlubber are nearly exactly the same so I will accept his as the answer as he was first to reply, thank you so much for the help :slight_smile:

sounds good yeah we do have the same but i do believe I did post first but its no contest its all about the help. Glad to help!

Of course :slight_smile: the speed at which I got help is amazing, the programming community continues to amaze me. Thanks again :slight_smile:

NP; Glad I could help :slight_smile:

Thank you again really appreciate it :slight_smile: