Best way to CONSTANTLY check if something is in an Area?

Godot Version

Godot 4

Question

Hello! It might be a very stupid question but, how should i check if something (a Body (CharacterBody, RigidBody etc.) for example).
I need to make it so once my character is in the Area, when I press “E” he Is able to take an item, but it then needs to constantly see the body in the Area, a thing that _on_body_entered does not do.

The only way around I found is to make it so that on_body_entered a “item1Interactable” variable becomes true, and it becomes false _on_body_exited and the variable is true and I press “E” i take the item.

But I wanted to know if there is a better way to do so, as it becomes very confusing even with very specific names for the variables.

1 Like
  1. Use a ShapeCast node or RayCast node on your player as the detector. (You can use it to cover an area, and it constantly detects.)
  2. Make the base node of the interaction object a StaticBody3D with a CollisionShape3D.
  3. Make sure the ShapeCast’s Mask is set to a layer specific for interaction (pick one you’re not using for anything else.)
  4. Make sure the StaticBody3D is on the matching Physics Layer.
  5. Add a script like this:
extends RayCast3D

func _physics_process(_delta: float) -> void:
	if not is_colliding():
		return
	var collider = get_collider()
	if Input.is_action_just_pressed("interact"):
		collider.interact()
2 Likes

I thought of a second idea today that I myself am going to try. It’s based on the OOP principle of Encapsulation.

  1. Create an Autoload called Interact.
#interact.gd
extends Node


var object: Node = null


func _physics_process(_delta: float) -> void:
	if not object:
		return
	if Input.is_action_just_pressed("interact"):
		object.interact()
  1. Add to your body_entered:
func _on_body_entered(body: Node) -> void:
	Interact.object = body
  1. Add to your body exited:
func _on_body_exited(body: Node) -> void:
	Interact.object = null
1 Like

Just as a thought experiment : If you’re only tracking a single object, then maybe make a boolean variable which sets to True upon entering the Area2D and sets to false on exiting the Area2D.

However, if you’re handling multiple objects then perhaps an array where every time you catch the body_entered signal it adds the object name to an array. Then the body_exit signal would remove the object name from the array.
That array would always have an accurate list of what objects can be picked up.

1 Like

wow, nice!

The Array idea Is good, the Boolean one is what O already do, but I do it with multiple objects.