I need help in making a projectile charge the longer I hold a button

Godot version: 4.1.3.stable


I making a top down shooter and I need help in programming a projectile to charge up the longer I hold the shoot button. I need the player to hold down the shoot button and charge their projectile so that it flies further. If you tap the shoot button it will fire but will not go very far.

If someone can provide a step by step on creating this feature because I have been banging my head against cement for the past 2 days.

Thank you!

What’s your code for firing the projectile? You can use a timer variable to make the initial force stronger the longer the button is held down. Set the variable to 0 when the button is pressed and add delta each frame. Fire the projectile when the button is released.

Writing this ad-hoc without checking for any syntax errors, but it should give you an idea.

var charging := false
var charge_start_time : float
var max_charge_power_time := 2000 # msec, 1000 = 1 second
var min_charge_power: 100 # this could be speed of bullet or damage or w/e "power" means to you
var max_charge_power: 500

func _process(delta):
	if Input.is_action_pressed("your_shoot_button_here") and charging == false:
		charging = true
		charge_start_time = Time.get_ticks_msec()

	if Input.is_action_just_released("your_shoot_button_here"):
		charging = false
		_shoot(charge_start_time, Time.get_ticks_msec())

	return power

func _shoot(charge_start: float, charge_end: float):
	var power = _calc_shot_power(charge_end - charge_start)

	# now just shoot projectile with this calculated power

func _calc_shot_power(charge_duration):
	var charge_percentage = (charge_duration) / max_charge_power_time # will be from 0 to 1+
	if charge_percentage > 1:
		charge_percentage = 1 # can't charge past 100%

	var power = min_charge_power + charge_percentage * (max_charge_power - min_charge_power)

Then if you have some progress bar to display charging power to the user, just do:

@onready var p_bar: ProgressBar = $PATH_HERE

func _ready():
	p_bar.min_value = min_charge_power
	p_bar.max_value = max_charge_power

and modify the first part of your _process to be:

	if Input.is_action_pressed("your_shoot_button_here"): 
		if charging == false:
			charging = true
			charge_start_time = Time.get_ticks_msec()

		p_bar.value = _calc_shot_power(Time.get_ticks_msec() - charge_start_time)