Can't work around null instance error

Godot Version

4.3

Question

I have an array of 3 power ups that cycle when players press a specific key (“seed swap”).

The player has these power ups(small scenes) as children as they affect the world around the player and will be following the player. I’d like to toggle the power ups on and off as the index of the array changes.

index 0
index 1 visible power up1
index 2 visible power up2

since this is in the player I wrote the logic for changing powerups in player CharacterBody2D

###Seed Swapper
#define seed order
var seed_state = ["no-seed", "lightbriner seed", "Hardshell seed"]
# create a variable for the index of seeds
var current_seed_index = 0

func _input(event):
#seed changing based on pressing "1" key called seed swap
	if Input.is_action_pressed("seed swap"):
		current_seed_index += 1
		#load seed1 scene when index is 1 
		if current_seed_index == 1:
			#visible 
			$seed.visible = true
		else:
			$seed.visible = false
		#resets current_seed_state to 0 if the number exceeds the array
		if current_seed_index >= seed_state.size():
			current_seed_index = 0

no matter what I’ve tried I cannot turn off the entire scene visibility and error out

Invalid assignment of property or key ‘visible’ with value of type ‘bool’ on a base object of type ‘null instance’.

Ive defined the scene as variable, tried set_visible(true/false), rebuilt the entire powerup scene in the player character scene. I’m at a loss as to why the $seed that is in the scene is returning as null.

this is my scene setup

can you print out all the children of the player?

func _ready():
	for child in get_children():
		print(child)
2 Likes

Is “seed” previously freed or deleted in other scripts? This might cause an error like this.

Try adding a breakpoint when the node’s visibility is set, and when the game stops, check in the “Remote” section of your node panel and find your scene to see if the “seed” node is there.

1 Like

Thank you for your reply,

I’ve used this code

	for child in $"..".get_children():
		print(child)

to get the children results

Sprite2D:<Sprite2D#31272731920>
CollisionShape2D:<CollisionShape2D#31289509131>
Node2D:<Node2D#31306286366>
Camera2D:<Camera2D#31323063578>
seed1:<Area2D#31339840775>

Please let me know if I did this correctly.

Thank you for letting me know I’ve never used remote so it’s really nice to learn a new tool for trouble shooting. in my case the seed area2d was not deleted and there are only 3 scenes in this prototype project so it was easy to verify.

I was able to sort of work around the problem by working on one seed at a time instead of the cycling through power ups. still trying to implement all features before putting them together.

You probably should save these nodes in variables with onready, because the names are not always the one you give them in the scene

1 Like

Hello, @pin-elbow! If your script connected to seed node, try this:

# define seed order
var seed_state = ["no-seed", "lightbriner seed", "Hardshell seed"]
# create a variable for the index of seeds
var current_seed_index = 0

# Seed node
@onready var seed_node = get_node("../seed")

func _input(event):
   if Input.is_action_pressed("seed swap"):
      current_seed_index += 1
      if current_seed_index == 1:
         seed_node.visible = true
      else:
         seed_node.visible = false

      if current_seed_index >= seed_state.size():
         current_seed_index = 0

If script connected to Player node, just replace "../seed" to "seed" at get_node function.

1 Like

Thank you, I will give it a try going forward sounds like an easier way to keep track of variables.

1 Like

thank you @Rimjact this is similar to @herrspaten suggestion about @onready I’ll implement this an check back in the next week. I really appreciate you writing it out in a code block. Thank you!

1 Like