创建场景
我创建了一个简单的场景,有一个文本,和两个按钮
我给他绑定了一个脚本,以显示金钱数量,和金钱增加按钮,点一下增加一块钱
scene.cs
using Godot;
using System;
public partial class scene : Node2D
{
private int Money;
private Label T_Money;
public override void _Ready()
{
T_Money = GetNode<Label>("./money");
}
public override void _Process(double delta)
{
T_Money.Text = $"Money:{Money}";
}
public void AddMoney()
{
Money++;
}
}
实现效果
创建保存脚本
要实现保存的功能,有一个简单的办法,就是用Resource类,我们新建一个脚本,继承自Resource
在这个脚本里面写出来要保存的数据,例如我这个场景的金钱
using Godot;
using System;
public partial class SaveDate : Resource
{
[Export] public int money = new int();
}
在scene脚本中,我们新建一个string字符串变量,作为存档位置
private string SavePath = "user://save.tres";
注意,这个路径是用户路径,位置在
C:\Users\用户名\AppData\Roaming\Godot\app_userdata\项目名
你也可以设置为 res:// 来保存在项目资源位置,但是只能在项目开发时使用,打包发布后就不能保存了
这里我们保存的后缀名是.tres,为了方便查看,也可以保存成.res文件,就加密了,或者你也可以保存为其他格式,如json等
保存函数
void SaveGame()
{
SaveDate saveDate;
if (!FileAccess.FileExists(SavePath))
{
GD.Print("角色文件不存在,正在创建");
saveDate = new SaveDate();
}
else
{
saveDate = ResourceLoader.Load<SaveDate>(SavePath);
}
saveDate.money = Money;
ResourceSaver.Save(saveDate, SavePath);
}
大家看代码就能明白,我们先声明了存档类的对象,然后判断存档文件是否存在,没有的话就建个新的,有的话就加载,之后就对这个对象赋上值,最后再保存即可
我们在Ready函数内调用一下SaveGame函数,然后运行一下场景,去路径上的文件夹找找看
我们找到了这个保存的文件,里面确实有了一个money变量
加载函数
至于加载存档,我们可以再写个LoadGame函数
bool LoadGame()
{
if (!FileAccess.FileExists(SavePath))
{
GD.Print("存档文件不存在,无法加载。");
return false;
}
var saveDate = ResourceLoader.Load<SaveDate>(SavePath);
if (saveDate == null)
{
GD.Print("加载存档失败");
return false;
}
Money = saveDate.money;
return true;
}
之后我们可以在Ready函数里面写一下初始化调用的代码
if (LoadGame())
{
GD.Print("人物加载成功");
}
else
{
SaveGame();
}
现在我们运行场景,可以正确的保存和加载数据了
注意
频繁进行保存和读取操作会出问题,报错,尽量避免频繁读取,而且保存代码可以优化一下,可以设置为空闲时调用保存操作(CallDeferred方法)
void SaveGame()
{
SaveDate saveDate;
if (!FileAccess.FileExists(SavePath))
{
GD.Print("角色文件不存在,正在创建");
saveDate = new SaveDate();
}
else
{
saveDate = ResourceLoader.Load<SaveDate>(SavePath);
}
saveDate.money = Money;
CallDeferred(nameof(SaveToFile),saveDate);
}
void SaveToFile(SaveDate data)
{
ResourceSaver.Save(data, SavePath);
GD.Print("保存完成");
}
其他
如果我们想保存更复杂的数据,像自定义类字典或者数组什么的,可以按照下面的来做
比如我们要实现物品列表的话,自定义一个物品类,键就作为物品ID,里面写比如数量、描述等变量,在存档数据脚本内可以这么写
[Export] public Godot.Collections.Dictionary<int,类名> items = new Godot.Collections.Dictionary<int,类名>();
之后调用的时候就可以很方便的调用和修改了