0 votes

Hello everyone.
I know that my question is probably very stupid, but I can't figure out what the problem is. (maybe there is no problem. and I just don't have enough knowledge)
The project tree is very simple:
Node2D(named:MainScene)
- TileMap
- - KinematicBody2D
- - - CollisionShape2D
- - - Sprite
- - - - Panel
- - - - - Label

In the KinematicBody2D node, a script with simple control and variable speed.

extends KinematicBody2D
var speed = 70

func _ready():
pass #

func _process(delta):

var velocity = Vector2()
if Input.is_action_pressed("up"):
    velocity.y -= speed
if Input.is_action_pressed("down"):
    velocity.y += speed
if Input.is_action_pressed("left"):
    get_node("Sprite").flip_h = true
    velocity.x -= speed
if Input.is_action_pressed("right"):
    get_node("Sprite").flip_h = false
    velocity.x += speed
if Input.is_key_pressed(KEY_SHIFT):
    speed = 120
else:
    speed = 70

move_and_slide(velocity)

position.x = clamp(position.x, 5, 335)
position.y = clamp(position.y, 0, 330)

In the Label node, a simple script that should show the value of the speed variable from the script in KinematicBody2D.
And here lies my problem.
If I try to access the KinematicBody2D node to get the value of a variable velocity in $KinematicBody2D.speed (auto-complete, and there have to print the manual), when you run the project I receive an error "Invalid get index 'speed' (on base: 'null instace')"
If you are applying through get_node(), then the autocomplete suggests ".", what's not working.

The only working way I could find:

text = "speed: " + String(get_parent().get_parent().get_node("KinematicBody2D").speed)

It seems to me that I am missing some simple way to indicate the path to another node.
Or is that exactly how it should work?

Godot version 3.4.2.stable
in Engine by (15 points)

3 Answers

+1 vote
Best answer

It's always the questions where the person comes across as genuine and/or humble where everyone steams in and debates what's the absolutely optimal solution to the nth degree. :)

Ok, drop this whole get_parent().get_parent().get_node("Fart") malarky. get_node("../../Fart") means the same thing. It's just more concise. So add ../ every time you want to go up one in the tree with get_node and you're golden.

So, to reference the KB2D from the Label, it's get_node("../../../../") (assuming these are all parents of each other, I'm interpreting the number of dashes as not meaning anything)

by (2,159 points)
selected by

Thanks for the reply!

get_node("../../../../") 

it also works fine, as does "find_parent" from the answer above.
It's a bit strange for me that there is no autofill of the path while writing the script. But it seems to be the norm.

I will use both options.

Well, it can't autofill because it's just a string. Getting slightly more advanced, there is the data type / object NodePath. If you put:

export var my_node : NodePath

Save this, click on the node and take a look at your inspector on the right and you'll see a my_node field which you can click on to pick out the node you want to reference from the tree. This is convenient, saves you working out the path in your head but it also has a huge advantage:

If you use get_node("../MyNode")and then you move MyNode, this will crash as Godot can no longer find it. If you move the node using NodePath as above then Godot will handle this and it won't crash so it's less brittle and more robust.

There is also separation of concerns and dependencies to consider but that's a huge topic and beyond the scope of this.

It's amazing. Thanks so much for the detailed explanation!

+1 vote

getparent().getparent().getparent().getnode("Node-name").speed

or

getowner().getnode("Node-name").speed

by (755 points)

Thanks!

get_owner().get_node("Node-name").speed

also work fine to me.

+1 vote

Hello Viskirson,

you are using 2 get_parent(), that brings you up to Sprite and Sprite ist not a parent of KinematicBody2D. You have to use 4 get_parents() to get to TitleMap where you can find KinematicBody2D as a child

text = "speed: " + String(get_parent().get_parent().get_parent().get_parent().get_node("KinematicBody2D").speed)

or try

text = "speed: " + String(find_parent("KinematicBody2D").speed)
by (130 points)

Thanks! find_parent("KinematicBody2D"work fine for me.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.