0 votes

Following scenario:

  1. KinematicBody2D with attached script "Player.gd".
  2. Classfile named "State.gd". Gets instanced by Player.gd by preloading as variable "state" and calling state.new() on it.
  3. Classfile named "Substate.gd". Gets instanced by State.gd the same way Player.gd did it with State.gd.

Player.gd delegates _input and _process computation to State.gd which in return delegates them to the Substate.gd by calling the corresponding functions and passing event/delta.

If I understand the docs correctly, I should be able to call functions within the instanced classes, yet I get errors like "Nonexistent function "func_name" in base Nil.

Here are code examples for better understanding what I am trying to do.

Player.gd

extends KinematicBody2D

onready var state = preload("State.gd").new()

func _input(event):
    state.handle_input(event)

func _process(delta):
    state.update(delta)

State.gd

onready var substate = preload("Substate.gd").new()

func handle_input(event):
    substate.handle_input(event)

func update(delta):
    substate.update(delta)

Substate.gd

var speed = 100
var velocity = Vector2()
var movement

func handle_input(event):
    # set variables for directions (up, down, left, right)
    # match event and set velocity according to it
    # assign movement to velocity.normalized() * speed

func update(delta):
    move_and_slide(movement)

From my understanding, this should work but I keep getting "nonexistent function" errors.
What is my mistake here or what have I misunderstood?

in Engine by (143 points)

Note: you don't need the onready in Player.gd.

1 Answer

+1 vote
Best answer

I think it's because you used onready in State.gd. onready is a shortcut for the initialization of the variable to be executed when _ready is called. However your states are not nodes, they are plain classes, so their _ready is never called because it's a Node feature.
In fact, you don't need to use onready at all, from the look of your code. It should work without when you use new.

by (28,731 points)
selected by

Solved the problem. thanks!
I still have to figure out how to call moveandslide() from within the substate. any idea how? my first guess would be that I could call a function from parent and pass arguments, which in return calls .moveandslide(movement) in Player.gd. But then again, Player.gd does not know about the variable movement and would throw an unknown identifier error.

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 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 webmaster@godotengine.org with your username.