Triggering an input once

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By keke
:warning: Old Version Published before Godot 3 was released.

Sorry if this is too simple, but…
I want an event to trigger when a key is pressed and/or released, but not keep triggering while the key is pressed/released. I can do this manually with something like the following:

if(Input.is_action_pressed("player_shoot")):
		if(!just_fired):
			missile_launcher.launch(state)
		just_fired=true
	else:
		just_fired=false

But I was wondering if there’s a better (built into godot) way…

There are many answers for that already, some…:

And the development version has an experimental just pressed and just released, but has some issues with modifier keys.

eons | 2016-12-29 12:55

:bust_in_silhouette: Reply From: DriNeo

You can write the code into _input() function instead. Like this example.

func _input(event):
 if(event.is_action_pressed("ui_select")):
  print("Action pressed !")

This code prints the message only once.

I made the test. The message is displayed only once no matter the press duration.
Maybe my code has a hidden drawback ?

DriNeo | 2016-12-29 23:51

You are right, it is weird, used to work that way, no idea when or what changed.

I’ve hidden my answer to prevent confussion, will keep testing on this to be sure.

eons | 2016-12-30 02:03

If someone hasn’t figured this out yet, I’d like to help: You need set_process_input(true) at func _ready()

func _ready():
	set_process_input(true)

func _input(event):
	#this event is called once per key-press
	if event.is_action_pressed("ui_accept"):
		# do stuff
		print("You pressed ui_accept key!")
    #you can have different key-presses checked here
	elif event.is_action_pressed("ui_cancel"):
		# do other stuff
		print("You pressed ui_cancel key!")

Jukepoks1 | 2016-12-30 16:27

@Jukepoks1 I’m just confused because actions are not reporting any echo, maybe I’m mistaken and that only happens with key press…

eons | 2016-12-30 16:57

Thanks!
Using the event argument instead of Input. for my actions fixed a lot of my input problems.

Stygian | 2017-10-10 08:47

:bust_in_silhouette: Reply From: Nutr1z

Hi,

I saw your sample code and I guess you are trying to limit the shot rate of a weapon. I will show you one solution I use, others are possible.

I use a Timer node with mode One shot and allow the player to shot only if time left of timer is equal to 0. In the if (when allowed to shot) I set the wait time of timer to the shooting rate expected and re start the timer.

if (Input.is_action_pressed("shot") and get_node("BulletTimer").get_time_left() == 0):

    # some shot code....

	get_node("BulletTimer").set_wait_time(SHOOTING_RATE) # set the new wait time for the time
	get_node("BulletTimer").start() # restart the timer

Timer node :
Process mode : Idle
Wait time : 0.01
One shot : checked
Autostart : checked

Wait time to 0.01 and Autostart checked is only here for the start of the game, before the first shot ! After the first shot you manage it by code

:bust_in_silhouette: Reply From: YeOldeDM

This is not much different than what you have, but might work/look a little better.

var shot_held = false


func _process(delta):
	var SHOOT = Input.is_action_pressed('player_shoot')

	if SHOOT and not shot_held:
		weapon.shoot() # do whatever you do when you shoot

	shot_held = SHOOT

This will give you that ‘semi-automatic’ input behavior. The shoot action will only trigger once per time the action is pressed, but will fire as quickly as the player can press that input.