Attempting to retrieve variable from different script for control node.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By darkdestiny1010

Currently I have a control node that I’m using with a label so I can set up a simple ammo counter for my game. In my player kinematicbody2d, I have the variable:

export var ammo = 6

And in my control node, I have:

onready var labelAmmo = "res://Player/KinematicBody2D.gd".ammo

With this, I immediately get the error “invalid index ‘ammo’ in constant expression.” I am unsure how to remedy this and would appreciate advice.

:bust_in_silhouette: Reply From: timothybrentwood

So what you’re trying to do is access the ammo property of a String. It’s the same as coding "Cool".ammo. Seems silly when you look at it from the computer’s perspective. But we’ve all been there. :slight_smile:

What you are going to want to do is every time that ammo variable gets changed, emit a custom signal that you create, then have your Control node connect()ed to that signal so it can receive the change and update the UI.

Here are the Godot docs on signals. I highly recommend reading through the entire thing, they’re essential for game programming.

Here is also a write up about communicating between nodes:
https://kidscancode.org/godot_recipes/basics/node_communication/
The diagram in the info box is extremely handy to learn.

Let me know if you need help.

Would this also retrieve the ammo variable from the player? Or would I have to set up code in the control node that makes its own ammo count that decreases each time ammo_changed is emitted?

darkdestiny1010 | 2021-05-12 15:04

Nevermind, got it working! Thank you so much!

darkdestiny1010 | 2021-05-12 15:41

You could just use a single variable in the player class to manage your ammo variable:

player.gd

signal ammo_changed(ammo_left)
...
func shoot()
    ammo -= 1 
    emit_signal(ammo_changed, ammo)

to connect the two:

mutual_parent_node.gd

onready var player = get_node("Player") # wherever these are located
onready var control_node = get_node("ControlNode") # whereever these are located

func _ready():
    player.connect("ammo_changed", control_node, "_on_ammo_changed")

finally

control_node.gd

# gets called whenever  ammo_changed is emitted because of the connect() function
func _on_ammo_changed(ammo):
    labelAmmo = str(ammo)
    # or something like:
    label.text = str(ammo)

timothybrentwood | 2021-05-12 15:44