I am making a function that comes up with a random position along the outside of the screen for a spawning system in my 2D game and I am getting the error
Invalid get index ‘global_position’(on base:‘null instance’)
Here is the code
func get_random_position():
var vpr = get_viewport_rect().size * randf_range(1.1,1.4)#reusable script for off the screen
var top_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y - vpr.y/2)#var to teach the sides of the screen to computer
var top_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var bottom_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y + vpr.y/2)
var bottom_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var pos_side = ["up","down","left","right"].pick_random()#picks random side
var spawn_pos1 = Vector2.ZERO
var spawn_pos2 = Vector2.ZERO
# pikes a side and range of coordinates
match pos_side:
"up":
spawn_pos1 = top_left
spawn_pos2 = top_right
"down":
spawn_pos1 = bottom_left
spawn_pos2 = bottom_right
"left":
spawn_pos1 = top_left
spawn_pos2 = bottom_left
"right":
spawn_pos1 = top_right
spawn_pos2 = bottom_right
var x_spawn = randf_range(spawn_pos1.x, spawn_pos2.x)
var y_spawn = randf_range(spawn_pos1.y, spawn_pos2.y)
return Vector2(x_spawn, y_spawn)
@onready var player = get_tree().get_first_node_in_group(“player”)
var time = 0
func _on_timer_timeout():
print(“works”)
time += 1
var butterfly_spawns = spawns
for i in butterfly_spawns:
if time >= i.time_start and time <= i.time_end:
if i.spawn_delay_counter < i.butterfly_spawn_delay:
i.spawn_delay_counter += 1#add one to delay of next butterfly
else:#if it is, than
i.spawn_delay_counter = 0
var new_butterfly = load(str(i.butterfly.resource_path))
var counter = 0
while counter < i.butterfly_number:
var butterfly_spawn = new_butterfly.instantiate()
butterfly_spawn.global_position = get_random_position()
add_child(butterfly_spawn)
counter += 1
func get_random_position():
var vpr = get_viewport_rect().size * randf_range(1.1,1.4)#
var top_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y - vpr.y/2)
var top_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var bottom_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y + vpr.y/2)
var bottom_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var pos_side = ["up","down","left","right"].pick_random()
var spawn_pos1 = Vector2.ZERO
var spawn_pos2 = Vector2.ZERO
# pikes a side and range of coordinates
match pos_side:
"up":
spawn_pos1 = top_left
spawn_pos2 = top_right
"down":
spawn_pos1 = bottom_left
spawn_pos2 = bottom_right
"left":
spawn_pos1 = top_left
spawn_pos2 = bottom_left
"right":
spawn_pos1 = top_right
spawn_pos2 = bottom_right
var x_spawn = randf_range(spawn_pos1.x, spawn_pos2.x)
var y_spawn = randf_range(spawn_pos1.y, spawn_pos2.y)
return Vector2(x_spawn, y_spawn)
It’s giving me errors in variable and in the function. For the variable it sais [Unexpected " Indent" in class body] and in the function it sais[Expected end of file]. I also tried switching the Node2D for a CharacterBody2D because my player is a CharacterBody2D but it did not change anything. When I tried to change it to an export it said [Cannot call method ‘get_first_node_in_groupe’ on null value]
As said before, the player node is probably not ready at the point your script is. Did you check the hierarchy of your scene? _ready() is called on children first, then on their parent nodes. Not quite sure about the order between sibling nodes.
You could also get the player inside the function where you need it (assuming the function is called at some point after the whole scene has been initialized).
gdscript cares about the whitespace at the start of a line. If it is indented you are saying that line belongs to a function or branch.
var player: Node2D # not indented, not part of any function, a global variable
func _ready() -> void: # not indented
await get_tree().process_frame # indented, part of the _ready function above
player = get_tree().get_first_node_in_group("player") # also indented, also part of the function
If you paste your script with proper formatting I can help more,
I check my hierarchy is there anything in particular in should be looking for my player is before the spawner. I don’t get what you mean by get the player inside the function where I need it. Do you mean the variable?
extends Node2D
@export var spawns: Array[Spawn_info] = []#Array = many variables coupled
var time = 0
var player: Node2D
func _ready() -> void:
await get_tree().process_frame
player = get_tree().get_first_node_in_groupe("Player")
func _on_timer_timeout():
print("works")
time += 1
var butterfly_spawns = spawns#referance to the array(spawn info)
for i in butterfly_spawns:
if time >= i.time_start and time <= i.time_end:#if timer is running
if i.spawn_delay_counter < i.butterfly_spawn_delay:#if delay is bigger NOT than its supposed to
i.spawn_delay_counter += 1#add one to delay of next butterfly
else:#if it is, than
i.spawn_delay_counter = 0#reset delay counter so restart cycle
var new_butterfly = load(str(i.butterfly.resource_path))
var counter = 0
while counter < i.butterfly_number:#if missing a butterfly
var butterfly_spawn = new_butterfly.instantiate()
butterfly_spawn.global_position = get_random_position()#to make him spawn in random pos
add_child(butterfly_spawn)#makes a clone(child)
counter += 1#count the children
func get_random_position():
var vpr = get_viewport_rect().size * randf_range(1.1,1.4)#reusable script for off the screen
var top_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y - vpr.y/2)#var to teach the sides of the screen to computer
var top_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var bottom_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y + vpr.y/2)
var bottom_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var pos_side = ["up","down","left","right"].pick_random()#picks random side
var spawn_pos1 = Vector2.ZERO
var spawn_pos2 = Vector2.ZERO
# pikes a side and range of coordinates
match pos_side:
"up":
spawn_pos1 = top_left
spawn_pos2 = top_right
"down":
spawn_pos1 = bottom_left
spawn_pos2 = bottom_right
"left":
spawn_pos1 = top_left
spawn_pos2 = bottom_left
"right":
spawn_pos1 = top_right
spawn_pos2 = bottom_right
var x_spawn = randf_range(spawn_pos1.x, spawn_pos2.x)
var y_spawn = randf_range(spawn_pos1.y, spawn_pos2.y)
return Vector2(x_spawn, y_spawn)
extends Node2D
@export var spawns: Array[Spawn_info] = []
var time = 0
var player: Node2D
# there were some errors in this ready function but i fixed them so there is only the main one left.
func _ready() -> void:
await get_tree().process_frame
player = get_tree().get_first_node_in_groupe("Player")
func _on_timer_timeout():
print("works")
time += 1
var butterfly_spawns = spawns
for i in butterfly_spawns:
if time >= i.time_start and time <= i.time_end:
if i.spawn_delay_counter < i.butterfly_spawn_delay:
i.spawn_delay_counter += 1
else:
i.spawn_delay_counter = 0
var new_butterfly = load(str(i.butterfly.resource_path))
var counter = 0
while counter < i.butterfly_number:
var butterfly_spawn = new_butterfly.instantiate()
butterfly_spawn.global_position = get_random_position()
add_child(butterfly_spawn)
counter += 1
func get_random_position():
var vpr = get_viewport_rect().size * randf_range(1.1,1.4)
var top_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y - vpr.y/2)#HERE IS THE ERROR im assuming it is in the next 3 lines as well because the are nearly identical
var top_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var bottom_left = Vector2(player.global_position.x - vpr.x/2, player.global_position.y + vpr.y/2)
var bottom_right = Vector2(player.global_position.x + vpr.x/2, player.global_position.y - vpr.y/2)
var pos_side = ["up","down","left","right"].pick_random()
var spawn_pos1 = Vector2.ZERO
var spawn_pos2 = Vector2.ZERO
match pos_side:
"up":
spawn_pos1 = top_left
spawn_pos2 = top_right
"down":
spawn_pos1 = bottom_left
spawn_pos2 = bottom_right
"left":
spawn_pos1 = top_left
spawn_pos2 = bottom_left
"right":
spawn_pos1 = top_right
spawn_pos2 = bottom_right
var x_spawn = randf_range(spawn_pos1.x, spawn_pos2.x)
var y_spawn = randf_range(spawn_pos1.y, spawn_pos2.y)
return Vector2(x_spawn, y_spawn)