“Cannot call method ‘is_node_ready’ on a null value."

I’m having an error where it says "Cannot call method ‘is_node_ready’ on a null value.
The debugger tells me that in 3 of my scripts there is a yellow arrow that would indicate the possible error,
I will be placing a “>” to assimilate the lines with the yellow arrow

1 - card_base_state

extends CardState

func enter() → void:
“>” if not card_ui.is_node_ready():
await card_ui.ready

card_ui.reparent_requested.emit(card_ui)
card_ui.color.color = Color.WEB_GREEN
card_ui.state.text = “BASE”
card_ui.pivot_offset = Vector2.ZERO
func on_gui_input(event: InputEvent) → void:
if event.is_action_pressed(“left_mouse”):
card_ui.pivot_offset = card_ui.get_global_mouse_position() - card_ui.global_position
transition_requested.emit(self, CardState.State.CLICKED)

2 - card_state_machine.gd

class_name CardStateMachine
extends Node

@export var initial_state: CardState

var current_state: CardState
var states := {}

func init(card: CardUI) → void:
for child in get_children():
if child is CardState:
states[child.state] = child
child.transition_requested.connect(_on_transition_requested)
child.card_ui = card

if initial_state:
“>” initial_state.enter()
current_state = initial_state
func on_input(event: InputEvent) → void:
if current_state:
current_state.on_gui_input(event)

func on_gui_input(event: InputEvent) → void:
if current_state:
current_state.on_gui_input(event)

func on_mouse_entered() → void:
if current_state:
current_state.on_mouse_entered()

func on_mouse_exited() → void:
if current_state:
current_state.on_mouse_exited()

func _on_transition_requested(from: CardState, to: CardState.State) → void:
if from != current_state:
return

var new_state: CardState = states[to]
if not new_state:
return

if current_state:
current_state.exit()

new_state.enter()
current_state = new_state
3 - card_ui.gd

class_name CardUI
extends Control

signal reparent_requested(which_card_ui: CardUI)

@onready var color: ColorRect = $Color
@onready var state: Label = $State
@onready var card_state_machine: CardStateMachine = $CardStateMachine as CardStateMachine

func _ready() → void:
“>” card_state_machine.init(self)

func _input(event: InputEvent) → void:
card_state_machine.on_input(event)

func _on_gui_input(event: InputEvent) → void:
card_state_machine.on_gui_input(event)

func _on_mouse_entered() → void:
card_state_machine.on_mouse_entered()

func _on_mouse_exited() → void:
card_state_machine.on_mouse_exited()

Its the first one. card_ui has no value. When is it supposed to have one?

1 Like

I don’t know, this code is from a YouTube tutorial video, I was following it normally until I had this problem at 31:40
here is the tutorial

Can you print your code again but this time use the coding-block?
paste it between ’ ``` ’ these symbols.
In the current state its not readable

I believe it is here, which is the “var” of card_ui

class_name CardState
extends Node

enum State {BASE, CLICKED, DRAGGING, AIMING, RELEASED}

signal transition_requested(from: CardState, to: State)

@export var state: State

var card_ui: CardUI

func enter() → void:
pass

func exit() → void:
pass

’ Like this? ’ Like this?

use three on each side

# paste code here

1 - card_base_state


func enter() → void:
“>” if not card_ui.is_node_ready():
await card_ui.ready

card_ui.reparent_requested.emit(card_ui)
card_ui.color.color = Color.WEB_GREEN
card_ui.state.text = “BASE”
card_ui.pivot_offset = Vector2.ZERO
func on_gui_input(event: InputEvent) → void:
if event.is_action_pressed(“left_mouse”):
card_ui.pivot_offset = card_ui.get_global_mouse_position() - card_ui.global_position
transition_requested.emit(self, CardState.State.CLICKED)```

2 - card_state_machine.gd

```class_name CardStateMachine
extends Node

@export var initial_state: CardState

var current_state: CardState
var states := {}

func init(card: CardUI) → void:
for child in get_children():
if child is CardState:
states[child.state] = child
child.transition_requested.connect(_on_transition_requested)
child.card_ui = card

if initial_state:
“>” initial_state.enter()
current_state = initial_state
func on_input(event: InputEvent) → void:
if current_state:
current_state.on_gui_input(event)

func on_gui_input(event: InputEvent) → void:
if current_state:
current_state.on_gui_input(event)

func on_mouse_entered() → void:
if current_state:
current_state.on_mouse_entered()

func on_mouse_exited() → void:
if current_state:
current_state.on_mouse_exited()

func _on_transition_requested(from: CardState, to: CardState.State) → void:
if from != current_state:
return

var new_state: CardState = states[to]
if not new_state:
return

if current_state:
current_state.exit()

new_state.enter()
current_state = new_state```

3 - card_ui.gd

```class_name CardUI
extends Control

signal reparent_requested(which_card_ui: CardUI)

@onready var color: ColorRect = $Color
@onready var state: Label = $State
@onready var card_state_machine: CardStateMachine = $CardStateMachine as CardStateMachine

func _ready() → void:
“>” card_state_machine.init(self)

func _input(event: InputEvent) → void:
card_state_machine.on_input(event)

func _on_gui_input(event: InputEvent) → void:
card_state_machine.on_gui_input(event)

func _on_mouse_entered() → void:
card_state_machine.on_mouse_entered()

func _on_mouse_exited() → void:
card_state_machine.on_mouse_exited()```

Can you show your CardState-script?

1 Like
class_name CardState
extends Node

enum State {BASE, CLICKED, DRAGGING, AIMING, RELEASED}

signal transition_requested(from: CardState, to: State)

@export var state: State

var card_ui: CardUI


func enter() -> void:
	pass


func exit() -> void:
	pass


func on_input(_event: InputEvent) -> void:
	pass


func on_gui_input(_event: InputEvent) -> void:
	pass

card_ui.gd

`class_name CardUI
extends Control

signal reparent_requested(which_card_ui: CardUI)

@onready var color: ColorRect = $Color
@onready var state: Label = $State
@onready var card_state_machine: CardStateMachine = $CardStateMachine as CardStateMachine


func _ready() -> void:
	card_state_machine.init(self)


func _input(event: InputEvent) -> void:
	card_state_machine.on_input(event)


func _on_gui_input(event: InputEvent) -> void:
	card_state_machine.on_gui_input(event)


func _on_mouse_entered() -> void:
	card_state_machine.on_mouse_entered()


func _on_mouse_exited() -> void:
	card_state_machine.on_mouse_exited()
	
`

card_state_machine.gd

class_name CardStateMachine
extends Node

@export var initial_state: CardState

var current_state: CardState
var states := {}


func init(card: CardUI) -> void:
	for child in get_children():
		if child is CardState:
			states[child.state] = child
			child.transition_requested.connect(_on_transition_requested)
			child.card_ui = card
	
	if initial_state:
		initial_state.enter()
		current_state = initial_state


func on_input(event: InputEvent) -> void:
	if current_state:
		current_state.on_gui_input(event)


func on_gui_input(event: InputEvent) -> void:
	if current_state:
		current_state.on_gui_input(event)


func on_mouse_entered() -> void:
	if current_state:
		current_state.on_mouse_entered()


func on_mouse_exited() -> void:
	if current_state:
		current_state.on_mouse_exited()


func _on_transition_requested(from: CardState, to: CardState.State) -> void:
	if from != current_state:
		return
		
	var new_state: CardState = states[to]
	if not new_state:
		return
	
	if current_state:
		current_state.exit()
	
	new_state.enter()
	current_state = new_state

card_base_state.gd

extends CardState


func enter() -> void:
	if not card_ui.is_node_ready():
		await card_ui.ready
	
	card_ui.reparent_requested.emit(card_ui)
	card_ui.color.color = Color.WEB_GREEN
	card_ui.state.text = "BASE"
	card_ui.pivot_offset = Vector2.ZERO


func on_gui_input(event: InputEvent) -> void:
	if event.is_action_pressed("left_mouse"):
		card_ui.pivot_offset = card_ui.get_global_mouse_position() - card_ui.global_position
		transition_requested.emit(self, CardState.State.CLICKED)

Is the card_base_state a child of the CardStateMachine?

brooo that was the problem, it worked now haha. Thank you very much!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.