1
\$\begingroup\$

I'm making an "Asteroids" clone in Godot 3.2.3

the way that the Bullet is spawned in-front of the Player ship is simple : the main game node will find the Player node's position and rotation and then instance the bullet in-front of the Player

func shooting(): var new_bullet = bullet.instance() add_child(new_bullet) new_bullet.position = $Player.position new_bullet.rotation = $Player.rotation $laser_sound.play()

works fine in game but a game crashing bug occurs if the player is pressing the "shoot" button right when they get hit by an Asteroid and i get this error

"Invalid get index 'position' (on base: 'null instance')." and it's pointing at new_bullet.position = $Player.position

so yeah what's happening is that the game is trying to find the player's position in order to spawn a new bullet but the player has just been removed, so the game just crashes since "Player" no longer exists

this is how i handle the Player dying

func _on_Player_area_entered(area): emit_signal("player_killed") queue_free()

i thought an easy solution would be to simply take away the Player's ability to press the "shoot" button and therefor not spawn a bullet right before the player is removed from the game, but none of the methods for disabling player input are actually working as intended...

func _on_Player_area_entered(area): emit_signal("player_killed") get_tree().get_root().set_disable_input(true) #i tried putting this here but it didn't do anything set_process_unhandled_input(false) #and this one did nothing either... queue_free()

how can i resolve this issue ? and tell me if you have any other method for resolving it.

thank you !!!

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Unfortunately, Godot 3 doesn't have an option to disable input globally. You can stop process functions like _input, _unhandled_input, _process in appropriate node using set_process_input(false), set_process_unhandled_input(false), etc.

So the solutions could be:

  1. Saving somewhere, for example in Singleton called GlobalVars with variable player which is a link to the Player node and disable inputs using the function I wrote above

global_vars.gd

var player = get_tree().get_root().find_node("Player")

func set_disable_input(value):
    player.set_process_input(value)

Warn: Using find_node is not recommended because it's very slow, but in this case, we don't know exactly where the Player would be in the scene tree to get the reference to the node

  1. Create a global bool variable input_disabled in Singleton for example called GlobalVars and when need disable input, just check the variable

global_vars.gd

var input_disabled = false

func set_disable_input(value):
    input_disabled = value

func get_disabled_input():
   return input_disabled

player.gd

func _input(event):
    if GlobalVars.get_disabled_input():
       return
    
    # Logic for inputs

In both cases, to disable input globally need just call this function GlobalVars.set_disable_input(true)

For me, better is the second option because it will be faster and will work 100%, at the same time, also much more flexible to have for example different state of disabling or just disable only some part of the game.

Maybe these answers also could help:

\$\endgroup\$
0
\$\begingroup\$

I solved the issue by simply just adding 1 line of code that checks if the Player actually exists before starting the function that spawns a bullet !

if player != null: #spawn a bullet ect...

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .