I have a portal scene, the portal scene is an area2D node with a collisionShape2D as its child. I have two portals in my game and I need the player to teleport back and forth between the two portals, the idea is if the player touches one of the portals then he’ll appear next to the other portal.
To solve this problem, I made this script:
extends Area2D
@export var portalPath : NodePath
var linkedPortal : Area2D
func _ready():
linkedPortal = get_node(portalPath)
func _on_body_entered(body):
if body.name == "Player":
body.position = linkedPortal.global_position
But now I have another problem, when the player enters the portal it is indeed teleported to the other’s location, but then it starts to teleport back and forth without letting the player move
I would teleport the player some pixels to the right or to the left, to avoid immediate collision with the teleporter.
Or maybe activate the teleport with a key press (usually UP)?
Similar to what @hr78 said, I would think of all portals as “one-way” and two “linked” portals merely teleporting adjacent to each other. Make linkedPortal take a Node2D instead of an Area2D so you may teleport to any defined location, like with a Marker2D.
You could set something like just_teleported = true and never teleport if that’s true. Once they stop overlapping (e.g. the player moves away from it) you set it to false and that will allow them to teleport again.
You could also put it on a timer. If the player stands in one place for 5 more seconds maybe they want to teleport back.
If you add a teleporting variable to the player, you can prevent the back and forth teleporting like this:
func _on_body_entered(body):
if body.name == "Player":
body.teleporting = not body.teleporting
if body.teleporting:
body.position = linkedPortal.global_position
This example is based on the assumption, that every teleporter is connected to another teleporter. If a teleporter moves the player to a location without another teleporter, the teleporter variable will get stuck to true, and next teleporter won’t work properly. So this is a very simple but not the safest or most flexible solution.
edit: I managed to simplify the code even further.
The problem here is that the collision shape detects the player when it enters, but keeps executing the same code over and over again while the player is inside the collisionShape.
Is there a way to detect just the moment the user enters, and if the user stays inside the collisionShape stop executing the code