【发布时间】:2026-01-09 05:15:01
【问题描述】:
所以我一直在为我的 Unity 项目制作一个保存/加载脚本,它看起来像这样(请不要复制):
using UnityEngine;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Runtime.Serialization;
using System.Reflection;
// Made By Wasabi.
// === This is the info container class ===
[Serializable ()]
public class SaveData : ISerializable {
// === Values ===
public bool foundKeyCard1 = false;
public bool foundKeyCard2 = false;
public bool foundKeyCard3 = false;
public bool foundKeyCard4 = false;
public bool foundKeyCard5 = false;
public bool foundKeyCard6 = false;
public bool foundKeyCard7 = false;
public bool foundKeyCard8 = false;
public bool foundKeyCard9 = false;
public bool foundKeyCard10 = false;
public bool foundCarKeys1 = false;
public float expscore = 0;
public int levelReached = 1;
// === /Values ===
public SaveData () {}
public SaveData (SerializationInfo info, StreamingContext ctxt)
{
foundKeyCard1 = (bool)info.GetValue("foundKeyCard1", typeof(bool));
foundKeyCard2 = (bool)info.GetValue("foundKeyCard2", typeof(bool));
foundKeyCard3 = (bool)info.GetValue("foundKeyCard3", typeof(bool));
foundKeyCard4 = (bool)info.GetValue("foundKeyCard4", typeof(bool));
foundKeyCard5 = (bool)info.GetValue("foundKeyCard5", typeof(bool));
foundKeyCard6 = (bool)info.GetValue("foundKeyCard6", typeof(bool));
foundKeyCard7 = (bool)info.GetValue("foundKeyCard7", typeof(bool));
foundKeyCard8 = (bool)info.GetValue("foundKeyCard8", typeof(bool));
foundKeyCard9 = (bool)info.GetValue("foundKeyCard9", typeof(bool));
foundKeyCard10 = (bool)info.GetValue("foundKeyCard10", typeof(bool));
foundCarKeys1 = (bool)info.GetValue("foundCarKeys1", typeof(bool));
expscore = (float)info.GetValue("expscore", typeof(float));
levelReached = (int)info.GetValue("levelReached", typeof(int));
}
public void GetObjectData (SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("foundKeyCard1", (foundKeyCard1));
info.AddValue("foundKeyCard2", (foundKeyCard2));
info.AddValue("foundKeyCard3", (foundKeyCard3));
info.AddValue("foundKeyCard4", (foundKeyCard4));
info.AddValue("foundKeyCard5", (foundKeyCard5));
info.AddValue("foundKeyCard6", (foundKeyCard6));
info.AddValue("foundKeyCard7", (foundKeyCard7));
info.AddValue("foundKeyCard8", (foundKeyCard8));
info.AddValue("foundKeyCard9", (foundKeyCard9));
info.AddValue("foundKeyCard10", (foundKeyCard10));
info.AddValue("foundCarKeys1", (foundCarKeys1));
info.AddValue("expscore", expscore);
info.AddValue("levelReached", levelReached);
}
}
// === This is the class that will be accessed from scripts ===
public class SaveLoad {
public static string currentFilePath = "SaveData.cjc";
public static void Save () // Overloaded
{
Save (currentFilePath);
}
public static void Save (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath, FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
bformatter.Serialize(stream, data);
stream.Close();
}
public static void Load () { Load(currentFilePath); } // Overloaded
public static void Load (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath, FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new VersionDeserializationBinder();
data = (SaveData)bformatter.Deserialize(stream);
stream.Close();
}
}
// === This is required to guarantee a fixed serialization assembly name, which Unity likes to randomize on each compile
// Do not change this
public sealed class VersionDeserializationBinder : SerializationBinder
{
public override Type BindToType( string assemblyName, string typeName )
{
if ( !string.IsNullOrEmpty( assemblyName ) && !string.IsNullOrEmpty( typeName ) )
{
Type typeToDeserialize = null;
assemblyName = Assembly.GetExecutingAssembly().FullName;
// The following line of code returns the type.
typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) );
return typeToDeserialize;
}
return null;
}
}
我想就是这样。 CS1513 不在里面。如果您发现任何错误,请告诉我。但是问题出在我正在制作的另一个脚本中,当我关闭应用程序时会自动保存。如下图(请勿抄袭):
using UnityEngine; // For Debug.Log, etc.
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.Runtime.Serialization;
using System.Reflection;
// Made by Wasabi.
void OnApplicationQuit()
{
public class SaveLoad {
public static string currentFilePath = "SaveData.cjc";
public static void Save () // Overloaded
{
Save (currentFilePath);
}
public static void Save (string filePath)
{
SaveData data = new SaveData ();
Stream stream = File.Open(filePath,
FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Binder = new
VersionDeserializationBinder();
bformatter.Serialize(stream, data);
stream.Close();
}
}
}
现在我知道void OnApplicationQuit() 下的代码应该是我的保存程序。好吧,我不确定我的保存脚本的哪一部分是我的保存例程。所以如果你能帮我解决这个问题,请随时检查我的保存/加载脚本并告诉我我的实际保存程序是什么。但无论如何,它一直告诉我“错误,”}“预期 (11,7) CS1513。”我检查了我的脚本。我读过另一篇文章,答案是错误意味着我忘记了脚本末尾的结束“}”。好吧,就我而言,这似乎不是真的,因为它没有丢失任何“}”。我什至尝试在最后添加一个额外的“}”,但它仍然说了同样的话。所以它只有在我在打开“{”之后直接放另一个“}”时才会清除错误
void OnApplicationQuit() 这没有任何意义。但是当我这样做时,它会在
void OnApplicationQuit()(具体而言:void OnApplicationQuit() 的 OnApplicationQuit() 的开头)并且我不能为该命名空间使用方法或函数,我不知道这意味着什么,我不知道不认为这是真的。我相信第二个错误只是因为我不得不输入void OnApplicationQuit() {} 而被触发。这里发生了什么,我该如何解决它?另一件事:我在研究如何执行此操作后构建了我的保存/加载脚本,但是代码如何知道我何时收集了 keycard1?我是否必须在 keycard1 中创建一个脚本,当我收集它时告诉保存/加载脚本?这是否会导致我不得不在 Save/Load 脚本中添加更多脚本来检测 keycard1 脚本,告诉 Save/Load 脚本我选择了它?我对 Unity 的整个 C# 部分仍然很陌生,而且我完全是自学成才的。你看,我才刚刚开始做我的第一个严肃的项目。所以我需要知道我用来调用保存和加载的保存/加载脚本中的保存和加载例程到底是什么;因为我需要制作一个带有按钮的菜单屏幕,当按下这些按钮时,会调用保存或加载例程。因此,当我按下保存或加载按钮,查看我的脚本时,脚本会知道我有 KeyCard,还是我必须手动将其放入脚本中?最后,当我获得 KeyCard2 时,如何制作一个调用保存的脚本?
此致,
芥末。
【问题讨论】:
-
“我可以向你保证,我使用的
public static字段和其他方法都很好”——不,它们不是。您应该始终避免使用可变的static状态。此外,正如您自己写的:“我不是 C# 专家”,所以当您的程序目前明显错误时,您无法“向我们保证”您的程序的正确性。 -
@Dai 好的好的!抱歉,如果这显然冒犯了您或以任何方式侮辱了您。正确,我在
c#可能会说“低智商”,因为我是自学成才的,而且我已经有 2 周的时间自学了。 我的意思是通过“我向你保证”是它在 Unity 中工作“非常好”,没有编译器错误或警告,所以它似乎没有造成任何麻烦.但是,如果它仅仅是低效的,那么尽管它是低效的。只要它有效,它就有效。希望这可以解决问题。