I’m attempting to create scene transitions to advance through levels in my game. However, the scene transition is not working currently, since it’s not detecting the player entering the area. Below is my code for the “exit” class, based on the tutorial found here (https://www.youtube.com/watch?v=FuIn_1aK7rM&list=WL&index=100&t=161s):
extends Area2D
var entered = false
func _on_body_entered(body: PhysicsBody2D):
entered = true
print("entered")
func _on_body_exited(body):
entered = false
func _physics_process(_delta):
if entered == true:
if Input.is_action_just_pressed("interact"):
get_tree().change_scene_to_file("res://levels/level_2.tscn")
print("exit found")
I have “interact” bound to E and the exit is an Area2D with a CollisionShape2D child node. The Area2D::body_entered() and Area2D::body_exited() are connected to my _on_body_entered() and on_body_exited() functions. The goal of this code is essentially to detect if the player has entered the collision shape and if they have entered it and pressed “interact”, then the player advances to the next level.
P.S. for the game I’m making it might be ideal to not require the player to interact with the exit and just have the scene change if the player enters the collision shape.
It might be a good idea to check for a group. I’m not sure if that’s causing the issue, but if another object enters and exits the area 2D while the player is inside, it could turn the “entered” bool off.
Also try adding a red circle to the left of the line number to make sure the code is running. Printing the line will do the same thing, but it could be handy.
I’ve tried using print statements as well as break statements, but the _on_body_entered just doesn’t get called. Though I did find something interesting after changing the code around a bit - when the CollisionShape2D was touching the walls, it triggered a scene change, but when the player entered the CollisionShape2D, the scene change was not triggered. Here’s the new code:
extends Area2D
# ref: https://www.youtube.com/watch?v=sKqtCc_HykM
# TODO make this object oriented
@export var connected_scene: String
@onready var player = $"../Player"
var levels_folder = "res://levels/"
func _on_body_entered(body):
print("exit found")
if body == player:
print("player found exit")
var full_path = levels_folder + connected_scene + ".tscn"
var scene_tree = get_tree()
scene_tree.call_deferred("change_scene_to_file", full_path)
func _on_body_entered(body):
if body is Player:
entered = true
print("entered")
func _on_body_exited(body):
if body is Player:
entered = false
print("exited")
Add class_player Player in the player script after extends
What type of node is the player? If the player extends StaticBody2D, it’s not detected by Area2Ds, even though it inherits PhysicsBody2D. This wasn’t a problem in 3.x, but now that move_and_collide() is in PhysicsBody2D, some users may want to use StaticBody2D for movable objects. This can be solved by adding an Area2D node to the player and using it for detecting other Area2D nodes.
If that wasn’t the problem, the only other thing I can think of is that there’s something wrong with collision layers/masks.