データの管理

data-complete.webp

データの保存

Resourceを使用して独自のデータ形式を作ることができます

data-manage-menu.webp

保管場所

プロジェクト設定からデータの保管場所を変更することができます テスト中は決めた場所においておくほうがやりやすいと思います オンにチェックを入れて、保存したいフォルダのパスを直接指定します

custom-user-dir.webp

現在設定されているパスを知りたい場合にはOSの関数を使ってprintすれば確認できます OS.get_user_data_dir()

gdscriptで保存

timestampを保存する簡単なスクリプトを作成します

extends Control

onready var saveButton = $ItemList/Save

var save_path = "user://save.dat"
var data := {}

func _ready():
	saveButton.connect("pressed", self, "save_data")

func save_data():
	var loader = File.new()
	loader.open(save_path, File.WRITE)
	var new_data = {
		"timestamp": OS.get_unix_time()
	}
	data[data.size()] = new_data
	loader.store_line(to_json(data))
	print("saved")
	loader.close()
	load_data()

これでセーブボタンを押せば、save.datファイルにJSON形式でデータが書き出されていると思います

gdscriptで読み込み

セーブデータを読み込み、コンテナにボタンを追加します

onready var container = $ItemList/ScrollContainer/VBoxContainer

func _ready():
	load_data()

func load_data():
	# Load from File
	var loader = File.new()
	if not loader.file_exists(save_path):
		return print("user data couldn't find")
	loader.open(save_path, File.READ)
	while loader.get_position() < loader.get_len():
		data = parse_json(loader.get_line())
	loader.close()
	
	# Clear container	
	for c in container.get_children():
		container.remove_child(c)
	# add data
	for d in data.keys():
		var button = generate_button()
		if data.get(d) is Dictionary and data.get(d).has("timestamp"):
			button.text = str(data.get(d).timestamp)
		container.add_child(button)

ボタンを作成するスクリプトこんな感じです

func generate_button():
	var button = Button.new()
	button.rect_min_size.y = 100
	button.text = "Test"
	return button

データを一括消去する

全ていっぺんに消してしまう場合は簡単です dataを完全に上書きします

onready var clearButton = $ItemList/Clear

func _ready():
	clearButton.connect("pressed", self, "clear_data")
  
func clear_data():
	var loader = File.new()
	loader.open(save_path, File.WRITE)
	data = {}
	loader.store_line(to_json(data))
	print("cleared")
	loader.close()

一部のデータを消去する

削除ボタンを作成して、押したら消えるようにします

セーブデータを一覧にして表示していた部分のボタンに削除ボタンを追加します

func generate_button():
...	
	# delete button
	var delete_button = Button.new()
	delete_button.rect_min_size = Vector2(30, 30)	
	delete_button.text = "x"
	delete_button.name = "Delete"
	delete_button.connect("pressed", self, "delete_data", [button])
	button.add_child(delete_button)
  
  return button

ボタンとデータを繋ぐものが必要なので、新たにDictionaryを追加します ボタンを作成する部分で値を入れます instanceのIDで探すとデータのIDが取得できるようになりました

var buttons := {}

func load_data():
...
	for d in data.keys():
		...
		buttons[str(button.get_instance_id())] = d

削除ボタンが押された時に呼び出す関数を作成します

func delete_data(button: Button):
	container.remove_child(button)
	var index = str(button.get_instance_id())
	if buttons.has(index):
		data.erase(buttons.get(index))
		buttons.erase(index)
  # update file
	var loader = File.new()
	loader.open(save_path, File.WRITE)
	loader.store_line(to_json(data))
	print("deleted")
	loader.close()
	

これで削除できるようになりました

ボタンを押した時にロードされるようにする

セーブボタンとロードボタンが押された時にデータをロードする関数を呼びます

func save_data():
...
	load_data()
  
func clear_data():
...
	load_data()
  
func delete_data(button: Button):
...
	load_data()

もしControlがうまく設定できない場合

UIの基本のページが参考になると思います

参考

OS Directory