Godot C#基于Resource的保存系统

之前用的Json保存方案,不太行,很多复杂数据都无法存储

现在改为基于Resource的方案

[GlobalClass]
public partial class SaveDataResource : Resource
{
    [Export] public int Version = 1;
    [Export] public Godot.Collections.Dictionary NodeData = new();
}
public partial class SaveSystem : Node
{
	private const string SavePath = "res://save.res";
	public Error SaveResource()
	{
		try
		{
			SaveDataResource saveData = ResourceLoader.Load(SavePath);
			var persistNodes = GetTree().GetNodesInGroup("Persist");

			foreach (Node node in persistNodes)
			{
				if (node is ISaveable saveable)
				{
					string nodePath = node.Owner.Name + node.Name;
					GD.Print(nodePath, "----nodePath");
					saveData.NodeData[nodePath] = saveable.CaptureState();
				}
			}
			return ResourceSaver.Save(saveData, SavePath);
		}
		catch (System.Exception e)
		{
			GD.PrintErr($"保存失败: {e.Message}");
			return Error.Failed;
		}
	}

	public Error LoadResource()
	{
		if (!ResourceLoader.Exists(SavePath))
			return Error.FileNotFound;

		var saveData = ResourceLoader.Load(SavePath);
		if (saveData == null)
			return Error.InvalidData;

		var persistNodes = GetTree().GetNodesInGroup("Persist");
		foreach (Node node in persistNodes)
		{
			if (node is ISaveable saveable)
			{
				string nodePath = node.Owner.Name + node.Name;
				GD.Print(nodePath, "----nodePath");
				if (saveData.NodeData.TryGetValue(nodePath, out var data))
				{
					saveable.RestoreState((Dictionary)data);
				}
			}
		}
		return Error.Ok;
	}
}

 实现ISaveable接口的类

[GlobalClass]
public partial class Inventory : Node, ISaveable
{
    public Dictionary CaptureState()
    {
        Dictionary keyValuePairs = new();
        for (int i = 0; i < inventorySize; i++)
        {
            if (slots[i].item != null)
            {
                keyValuePairs.Add(i, new Dictionary{
                    {"item",slots[i].item},
                    {"number",slots[i].number},
                });
            }
        }
        return new Dictionary
        {
            { "InventorySlots", keyValuePairs },
        };
    }

    public void RestoreState(Dictionary data)
    {
        slots = new InventorySlot[inventorySize];
        Dictionary keyValuePairs = (Dictionary)data["InventorySlots"];
        foreach ( var item in keyValuePairs)
        {
            InventoryItem inventoryItem =  (InventoryItem)item.Value["item"];
            AddItemToSlot(item.Key,inventoryItem,(int)item.Value["number"]);
        }
        InventoryUpdatedEvent?.Invoke();
    }
}
[GlobalClass]
public partial class Equipment : Node, ISaveable
{
    public Dictionary CaptureState()
    {
        return new Dictionary
        {
            { "EquippedItems", equippedItems },
        };
    }

    public void RestoreState(Dictionary data)
    {
        equippedItems = (Dictionary)data["EquippedItems"];
        EquipmentUpdateEvent?.Invoke();
    }
}

实际效果可以看我B站视频

https://www.bilibili.com/video/BV1cQdgY5EQN/?spm_id_from=333.1007.top_right_bar_window_dynamic.content.click&vd_source=89a4664f2f45743047cedd753a70f5d1

有任何改进方案可以联系我

你可能感兴趣的:(godot,c#)