How do I create a Zelda-like Charged Spin Attack?

Godot Version
4.2.1

Question
Hi. I am trying to create a Spin-Attack where you have to press and hold down the attack button to charge up for a few seconds I have a Timer node setup for this, then once the timer has reached 0 you can let go off the attack button in order to perform the attack like in Zelda, but if you let go of the button before the timer has reached 0 then it won’t do anything, that’s how I want it work. But I am having trouble getting this to work here is the problem, as soon as I let go of the attack button, it performs the Spin-Attack immediately before the timer has reached 0 I don’t want that, i’ve tried using if statements but that dosen’t seem to do anything. I am still quite new to Gdscript, I would appreciate some help, what do I need to do in order for this to work?

Here is the code

if Input.is_action_just_pressed("attack") and !isBlocking:
		if !isSpinning:
			attack()
			if !isShooting:
				isShooting = true
				fire_sword_beam_ability()
				swordBeamCooldownTimer.start()
				await swordBeamCooldownTimer.timeout
				isShooting = false
		
	if Input.is_action_pressed("attack") and isCharging == false and !isAttacking:
		isCharging = true
		animations.play("charge_" + lastAnimDirection)
		chargeTimer.start()
		
	if Input.is_action_just_released("attack") and !isAttacking:
		if !chargeTimer.timeout:
			isCharging = false
			chargeTimer.stop()
			return
		elif chargeTimer.timeout:
			isCharging = false
			chargeTimer.stop()
			spin_attack() 

Given your description of the current behaviour of your system, I can only assume that the code snippet you’ve provided is incorrectly formatted - this code would not produce what you’re experiencing. Formatting errors makes it very hard to debug.

Can you please confirm the validity of the code you’ve posted. Does it have the right indentation?

It would also be nice if you could provide a more complete snippet of code. It’s important to know where the code is running. Is it in _ready(), _process(), or some other place?

I am actually not using _process(), but here is what is in _ready() , _physics_process(), handle_input is where I have all the code from above

func _ready():
	effects.play("RESET")


func _physics_process(_delta: float):
	handle_input()
	move_and_slide()
	update_animation()
	if direction.length() != 0:
		bow.rotation = direction.angle()


func _process(_delta):
	pass

Okay. And…

Validity, what does that mean?

I’m just trying to figure out whether the initial code you posted matches what you have in your project. Indentation matters as it indicates where code is in relation to other statements.

Assuming that your initial code snippet is incorrectly formatted, I believe you’re using timeout incorrectly. timeout is a signal, not a bool state (it does not return whether the timer has completed). Use this condition instead:

if chargeTimer.time_left <= 0:
1 Like

This is all the child nodes that are on the player scene, and I have a reference to the Timer node as a variable, if that is what you’re asking for?


if chargeTimer.time_left <= 0:

Ok I just tried it, that seems to have solved the issue, thank you :+1:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.