Area2D Node Does Not Detect Until Ball Reaches A Certain Area Or When We Stop Dragging

Godot Version

v4.2.1.stable.official

Question

I am making a mobile game and the ball in the game I am making needs to be dragged only in a certain area. In the code, it starts dragging only in the area I specify, but the problem is that if I start dragging in that area, I can also take it out of that area. But when it reaches a certain place, it stops.

Code

extends RigidBody2D

var dragging = false  # Sürükleme kontrolü
var offset = Vector2.ZERO  # Farenin topa olan mesafesi
var last_position = Vector2.ZERO  # Hızı hesaplamak için önceki pozisyon
var can_drag = false  # Sürükleme izni

@onready var drag_area = $"../../Center/DragArea2D"   # Area2D düğümünü referans al

func _ready():
	# Fizik materyali ekleyerek sekmeyi aktif edelim
	physics_material_override = PhysicsMaterial.new()
	physics_material_override.bounce = 0.7  # 0.0 - 1.0 arasında, ne kadar sekmesini istersen artır
	physics_material_override.friction = 0.8  # Hafif bir sürtünme ekleyelim

	# Area2D sinyallerini bağla
	if drag_area:
		drag_area.body_entered.connect(_on_drag_area_entered)
		drag_area.body_exited.connect(_on_drag_area_exited)

func _input(event):
	if can_drag and event is InputEventMouseButton:
		if event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
			if (global_position - event.position).length() <= $CollisionShape2D.shape.radius:
				dragging = true
				offset = global_position - event.position
				freeze = true  # Fizik motorunu durdur

		elif not event.pressed and dragging:
			dragging = false
			freeze = false  # Fizik motorunu aç
			linear_velocity = (global_position - last_position) / get_physics_process_delta_time()  # Hız ekleyelim

func _process(delta):
	if dragging:
		last_position = global_position  # Önceki pozisyonu sakla
		global_position = get_global_mouse_position() + offset

func _on_drag_area_entered(body):
	if body == self:
		can_drag = true

func _on_drag_area_exited(body):
	print("test")
	if body == self:
		can_drag = false
		dragging = false
		set_deferred("freeze", false)  # Hata önlemek için set_deferred kullandık.

Photo And Videos


# Area2D sinyallerini bağla
if drag_area:
	drag_area.body_entered.connect(_on_drag_area_entered)
	drag_area.body_exited.connect(_on_drag_area_exited)

One thing that seems possible is, drag_area is null because of the order in which nodes come into the scene tree. It looks like this script is on your “Right/RigidBody2D” node, which comes into the scene tree before the “Center” node. To test this out, I would add a print statement:

# Area2D sinyallerini bağla
if drag_area:
	print("drag area node exists")
	drag_area.body_entered.connect(_on_drag_area_entered)
	drag_area.body_exited.connect(_on_drag_area_exited)
else:
	print("drag area node does not exist yet")

However, the main issue I have with this code is the way you’re connecting code to another node’s signal. I think it would be better if your DragArea2D had its own script and handled the body_entered signal on its own. You could do something like this:

In your existing RigidBody2D node:

    func _ready():
        # Whatever code you already have
        add_to_group("draggable_balls")  # heh

In drag_area.gd:

    func _on_body_entered(body):
        if body.is_in_group("draggable_balls"):
            body.can_drag = true
        # etc