How to reference node in Godot

Viewed 228

I'm using gdscipt and I'm trying to set up a state machine. I'm trying to access PlayerStateMachine/PlayerStateMachineManager.gd

by using

onready var statemachine = get_node("PlayerStateMachine/PlayerStateMachineManager.gd")

but I keep getting the error

get_node: (Node not found: "PlayerStateMachine/PlayerStateMachineManager.gd" (absolute path attempted from "/root/Player").)

From what I understand, get_node() should look for the path from the parent of the current node, so why is it not finding PlayerStateMachineManager.gd?

FYI: PlayerStateMachine is a folder in the same folder as Player.gd

Directory Picture

2 Answers

The get_node method will try to get a node form the scene tree (or fail with an error). However, apparently you are passing a path to a script file (e.g. with extension ".gd")? Files are in the FileSystem tree, not the Scene tree.

To be clear: a script is not a Node, and a Node is not a script (nor script file). Nodes exist in the scene tree, and might - or might not - have a script attached to them. An script could be attached to an Object, multiple Objectss, or none. And yes, Nodes are Objects

You can add Nodes to the scene tree from code using add_child, and the components of the path in the scene tree are the names of the Nodes. You can also modify the scene tree of a scene file (e.g. with extension ".tscn"), which you can do visually in the Godot editor.

To reiterate: adding a Node does not imply adding a script file. And the way you organize the script files does not have to match the scene tree. Furthermore, you can have scripts that are not attached to Nodes.

Under the assumption that you want a Node (and not a script file), you need the path to it in the scene tree. I cannot tell you which is the path, because you did not share how your scene tree looks like.

In the editor the Scene tree looks something like this:

Scene

And get_node uses paths in the that tree.

See Nodes and scene instances


Alternatively you do want to load a script file. After all, the image you shared is of the file system tree (except this picture is not of the Godot editor):

Files

You can load these script files using load (or preload or ResourceLoader.load or ResourceLoader.load_interactive…) giving you a Script. If it is a GDScript script file, it is a GDScript. Which are Objects too. And you can instantiate that GDScript with new…

From the point of view of the GDScript language, Scripts are classes. However, behind the scenes what happens is that when you instantiate a GDScript Godot will create an Object the appropriate type (Node or not) and attaches the GDScript to it. Notice that the Object class has get_script and set_script methods.

Be aware that Godot packages and virtualices the project file system. So you would use a path starting with "res://" to refer to the files in the project file system, which are actual files while you are editing the game, or virtual files inside the ".pck" file you get once you exported the game.

See File system and File paths in Godot projects

Just to extend to the answer of Theraot:

If your script is attached to your PlayerStateMachine Node you can access it via the node.

So as an example, if you have a function change_state() in your PlayerStateMachineManager.gd and your SceneTree looks like this:

Player -> Player.gd attached
  PlayerStateMachine -> PlayerStateMachineManager.gd attached

you can do something like this in the player script:

var statemanager

func _ready()
   statemanager = $PlayerStateMachine # same as get_node("PlayerStateMachine")
   statemanager.change_state("idle")
Related