【Godot】セーブデータの保存方法

このページでは、Godot Engineでゲームデータをセーブ、ロードする方法について説明をします。

この記事は Godot3.xでの実装方法となります

Godot4.xでの実装方法は以下の記事となります。

【Godot4.x】セーブデータの保存方法

ファイルの読み込みと書き込み

ファイル書き込みは以下の記述で行います

# Fileオブジェクト生成
var f = File.new()

# ファイルを書き込みモードで開く
f.open("user://savedata.txt", File.WRITE)

# "test save" という文字を書き込む
f.store_string("test save")

# ファイルを閉じる
f.close()

このファイルを読み込む場合は以下のように記述します

# Fileオブジェクト生成
var f = File.new()

if f.file_exists("user://savedata.txt"):
  # ファイルが存在していたら読み込みモードで開く
  f.open("user://savedata.txt", File.READ)

  # テキストを取得
  print(f.get_as_text())

  # ファイルを閉じる
  f.close()

保存場所

Godot では「ユーザーパス (user://)」でファイル書き込みを行った場合以下の場所に保存されます

  • Windows: %APPDATA%\Godot\ [プロジェクト名]
  • macOS: ~/Library/Application Support/Godot/[プロジェクト名]

セーブデータが正しく書き込まれたかどうか確認する場合には、このパスにあるファイルをテキストエディタで開いて確認します。

この情報に関する公式ドキュメントは以下のページとなります。

JSON形式で保存する

JSONへの変換処理を使用すると、辞書型のデータがそのままテキストとして保存できて便利です。
例えば書き込み処理は以下のように記述します。

# セーブデータ
var data = {
  "name": "hero", # プレイヤー名
  "hp": 10 # HP
}

# JSONテキストに変換
var s = JSON.print(data, "\t")


var f = File.new()
f.open("user://savedata.txt", File.WRITE)
f.store_string(s)
f.close()

保存された savedata.txt を開くと以下のようなテキストファイルが作成されています。

savedata.txt
{
    "name": "hero",
    "hp": 10
}

読み込み処理は以下のようになります

var f = File.new()
if f.file_exists("user://savedata.txt"):
    # セーブデータが存在するので読み込める
    f.open("user://savedata.txt", File.READ)
    var s = f.get_as_text()
    # JSONテキストを変換
    var err = JSON.parse(s)
    if err.error == OK:
        # 正常に変換できた
        print("name: %s"%err.result["name"])
        print("hp: %d"%err.result["hp"])
    else:
        # 失敗したら新規にセーブデータを作成する
        pass
else:
    # 存在しない場合は新規にセーブデータを作成する
    pass

ゲーム開始時にこの処理を呼び出し、セーブデータを読み込むようにします。
もしファイルが存在しない場合はセーブデータを新規作成し、JSONからの変換が失敗する場合も新規作成するようにします

var2str() / str2var() でデータを直接シリアライズする

var2str() を使用すると直接データをシリアライズすることができます。例えば Vector2() というデータ型を直接シリアライズすることができます。

以下、サンプルコードです。

func _ready() -> void:
	var data = {}
	data["name"] = "hero"
	data["position"] = Vector2(300, 200)
	# 文字列にシリアライズする
	var s = var2str(data)
	print(s)
	print("--------------------")
	
	# 文字列からデータにシリアライズする
	var data2 = str2var(s)
	print(data2["name"])
	print(data2["position"])
実行結果
{
"name": "hero",
"position": Vector2( 300, 200 )
}
--------------------
hero
(300, 200)

ただ、独自のデータ型、例えば class キーワードを使用したデータ構造はシリアライズができなくなります

ですのでおそらくですが、組み込み型のみが対応している印象です。

参考