Interaction with an object while in its "area 2D"

I want to make it so that when a player enters an area with an NPC and presses the interaction button, the NPC starts talking. When I did it myself, it turned out that when the player pressed interaction, he could talk to the NPC from any point on the map.

Hi,

Hard to say without more context (code or screenshots), but it seems to me you need to hook some logic to the NPC’s Area2D signals.
See area_entered and area_exited (Area2D — Godot Engine (stable) documentation in English): when the area is “entered”, store the info that the player can interact somewhere, and when it is “exited”, do the opposite. You can use a bool variable to do so. Then, based on the variable value, you know if the player can interact or not!

1 Like

I think I misunderstood something, because what happens is that “true” only works at the moment of “entering” the area, that is, when the player is inside the area and presses the “use” button, nothing happens, there is only a split second for the player to press the button and the action to work.
Could you tell me how to fix this in the code?
(I would like to attach a video with a detailed explanation of the problem, but Godot does not allow new users to attach videos).

Added a timer to have more time to press the “use” button, but it did not help with my problem :frowning:

extends Node2D
@onready var anim = $AnimatedSprite2D
var reu = false

func _process(delta):
if reu == true:
print(“reu == true”)
if reu == false:
print(“reu == false”)

func _input(event):
if Input.is_action_just_pressed(“use”):
reu = true
await get_tree().create_timer(1).timeout
reu = false

func _on_area_2d_2_body_entered(body):
if body.has_method(“player”):
anim.play(“default”)
if reu == true:
get_tree().change_scene_to_file(“res://mines.tscn”)

func _on_area_2d_2_body_exited(body):
if body.has_method(“player”):
anim.play(“new_animation”)

In your code, you’re doing your interaction code inside the _on_area_2d_2_body_entered function, which is wrong. Think about it: do you want to do your interaction logic when entering an area? No. You want to do it when pressing a key. But, you also have one condition: you need to be inside an area, and that you should do in the _on_area_2d_2_body_entered, only to store the info that you entered an area and nothing more.

Here’s what you need to do in more details:

  • Declare a bool variable in your script, called something like “is_in_area”.
  • When an area is entered, set the variable to true. When an area is exited, set the variable to false. The boolean is never set somewhere else.
  • When pressing the use button, just check the variable value.

Something like this:

var is_in_area: bool = false

func _input(event):
    if Input.is_action_just_pressed(“use”):
        if is_in_area:
            print("Do something!")

func _on_area_2d_2_body_entered(body):
    is_in_area = true

func _on_area_2d_2_body_exited(body):
    is_in_area = false

I did not test the code, I wrote it on the fly so you may have to adjust some things. Let me know if that helps!

2 Likes

This works exactly as I wanted))) Thank you very much. Without you I would have been messing around with this for another week.

1 Like