Help with a function, loading values from node

Godot Version

4.2.1

Question

I have the following setup:
1 main node
1 child nodes: player1

player1 has a script with a few values, that the function need to take to calculate correctly

The main node:

@onready var player1 = $Player1

func calculate_engagement_score(player):
	var player_attributes = player.get("skill")
	# Assumes "attributes" is a property containing PlayerAttributes node
	var general_aim = player_attributes.general_aim
	var general_movement = player_attributes.general_movement
	var reaction_time = player_attributes.reaction_time
	
	# Aim Accuracy Score: The more accurate a player is, the better their chances of 
	# hitting the enemy
	var aim_score = general_aim / 100

	# Movement Speed Score: Faster players can move to advantageous positions or escape
	# dangerous situations
	var positioning_score = general_movement / 100

	# Reaction Time Score: Quicker reaction time helps a player respond effectively
	# during an engagement
	var reaction_time_score = reaction_time / 100
	
	return (aim_score + positioning_score + reaction_time_score) / 3

func _ready():
	calculate_engagement_score(player1)

player1 node:

extends Node2D

@onready var general_aim = 50.0
@onready var general_movement = 50.0
@onready var reaction_time = 50.0

I get the error:
Invalid get index 'general_aim' (on base: 'Nil')

I think this part is wrong:

    var player_attributes = player.get("skill")
	# Assumes "attributes" is a property containing PlayerAttributes node
	var general_aim = player_attributes.general_aim
	var general_movement = player_attributes.general_movement
	var reaction_time = player_attributes.reaction_time

I’m not sure how to make it work,
Thank you

Would help if you used the </> format for your code. It’s too hard to read.
Also include the errors you get.
Try to help us help you.

func _ready():
	calculate_engagement_score(player1)

In this func (in player1), you are calling another function that Godot can’t find. You need to specify the object that holds it.

You could try:
$main.calculate_engagement_score(player1)

ETA - Am still looking. I think I got that ^ wrong

Thank you for the reply!
I hope it’s better now

It’s the same problem backwards. main does not know about player1.

In main, refer to $player1.whatever

hth

It’s all about giving a enough info to Godot so it can find the object that you want to get access too.

Usually naming them with $ (and be sure to use the right path. Try drag and drop from the tree to the code editor to see how it makes paths) is enough.

You can also pre-prepare shorter names with @onready

in main:

@onready var p1 = $player1
func _onready():
  calculate_engagement_score(p1)

Thank you, It solved a different issue I had, but I still get the:
Invalid get index 'general_aim' (on base: 'Nil')

The error is syaing that player_attributes is null. Check your assumptions and go backwards. Is “skill” a thing in player? etc.

When _ready() is called on a node, their children are not yet ready (they are accessible, but uninitialized). This means you can get to them with $path syntax, but you can’t retrieve properties yet.
In this particular case, what you can do is just call your calculate engagement function fromthe _ready function of the child. That’s the easy dumb solution. You could also use signals or just call_deferred. In the end it will depend on your end goal and design, so can’t really tell you what’s better at this point with the information given.

1 Like