在 Unity 中使用 ScriptableObjects 制作的基于文本的冒险游戏中的 Save/Load 系统问题
Issues with Save/Load System in a Text Based Adventure game made with ScriptableObjects in Unity
我几乎完成了我的基于文本的冒险游戏,我正在尝试设置一个可用的 Save/Load 系统。我似乎无法做到这一点。
看了很多教程,觉得Json可能是我需要的。不幸的是,我似乎无法为 'Load' 部分获得正确的 Json 代码。我还担心我试图保存的数据量对于一个简单的序列化过程来说太多了,或者我过于复杂了,有一个更简单的解决方案。
这是我正在尝试 Save/Load 的数据。如您所见,我有字典和列表,以及我要保存的 'Room' ScriptableObject,即保存游戏时玩家所在的 currentRoom。 currentRoom 在 GameController 中被跟踪。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SaveData
{
public Room saveRoomNavigation;
public List<string> saveNounsInInventory = new List<string>();
public List<InteractableObject> saveUseableItemList = new
List<InteractableObject>();
public Dictionary<string, string> saveExamineDictionary = new
Dictionary<string, string>();
public Dictionary<string, string> saveTakeDictionary = new
Dictionary<string, string>();
public List<string> saveNounsInRoom = new List<string>();
public Dictionary<string, ActionResponse> saveUseDictionary = new
Dictionary<string, ActionResponse>();
public SaveData (GameController controller, InteractableItems
interactableItems)
{
saveRoomNavigation = controller.roomNavigation.currentRoom;
saveNounsInInventory = interactableItems.nounsInInventory;
saveUseableItemList = interactableItems.useableItemList;
saveExamineDictionary = interactableItems.examineDictionary;
saveTakeDictionary = interactableItems.takeDictionary;
saveNounsInRoom = interactableItems.nounsInRoom;
saveUseDictionary = interactableItems.useDictionary;
}
}
然后这是我的保存系统代码,我在其中尝试使用 Json 和二进制文件实现序列化。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class SaveSystem
{
public static void SaveGame (GameController controller,
InteractableItems interactableItems)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/savegame.rta";
FileStream stream = new FileStream(path, FileMode.Create);
SaveData data = new SaveData(controller, interactableItems);
var json = JsonUtility.ToJson(data);
formatter.Serialize(stream, json);
stream.Close();
}
public static SaveData LoadGame()
{
string path = Application.persistentDataPath + "/savegame.rta";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
SaveData data =
JsonUtility.FromJsonOverwrite((string)formatter.Deserialize(stream,
????));
//SaveData data = formatter.Deserialize(stream) as
SaveData;
stream.Close();
return data;
}
else
{
Debug.LogError("Save file not found in " + path);
return null;
}
}
}
我把'????'放在哪里上面是我似乎无法让它接受我试图覆盖的对象的地方,我认为它是 'SaveData' 因为这是我在玩家单击 [= 时将信息放入游戏的地方53=] 按钮。它告诉我“'SaveData' 是一种类型,在给定的上下文中无效”
这是我在使用 'Save' 和 'Load' 按钮时调用的代码,它在我的 GameController Class 中,在玩游戏期间跟踪大部分内容。
public void SaveGame()
{
SaveSystem.SaveGame(this, interactableItems);
}
public void LoadGame()
{
SaveData data = SaveSystem.LoadGame();
roomNavigation.currentRoom = data.saveRoomNavigation;
interactableItems.nounsInInventory = data.saveNounsInInventory;
interactableItems.useDictionary = data.saveUseDictionary;
interactableItems.takeDictionary = data.saveTakeDictionary;
interactableItems.examineDictionary =
data.saveExamineDictionary;
interactableItems.useableItemList = data.saveUseableItemList;
interactableItems.nounsInRoom = data.saveNounsInRoom;
DisplayRoomText();
DisplayLoggedText();
}
在游戏中使用时,我遇到了 "SerializationException" 个错误,所以那是我尝试 Json 的时候。我读到它可以序列化的地方比基本的 Unity Serializer 多得多。错误消失了,使用 Json 似乎可以保存,但现在我无法正确获取加载语法。
我是新手,所以也许我让这件事变得更难了……我也研究了 Userprefs,但我认为我无法将脚本化对象 Room 转换为类型字符串。
提前致谢!
[更新] 这是我能够以 .txt 格式保存的内容。这证明它正在节省,只是不确定 "instanceIDs" 是否会给我所需的负载。
ˇˇˇö{"saveRoomNavigation":
{"instanceID":11496},"saveNounsInInventory":["sword"],"saveUseableItemList":[{"instanceID":11212},{"instanceID":11588} ,{"instanceID":10710},{"instanceID":11578},{"instanceID":10718},{"instanceID":11388},{"instanceID":11276} ],"saveNounsInRoom":["rocks","hole"]}
查看 Unity 内置 JsonUtility 的文档:
https://docs.unity3d.com/Manual/JSONSerialization.html
表示不支持 "Dictionaries" 等类型。鉴于您的 SaveData 示例中有多个词典,我建议您使用更强大的 JSON 库,例如 JSON.NET,它在资产商店中是免费的:
https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347
我几乎完成了我的基于文本的冒险游戏,我正在尝试设置一个可用的 Save/Load 系统。我似乎无法做到这一点。
看了很多教程,觉得Json可能是我需要的。不幸的是,我似乎无法为 'Load' 部分获得正确的 Json 代码。我还担心我试图保存的数据量对于一个简单的序列化过程来说太多了,或者我过于复杂了,有一个更简单的解决方案。
这是我正在尝试 Save/Load 的数据。如您所见,我有字典和列表,以及我要保存的 'Room' ScriptableObject,即保存游戏时玩家所在的 currentRoom。 currentRoom 在 GameController 中被跟踪。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SaveData
{
public Room saveRoomNavigation;
public List<string> saveNounsInInventory = new List<string>();
public List<InteractableObject> saveUseableItemList = new
List<InteractableObject>();
public Dictionary<string, string> saveExamineDictionary = new
Dictionary<string, string>();
public Dictionary<string, string> saveTakeDictionary = new
Dictionary<string, string>();
public List<string> saveNounsInRoom = new List<string>();
public Dictionary<string, ActionResponse> saveUseDictionary = new
Dictionary<string, ActionResponse>();
public SaveData (GameController controller, InteractableItems
interactableItems)
{
saveRoomNavigation = controller.roomNavigation.currentRoom;
saveNounsInInventory = interactableItems.nounsInInventory;
saveUseableItemList = interactableItems.useableItemList;
saveExamineDictionary = interactableItems.examineDictionary;
saveTakeDictionary = interactableItems.takeDictionary;
saveNounsInRoom = interactableItems.nounsInRoom;
saveUseDictionary = interactableItems.useDictionary;
}
}
然后这是我的保存系统代码,我在其中尝试使用 Json 和二进制文件实现序列化。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static class SaveSystem
{
public static void SaveGame (GameController controller,
InteractableItems interactableItems)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/savegame.rta";
FileStream stream = new FileStream(path, FileMode.Create);
SaveData data = new SaveData(controller, interactableItems);
var json = JsonUtility.ToJson(data);
formatter.Serialize(stream, json);
stream.Close();
}
public static SaveData LoadGame()
{
string path = Application.persistentDataPath + "/savegame.rta";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
SaveData data =
JsonUtility.FromJsonOverwrite((string)formatter.Deserialize(stream,
????));
//SaveData data = formatter.Deserialize(stream) as
SaveData;
stream.Close();
return data;
}
else
{
Debug.LogError("Save file not found in " + path);
return null;
}
}
}
我把'????'放在哪里上面是我似乎无法让它接受我试图覆盖的对象的地方,我认为它是 'SaveData' 因为这是我在玩家单击 [= 时将信息放入游戏的地方53=] 按钮。它告诉我“'SaveData' 是一种类型,在给定的上下文中无效”
这是我在使用 'Save' 和 'Load' 按钮时调用的代码,它在我的 GameController Class 中,在玩游戏期间跟踪大部分内容。
public void SaveGame()
{
SaveSystem.SaveGame(this, interactableItems);
}
public void LoadGame()
{
SaveData data = SaveSystem.LoadGame();
roomNavigation.currentRoom = data.saveRoomNavigation;
interactableItems.nounsInInventory = data.saveNounsInInventory;
interactableItems.useDictionary = data.saveUseDictionary;
interactableItems.takeDictionary = data.saveTakeDictionary;
interactableItems.examineDictionary =
data.saveExamineDictionary;
interactableItems.useableItemList = data.saveUseableItemList;
interactableItems.nounsInRoom = data.saveNounsInRoom;
DisplayRoomText();
DisplayLoggedText();
}
在游戏中使用时,我遇到了 "SerializationException" 个错误,所以那是我尝试 Json 的时候。我读到它可以序列化的地方比基本的 Unity Serializer 多得多。错误消失了,使用 Json 似乎可以保存,但现在我无法正确获取加载语法。
我是新手,所以也许我让这件事变得更难了……我也研究了 Userprefs,但我认为我无法将脚本化对象 Room 转换为类型字符串。
提前致谢!
[更新] 这是我能够以 .txt 格式保存的内容。这证明它正在节省,只是不确定 "instanceIDs" 是否会给我所需的负载。
ˇˇˇö{"saveRoomNavigation": {"instanceID":11496},"saveNounsInInventory":["sword"],"saveUseableItemList":[{"instanceID":11212},{"instanceID":11588} ,{"instanceID":10710},{"instanceID":11578},{"instanceID":10718},{"instanceID":11388},{"instanceID":11276} ],"saveNounsInRoom":["rocks","hole"]}
查看 Unity 内置 JsonUtility 的文档:
https://docs.unity3d.com/Manual/JSONSerialization.html
表示不支持 "Dictionaries" 等类型。鉴于您的 SaveData 示例中有多个词典,我建议您使用更强大的 JSON 库,例如 JSON.NET,它在资产商店中是免费的:
https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347