Can't get a node as a varibable on an object spawned during runtime

Godot Version

4.3

Question

I have a player node, and a dropped_item node. I need to be able to call a function in the player node from a dropped_item. It works when the item is placed in the scene initially, but when it’s spawned during runtime, it cannot connect to the player node.
===========================| Item code

extends CharacterBody2D
var item_id = -2
var mouse_on_item = false
#var player_character: CharacterBody2D
@onready var player_character = $"../PlayerCharacter"
#@onready var player_character = get_tree().get_root().get_node("../PlayerCharacter")
#func _ready() -> void:
	#var player_character = %PlayerCharacter

func _process(delta: float) -> void:
	#var player_character = get_parent().get_node("PlayerCharacter")
	if not is_on_floor():
		velocity += get_gravity() * delta
	if get_global_mouse_position().x <= global_position.x + 32 and get_global_mouse_position().x >= global_position.x - 32 and get_global_mouse_position().y <= global_position.y + 32 and get_global_mouse_position().y >= global_position.y - 32:
		mouse_on_item = true
	if mouse_on_item and Input.is_action_pressed("pick_up"):
		player_character.replace_weapon(item_id)
	move_and_slide()

====================================| The error
E 0:00:13:0499 dropped_item.gd:5 @ _ready(): Node not found: “…/PlayerCharacter” (relative to “/root/DroppedItem”).
<C++ Error> Method/function failed. Returning: nullptr
<C++ Source> scene/main/node.cpp:1792 @ get_node()
dropped_item.gd:5 @ _ready()
=======================================| The scene tree
image
=======================================| The code for spawning item during runtime

func drop_weapon(item_id: int) -> void:
	var instance = dropped_item.instantiate()
	instance.global_position = global_position
	instance.velocity.y = -350
	instance.item_id = item_id
	#instance.player_character = $"."
	main.add_child.call_deferred(instance)

=========================|
The commented lines of code are solutions that I tried, and they failed.

Try calling the player like this:

@onready var player_character = get_node("/root/level_test/PlayerCharacter")  # Adjust the path based on your scene structure, assuming you'll change the name of "level_test".
1 Like

Thanks, it works now, but is there a solution to make it work for any scene where there’s a player, and not write a different path for each one?

Yep, you can use:

@onready var character = find_child("Main character", true)

Make sure you don’t forget that true, because it allows find_child() to search recursively through all nodes and their children, not just the children of the root.

gives an error. (i just copied the line and fixed the variable name cuz it’s “player_character”)
image

I’d need the code to be honest, as It works for me. And I tested it before sending you my example.

well, all the code there is that is relevant to this part of the project is in the question part. if i just replace the line that didn’t work with that solution, it breaks for some reason. maybe something about the structure, then?

still can’t find a way to get the player regardless of scene. now i also need it for enemies to work though, not only items.

edit: solved it. i spawned items too high in the tree, somehow. still don’t understand much about it, but at least i made it work.