0 votes

Alright. First time working in Godot. I've tried solving this via tutorials and docs, previous posts but nothing is working. Working on making a simple game to learn the process. It's all in 2D.

The game: KinematicBody2D (player controls) try's to knock a ball (KinematicBody2D, not controlled) into a goal. The goal is created by making a gap in the walls, so only a small part of the rectangular arena allows the ball to pass through, there is art to show the entrance of the goal, but the actual Area2D box representing the goal is not in the scene. I want to use a signal to connect the action of passing through the goal to initiate the next level.

What I've tried (and not succeeded with):
I made a Sprite with Area2D I titled Hitbox, and a CollisionShape as children of the Sprite. I placed the shapes at the line between goal and arena.

Here is my script:

extends Sprite

func onHitboxbodyentered(body) -> void:
if body.isingroup("ObjectGroup"):
gettree().changescene("res://Level" + str(int(gettree().current_scene.name) + 1) + ".tscn")

I have the ball titled Object and in a group called ObjectGroup
I have all the Levels titled Level1, Level2,Level_3, etc (I got this idea for the level change from a youtube video)

I've also tried the following script

extends Sprite

func onhitboxareaentered(area: Area2D) -> void:
if area.isingroup("Object"):
gettree().changescene("res://Level" + str(int(gettree().current_scene.name) + 1) + ".tscn")

When I run the project, the ball goes through the goal, but the level does not change. I have the signal connecting the Hitbox to the Sprite, and I've loaded the above scripts into the sprite. I have the sprite in each scene, connected to the Node at the base of the level.

Happy to provide more info, I hope I provided enough. I'm very new to this, assume I don't know/understand. Thank you in advance!

Godot version v3.3.stable.official
in Engine by (12 points)

1 Answer

0 votes

If your ball is a kinematic body, then area_entered signal won't get triggered because that signal is for other areas only. You should keep using body_entered.

the ball goes through the goal, but the level does not change

To me, it seems like either the signal is not being emitted, or the condition (is_in_group) is not true. Make sure that the signal and the condition are working properly using print().
So you can try something like this:

extends Sprite

func _on_Hitbox_body_entered(body) -> void:
  print("Signal Triggered!")
  if body.is_in_group("ObjectGroup"):
      print("Condition Passed!")
      get_tree().change_scene("res://Level" + str(int(get_tree().current_scene.name) + 1) + ".tscn")

You can also use assert to check if the condition returns true or not, however that'll pause the execution if the condition happens to return false.


Hopefully that'll give you a better idea of what the issue is.

If the issue is with the signal:

  • Make sure you're using the correct signal (body_entered).
  • Make sure the signal is connected properly (you should see a green signal icon to the left side of the method).
  • Check the collision layer/mask of both the goal area and the ball body.
    Here's a short 10min video by GDQuest about layers and masks, if you're not familiar with them.

If the issue is with the condition, you can either double check your groups and make sure that everything is set up properly or instead of checking the group, check the class.
To do that, load/preload your ball script into a variable or constant. Then use is to check if body extends the ball script:

extends Sprite

const Ball = preload("ball.gd")

func _on_Hitbox_body_entered(body) -> void:
  print("Signal Triggered!")
  if body is Ball:
      print("Condition Passed!")
      get_tree().change_scene("res://Level" + str(int(get_tree().current_scene.name) + 1) + ".tscn")

Alternatively, you can use the class_name keyword in your ball script if you don't want to load it into a variable first.

extends KinematicBody2D
class_name Ball

However, that'll make ball.gd become available when adding new nodes to the scene because class_name adds the script as a new type to the editor.

by (180 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.