繁体   English   中英

学习 Unity 中的保存和加载; 由于未知原因遇到错误 CS1513

[英]Learning about Saving and Loading in Unity; encountered error CS1513 for unknown reason

所以我一直在为我的 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 时,如何制作一个调用保存的脚本?

真挚地,

芥末。

请不要复制

我向你保证,我什至不想^^


你的第二个片段应该做什么?

您有一个方法声明OnApplicationQuit()并在该方法中声明public static字段和其他方法。

-> c# 中不允许这样做。

  • 您的方法OnApplicationQuit()应该属于MonoBehaviour {...}类型的类型
  • 然后你不能在方法中使用访问修饰符。 您宁愿简单地调用该 static 方法SaveLoad.Save()

您宁愿在场景中有一个 GameObject 并附加一个组件,例如

public class SaveLoadBehavior : MonoBehaviour
{
     private void Awake ()
     {
         SaveLoad.Load();
     }

     void OnApplicationQuit()
     {
         SaveLoad.Save();
     }
}

请参阅OnApplicationQuit

请注意,Unity 中的每个组件都需要写入一个单独且同名的文件中。 所以在示例中它应该在SaveLoadBehaviour.cs中(其中.cs隐藏在 Unity 中)


实际上,您可能更愿意使用 RuntimeInitializeOnLoadMethod 和Application.quitting这样的替代方法,您根本不需要上述组件和RuntimeInitializeOnLoadMethod

public class SaveLoad
{
    // will be automatically called on application start
    [RuntimeInitializeOnLoadMethod]
    private static void Init()
    {
        Load();
        // register a callback to the application quitting event
        Application.quitting += OnQuit;
    }

    // will be automatically called on application quit
    private static void OnQuit()
    {
        Save();
    }

    .... // Your load and save methods just the way you have them already

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM