godotengine / godot-docs

Godot Engine official documentation
https://docs.godotengine.org
Other
3.77k stars 3.07k forks source link

First 2D game: acessing group produces error, no mention of scene/global groups #9802

Closed gerritnowald closed 6 days ago

gerritnowald commented 3 weeks ago

Your Godot version: 4.3

Acessing group produces error, no mention of scene/global groups

URL to the documentation page: https://docs.godotengine.org/en/stable/getting_started/first_2d_game/06.heads_up_display.html

For me the grouping of the mobs and removal does not work. Everything else did work perfectly so far. First of all, there now are scene groups and global groups, which are not mentioned in the tutorial.

I did everything like described, but when I test the game it crashes and I get an error

0:00:07:0613 main.gd:30 @ _on_score_timer_timeout(): Node not found: "HUD" (relative to "/root/Main").
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> scene/main/node.cpp:1792 @ get_node()
main.gd:30 @ _on_score_timer_timeout()

Which is strange, because it seems unreleated to the removal of the creeps.

When I comment out the line

 get_tree().call_group("mobs", "queue_free")

in new_game(), everything else works fine (except the removal of the creeps of course).

Both scene group and global group produce the same error.

Piralein commented 3 weeks ago

The error states: In your function called _on_score_timer_timeout() in your main.gd, you try to access a node with the path root/Main/HUD, which doesn't exist.

Please make sure you placed your HUD node as a child of the Main node.

gerritnowald commented 3 weeks ago

@Piralein thank you, yes I understand the error. HUD is a child of Main. Everything works fine. But when I add get_tree().call_group("mobs", "queue_free") I get the error, which seems completely unrelated to the HUD.

Here is my complete main.gd:

extends Node

@export var mob_scene: PackedScene
var score

func _ready():
    #new_game()
    pass

func new_game():
    score = 0
    $Player.start($StartPosition.position)
    $StartTimer.start()

    $HUD.update_score(score)
    $HUD.show_message("Get Ready")

    #get_tree().call_group("mobs", "queue_free")

    $Music.play()

func _on_start_timer_timeout() -> void:
    $MobTimer.start()
    $ScoreTimer.start()

func _on_score_timer_timeout():
    score += 1
    $HUD.update_score(score)

func _on_mob_timer_timeout():
    # Create a new instance of the Mob scene.
    var mob = mob_scene.instantiate()

    # Choose a random location on Path2D.
    var mob_spawn_location = $MobPath/MobSpawnLocation
    mob_spawn_location.progress_ratio = randf()

    # Set the mob's direction perpendicular to the path direction.
    var direction = mob_spawn_location.rotation + PI / 2

    # Set the mob's position to a random location.
    mob.position = mob_spawn_location.position

    # Add some randomness to the direction.
    direction += randf_range(-PI / 4, PI / 4)
    mob.rotation = direction

    # Choose the velocity for the mob.
    var velocity = Vector2(randf_range(150.0, 250.0), 0.0)
    mob.linear_velocity = velocity.rotated(direction)

    # Spawn the mob by adding it to the Main scene.
    add_child(mob)

func game_over():
    $ScoreTimer.stop()
    $MobTimer.stop()

    $HUD.show_game_over()

    $Music.stop()
    $DeathSound.play()
Piralein commented 3 weeks ago

Is it possible your HUD node is part of the mobs group and gets freed in your new_game function?

gerritnowald commented 3 weeks ago

Yes this was it! There was also a group mobs in Main , which then also contained the HUD because it is a child of Main.

I think this happened because I first created a global group. The tutorial should be updated in the regard that a scene group has to be created instead of a global group.

Thank you!