Hello. I am trying call the respawn_player() function in the BaseScene script that is attached to the level scene, when pressing the retry button in the GameOver screen, but when I type that in the code I get this error messege
I can’t figure out what it is that I am doing wrong or if I am messing something what do I need to do?
BaseScene Script:
class_name BaseScene extends Node
@onready var player: Player = $Player
@onready var camera = $FollowCam
@onready var entrance_markers: Node2D = $EntranceMarkers
@export var startingPos: Marker2D
# This input event is for testing.
func _input(event):
if Input.is_action_just_pressed("retry"):
respawn_player()
# Called when the node enters the scene tree for the first time.
func _ready():
if scene_manager.player:
if player:
player.queue_free()
player = scene_manager.player
add_child(player)
camera.follow_node = player
position_player()
func position_player() -> void:
var last_scene = scene_manager.last_scene_name
if last_scene.is_empty():
last_scene = "any"
for entrance in entrance_markers.get_children():
if entrance is Marker2D and entrance.name == "any" or entrance.name == last_scene:
player.global_position = entrance.global_position
func respawn_player() -> void:
player.global_position = startingPos.global_position
GameOver screen script:
extends Control
signal opened
signal closed
var isOpen: bool = false
func open():
visible = true
isOpen = true
opened.emit()
func close():
visible = false
isOpen = false
closed.emit()
func _on_retry_button_pressed():
close() # Closes the GameOver screen UI.
PlayerHealth.set_health_to_max()
BaseScene.respawn_player() # This line here, is highlighted in red.
func _on_quit_button_pressed():
get_tree().quit()
To call function respawn_player you need to have an instance of BaseScene class in your GameOver script. These are called static functions. In this case BaseClass is considered not as variable of typeBaseClass, but as class type, so Godot tries to call respawn_player function as static.
The issue here is that you are trying to call respawn_player() from the BaseScene class itself, not an instance of it. You will have to create a reference to the instance of BaseScene inside the GameOver script and then you will be able to call the function. To do that, you can use @export or the get_node() function, for example.
Is the BaseScene a node in tree? If so, could it be made an autoload? If yes, then the answer from @KingGD would be right (but as said, you have to remove class_name section to avoid conflicts between autoload node and class name).
Okay I see World node does have references to its children, so is it possible to add reference to the BaseScene node via @export annotation in GameOver script?
I can’t assign World in the inspecter, when I click on assign it only points to all the children that are in the GameOver screen control node, I can’t drag over the world node either
Then as a quick (I’m not sure if it’s the proper way of doing things) solution I see creating another Mediator autoload, so World and GameOverScreen could communicate with each other without coupling. It has got more of design problem…
class_name BaseScene
extends Node2D
# your properties
func _ready():
Mediator.base_scene = self
# your code of _ready function
# your functions
func respawn_player() -> void:
player.global_position = startingPos.global_position
GameOverScreen script:
extends Control
# your code
func _on_retry_button_pressed():
close() # Closes the GameOver screen UI.
PlayerHealth.set_health_to_max()
Mediator.retry()
mediator.gd (must be an autoload with name Mediator):
extends Node
var base_scene: BaseScene
func retry():
base_scene.respawn_player()
Here GameOverScreen notifies Mediator that event occured and Mediator delegates work to World node (BaseScene instance). If you have further questions feel free to ask!