游戏开发分享
[Godot] C#使用Json进行数据结构的保存与加载
2025-09-19
•2 分钟•232 字之前,我使用Godot内置的Resource类实现了游戏的保存与加载功能[Godot] C# 使用Resource类实现保存功能 然而,随着深入的使用,我发现其功能逐渐不能满足我的要求,最重要的一点是,他进行文件的存取必须使用 res:// 或 user:// 开头的路径,所以,对于我最近的使用来说,我需要换一种办法实现数据的存取
最终,我决定使用Json进行数据存取系统,下面我将给大家介绍一下我的实现过程
脚本编写
首先,为了方便使用,我决定先写一个类文件,这里我将我的代码分享给大家
using System;
using System.IO;
using System.Text.Json;
public static class SaveHalper
{
public static bool Save<T>(T data, string path)
{
try
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); //序列化
File.WriteAllText(path, json);
return true;
}
catch
{
return false;
}
}
public static T Load<T>(string path)
{
try
{
var file = File.ReadAllText(path);
return JsonSerializer.Deserialize<T>(file); //反序列化
}
catch
{
return default;
}
}
}
通过这个脚本,我们可以方便的实现数据的存取
数据类编写
对于我们的数据类,我们需要按照下面的格式来写
using System;
using System.Collections.Generic;
[Serializable]
public class Data
{
public string Text { get; set; }
//需要其他自定义类和数组还可以按下面的写
public List<自定义结构类> cardDatas { get; set; } = new();
}
注意,我们需要写[Serializable]才能序列化,为了正常存取,变量需要转成属性
代码使用
这样,我们就能在脚本里面正常的存取了
var error = SaveHalper.Save(data, path); //保存data数据到path路径
var gameData = SaveHalper.Load<data>(path); //读取path数据(data类型)到gameData
//其中,我们可以判断error来看保存是否正常,判断gameData是否为null来看读取是否正常
如上所述,我们就能实现数据的存取了
其他-数据保存
下面,我给大家分享一下我的保存代码
public bool Save()
{
if (data== null)
return false;
var error = SaveHalper.Save(data, path + ".tmp"); //创建临时文件
if (!error) //判断是否创建错误
{
DirAccess.RemoveAbsolute(path + ".tmp"); //移除临时文件
return false;
}
if (FileAccess.FileExists(path))
DirAccess.RemoveAbsolute(path); //移除原文件
DirAccess.RenameAbsolute(path + ".tmp", path); //对临时文件重命名
return true;
}
//或者,我们将其集成在Save函数内
public static bool Save<T>(T data, string path)
{
try
{
var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); //序列化
File.WriteAllText(path + ".tmp", json); //创建临时文件
if (File.Exists(path))
File.Replace(path + ".tmp", path, null); //替换文件
else
{
File.Move(path + ".tmp", path); //移动,创建新文件
}
GD.Print("保存成功");
return true;
}
catch (Exception e)
{
if (File.Exists(path + ".tmp")) //移除临时文件
File.Delete(path + ".tmp");
GD.Print($"保存失败({e})");
return false;
}
}
这样,我们通过创建临时文件的方法,防止了文件保存错误导致原文件错误的问题,大家也可以随意修改分享代码,感谢观看!