Timer only working on autostart

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By NPC______

I have a Boss in my game who is supposed to bounce up and down the screen, activate after a specific score, and shoot a fireball after a timeout. Everything but the attack works. The attack works partially. This is because when I autostart the attack timer, it works no problem. But when I try and activate it in the code, it refuses to work. All of my signals are connected and don’t know why it is not working.

Here’s my code:

Note: any things that relate to the instance node is a signal connected to the game’s code.

Edit: I found that when I have the timer (known as $Attack.start() ) in the code and have autostart on, the timer disables itself. I also thought maybe changing the name to just timer, as my attack had a similar name. But this had made no difference

Boss code

extends KinematicBody2D

var attack1 = preload(“res://Characters/Enemies/Units/Blastboss.tscn”)
var complete = preload(“res://Misc/stage cleaner.tscn”)
export (int) var speed = 30
var health_var = 20
var point_value = 100
var direction = 1
var velocity = Vector2()
var fire = false

signal instance_node(node, location)

func _physics_process(_delta):
if Global.score >= 3:
$Attack.start() <----- does not work
velocity.y = speed * direction
if is_on_wall():
direction = direction * -1
if health_var <= 0:
Global.score += point_value
emit_signal(“instance_node”, complete, global_position)

func _on_hurt_timeout():

func _on_hitbox_area_entered(area):
if area.is_in_group(“Enemy_Damager”):
health_var -= 1
if area.is_in_group(“Secret”):
health_var -= 2
if area.is_in_group(“Flash”):
health_var -= 5
if area.is_in_group(“Power”):
health_var -= 3

func _on_Attack_timeout():
emit_signal(“instance_node”, attack1, $Position2D.global_position)

Game’s code

extends Node2D

func _ready():
Global.game = self

func _exit_tree():
Global.game = null

func _on_create_particles_enemy(particles, location):
var particles_instance = particles.instance()
particles_instance.global_position = location

func instance_node(node, location):
var node_instance = node.instance()
node_instance.global_position = location

:bust_in_silhouette: Reply From: IvanVoirol

In your code, you declare the variable Attack :

var Attack = preload("res://Characters/Enemies/Units/Blastboss.tscn")

But then when you call the start() function, you don’t call it from this variable :


which is the equivalent of get_node(Attack).start()
This means you don’t use the variable Attack, but instead try to get the node Attack, which I guess doesn’t exist in your project.
So try to replace $Attack.start() with Attack.start()

Also, if you have the motivation, you should look into the style guide, to learn about the naming conventions. When naming a variable use the snake_case, and when naming a node use the PascalCase. Using these conventions, you could have seen that you didn’t use the variable, but called a node (so in your example, you should name your variable attack)

Sorry for late response but Attack was the name of the timer. It was a little confusing considering the variable was also named Attack. I changed the variable name now to attack1.

NPC______ | 2020-08-25 00:11

And is it working?
If not, send me your project so I can have a better understanding of it.

IvanVoirol | 2020-08-25 06:43

Do not worry I have figured it out. The problem was that it wasn’t being protected from the physics process delta which happens every frame if I’m not mistaken. This means the timer was being reset every frame and therefore, would never time out. I was told to do if $Attack.is_stopped():
$Attack.start(). This fixed the issue and protected it from the physics process

NPC______ | 2020-08-25 21:55