Godot Version
4.7.1
Question
Trying to make GeneralSavingSystem to have player keep level and position for next gameplay.
Couple things going wrong, once I get Nil for Player, Level or call deferred child if I do direct change of scene,
This time I went with built it scene_change via UI, but problem is the ColorRectFader is not ready at the time of load_game_state() call in ready method inside GeneralSaveSystem.
current error is
E 0:00:00:533 UI.fade_out: Invalid assignment of property or key 'visible' with value of type 'bool' on a base object of type 'Nil'.
<GDScript Source>UserInterface.gd:66 @ UI.fade_out()
<Stack Trace> UserInterface.gd:66 @ fade_out()
UserInterface.gd:82 @ change_scene()
general_save.gd:19 @ load_game_state()
general_save.gd:13 @ _ready()
The code starts to be little obscure and not sure where to go next
class_name GeneralSaveSystemClass
extends Node
@export var levels : Array[String] = []
@onready var player : CharacterBody3D = get_tree().get_first_node_in_group("Player")
@onready var level_node : Node3D = get_tree().get_first_node_in_group("Level")
var current_level_index: int = 0
var level : String
var player_position : Transform3D
const SETTINGS_PATH := "user://attributes.cfg"
var config = ConfigFile.new()
func _ready() -> void:
load_game_state()
func load_game_state() -> void:
load_data()
get_setting("Player", "position", player_position)
get_setting("Level", "index", current_level_index)
UserInterface.change_scene(levels[current_level_index], player_position)
func find_level_in_array() -> void:
for level_index in range(levels.size()):
if levels[level_index] == level:
current_level_index = level_index
break
func update_data() -> void:
get_tree_reference()
player_position = player.transform
level = level_node.scene_file_path
find_level_in_array()
func get_tree_reference() -> void:
player = get_tree().get_first_node_in_group("Player")
level_node = get_tree().get_first_node_in_group("Level")
func save_player_position() -> void:
update_data()
set_setting("Player", "position", player_position)
func save_level_index() -> void:
update_data()
set_setting("Level", "index", current_level_index)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("debug_key"):
update_data()
print(current_level_index, " ", level, " ", player_position)
if event.is_action_pressed("save_key"):
save_player_position()
save_level_index()
# recycled from saving_system:
func save_data() -> void:
var err = config.save(SETTINGS_PATH)
if err != OK:
push_warning("Failed to save: %s" % err)
func load_data() -> void:
var err = config.load(SETTINGS_PATH)
if err != OK:
return
func set_setting(section: String, key: String, value: Variant) -> void:
config.set_value(section, key, value)
save_data()
func get_setting(section: String, key: String, value: Variant) -> Variant:
return config.get_value(section, key, value)
data in attribute.cfg
[Player]
position=Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10.0679, 0.9248332, 13.692233)
[Level]
index=1
The error is relevant to UI script
func fade_out(tween_in: Tween):
color_rect_fader.visible = true
tween_in.tween_property(color_rect_fader, "color:a", 1.0, 0.25).from(0.0)
func change_scene(next_scene: String, player_transform: Transform3D) -> void:
# Store a reference to the player to pass its settings onto the next player.
var player = get_tree().get_first_node_in_group("Player")
# Stop movement and cache settings.
player.set_physics_process(false)
var zoom = player.zoom
var view = player.view
var tween = create_tween()
fade_out(tween)
tween.tween_callback(func(): get_tree().change_scene_to_file(next_scene))
# Wait at least one frame for the scene to update and ready.
tween.tween_interval(0.1)
tween.tween_callback(func():
# Apply the cached variable to the new player.
var new_player = get_tree().get_first_node_in_group("Player")
# Set the player's position in the new level.
new_player.global_transform = player_transform
new_player.view = view
new_player.zoom = zoom
)
fade_in(tween)
# Fade the screen out, reload the level and fade back in.

