Player picking up items without matching the if-statements

Godot Version

4.5.1.stable

Question

I am working on Item pickup mechanics for my project, and I have an Area2D node to sense when the player is inside of a CollisionShape2D node. When the player is within the range, they are able to pick up an item.

The problem is that when the scene starts, if you don’t move within the range of an item, you can immediately use the click function (input from right mouse button) to get as many items as you want, even though you aren’t in range to get any.

Any help would be good help, and I’m a bit new to syntax-based coding so please be patient with me and use noobie words if you can, thank you!

P.S. Tell me if there is any code that you would need to help fix the problem, I will provide as quickly as I can!

Hotbar script code:

extends Control

@onready var in_area = GlobalVariables.in_area

@onready var rng = RandomNumberGenerator.new()

@onready var RNoutput = null

#I removed the inventory slot variables because it takes up a lot of space here, EmptySlot below is a variable for the next open slot in sequential order.

#region toggle hotbar visibility, interact, inventory visibility

func click():
	change_scene()
	var EmptySlot = decide_number()
	if EmptySlot != null:
		var Item_Instance = chosen_item.instantiate() 
		EmptySlot.add_child(Item_Instance)

#region input events

func _input(event):

# INTERACT
	if GlobalVariables.in_area:
		if event.is_action_pressed("Interact"):
			click()


Item script code:

extends Node2D

#region create variables

@onready var colshape = $Area2D2/colshape2

@onready var sprite = $Sprite2D

@onready var scenenumber = 1

#endregion

#region set variable for player range boolean

@onready var in_area = false

#endregion

#region show mouse button if player is or isnt in range, set the variable too

func _on_area_2d_body_entered(_body: Node2D) -> void:
	$RightMouseClickButton.visible = true
	in_area = true
	GlobalVariables.in_area = true

func _on_area_2d_body_exited(_body: Node2D) -> void:
	$RightMouseClickButton.visible = false
	in_area = false
	GlobalVariables.in_area = false

#endregion

#region looking if player is in range to get item into inventory CLICK FUNC

func click():
	queue_free()

func _input(event):
	if in_area:
		if event.is_action_pressed("Interact"):
			click()

I assume GlobalVariables is an autoload. Why are you tracking the pickup status of each item using one global property? Also, if GlobalVariables.in_area is instantiated as true, that might be the reason.

You aren’t doing anything to ensure that the _body entering this area actually is the player. If your item overlaps any body, including static bodies, it will trigger in_area = true.

You can add an if statement to check if the body is your player either by class_name with is, or by node name with .name

func _on_area_2d_body_entered(body: Node2D) -> void:
	if body is Player: # class_name
	# or
	if body.name == "Player": # name of player node
		in_area = true

Thank you both so much for responding to my message! I checked out the stuff you guys told me too, I changed the code to include:

func _on_area_2d_body_entered(body: Node2D) -> void:
	if body is Player: 
		$RightMouseClickButton.visible = true
		in_area = true
		GlobalVariables.in_area = true

I’m not too confident I did the right thing though because when I tried the code out it still didn’t work…

I don’t know if this will be any help for the cause, but I tried playing in a scene with no items to pick up and It still gave me ‘ghost items’

That sounds pretty wild. Can you add a print or better yet print_debug to your event or function click?

How are you testing this? Why would you get “ghost items” given this script it only deletes items, not giving any items.

Can you share your GlobalVariables script?