|
|
|
|
Reply From: |
Bernard Cloutier |
It would be simpler if you posted your code, instead of describing the code. Often, the error lies in parts we overlook when trying to describe it. (Also it’s easier to understand code by reading it instead of being told about it)
Have you done this tutorial on saving and loading? Saving games — Godot Engine (stable) documentation in English
If so, is your save/load mechanism similar? If not, why and how is it different?
It sound like your save file contains a list of node paths and their properties, and that when loading you want to get those properties from the file into their corresponding in-game node. If that’s all you need, then the tutorial should cover it. If not, feel free to ask me for more help (although if you do, please post your save/load scripts!).
Hi Bernard, thanks for the hint and for offering help. I’ll get back to you as soon as I can, and with some code then : )
pferft | 2020-10-15 16:26
Alright, I’ll try to show my setup (cutting out all button-animation related code etc.).
As I say, opening the save.txt-file shows me that saving works – the variables are being altered there accordingly. Pressing the load-button also prints “loading”, but it just won’t refresh exactly what it is loading in the scene itself.
My “game” (for mobile-device – everything meant for touch-input) consists of nothing but a little colored icon at the top of the screen and three checkboxes below with which I can change the color of that icon (blue, green and red). At the bottom are a save- and a load-button. That’s it.
This is what my scene looks like:
My Base-Node is “TheOrigin”:
extends Node2D
onready var save_load: SaveLoadClass = $SaveLoadNode
func _on_ButtonSave_save_button_was_just_released():
save_load.save_states()
func _on_ButtonLoad_load_button_was_just_released():
save_load.load_states()
get_tree().reload_current_scene()
# at least it's doing something, if yet not what it should...
# it reloads the scene but not considering the saved values.
The “first child” is my SaveLoadNode, basically just a script which I also put to AutoLoad:
extends Node
class_name SaveLoadClass
func save_states():
print("Saving...")
var save_game = File.new()
save_game.open("res://save.txt", File.WRITE) # later then "user", I know...
var save_nodes = get_tree().get_nodes_in_group("ToSave")
for save_node in save_nodes:
var save_dict = {
"name": save_node.name,
"value": save_node.pressed, # yes, "value" and "on" are the same here (just a test...)
"path": save_node.get_path(),
"on": save_node.pressed
}
# anti-confusion note to self: alphabetical order in the save-file
save_game.store_line(to_json(save_dict))
save_game.close()
func load_states():
print("Loading...")
var save_game = File.new()
if not save_game.file_exists("res://save.txt"):
print("No save game exists")
return
save_game.open("res://save.txt", File.READ)
while save_game.get_position() < save_game.get_len():
var save_data = parse_json(save_game.get_line())
var node_to_change = get_node(save_data["path"])
node_to_change.pressed = save_data["value"] # again, "value" and "on" are the same here...
node_to_change.pressed = save_data["on"]
save_game.close()
The other child of TheOrigin is TheFirstNode with its children CheckBox1Base, CheckBox2Base and CheckBox3Base, each member of the group ToSave and with this script (accordingly, excerpt is from CheckBox1Base (blue)):
extends Node2D
var pressed = false
var mode_on = false
var mode_off = false
func _ready():
mode_off = true
# mode_on = true # here deactivated, so the checkbox is "off" at loadup.
# This is loaded at load-button-press! But it's not being replaced by the latest saved value.
# Shouldn't it work if this state would be updated at startup/load-button-press?
# How can I have this updated/replaced with the latest saved value? That's the big question.
if mode_on == true:
get_node("CheckBox1AnimPlayer").play("just-big-full")
if mode_off == true:
get_node("CheckBox1AnimPlayer").play("just-big-empty")
########################################################################
var get_signal_from_checkbox_2
get_signal_from_checkbox_2 = get_tree().get_root().find_node("CheckBox2Base", true, false)
get_signal_from_checkbox_2.connect("checkbox_2_on", self, "checkbox_2_on_received")
get_signal_from_checkbox_2.connect("checkbox_2_off", self, "checkbox_2_off_received")
var get_signal_from_checkbox_3
# same like checkbox_2...
func checkbox_2_on_received():
# animate to "off"...
pressed = false
func checkbox_2_off_received():
print("CheckBox 2 OFF (I'm 1)")
# animated accordingly...
func checkbox_3_on_received(): # just like _2_...
########################################################################
func _on_CheckBox1Area_input_event(_viewport, _event, _shape_idx):
# all kind of animation-stuff and then:
if Input.is_action_just_released("mousebuttonclick"):
if mode_off == true or mode_on == false:
pressed = true
# here a tween manages the color of my icon...
mode_off = false
mode_on = true
return
if mode_on == true:
pressed = false
mode_on = false
mode_off = true
The final children of TheFirstNode are ButtonSave and ButtonLoad, basically just releasing their signals:
if Input.is_action_just_released("mousebuttonclick"):
emit_signal("save_button_was_just_released")
or “load_button was_…”
(These are all self-made buttons (CollisionShape2D and all…).)
I tried the tutorials, had them working, but I just can’t make my scene being refreshed at load-button-press. Any hint would be much appreciated.
(I’ll also happily upload a whole example-project, if you’d like!)
pferft | 2020-10-19 13:29
I haven’t read your whole reply, but I noticed this:
func _on_ButtonLoad_load_button_was_just_released():
save_load.load_states()
get_tree().reload_current_scene()
Now assuming your load_states
method works, why would you call reload_current_scene()
after loading from the file? Of course you’re going to end up with your scene in its initial state!
Bernard Cloutier | 2020-10-19 15:51
Ah, that is a yet rather desperate try to “refresh” the scene after loading, as it wouldn’t like it should yet. The idea is to load the saved variables “into position” and then refresh the scene to have them tatking effect. Didn’t work though…
I believe, as max.marauder suggests, if I could get the currently save variables from my SaveLoadNode into my CheckBox-Nodes, like:
func _ready():
mode_off = SaveLoadNode.mode_off
that would do the trick. I just can’t figure out how to “prepare” this mode_off in the SaveLoadNode in order to make it “grabable” from somewhere else then.
pferft | 2020-10-19 15:57
What I meant is what if you switch the statements around? First reload the scene, then load the state.
Bernard Cloutier | 2020-10-19 16:36
It doesn’t seem to change anything.
But I really believe that my code just isn’t complete yet for any effect to take place in this. I can’t figure out how to call the actual value into the func _ready(): of my checkboxes yet. They are in the save-file, but I can’t get them out.
EDIT:
I managed to have the saved stated being printed to the Output at load-button-press, so it’s definitely there. The only thing missing is refreshing…
Don’t want to seem overzealous, but I uploaded the current project just in case you’d like to take a look. Maybe the answer to the problem is plainly obivous that way? (I’d like to hope so! ; )
WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free
I never thought saving/loading could be such an endeavour!
pferft | 2020-10-19 16:48