简体   繁体   中英

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

So I've been making a save/load script for my Unity project, and it looks like this (please don't copy):

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; 
     } 
 }

And I think that's it. The CS1513 isn't in there. If you spot any errors, please let me know. But the problem is in this other script I'm making that autosaves when I close the application. It looks like this (Please don't copy):

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();
     }
   }
 }

Now I know the code under void OnApplicationQuit() is supposed to be my save routine. Well I'm not exactly sure what part of my save script is my save routine. So If you could help me with that, feel free to examine my save/load script and tell me what is my actual save routine. But anyways, it keeps on telling me "Error, "}" expected (11,7) CS1513." and I check my script. I've read another post and the answer was that the error meant that I had forgotten a closing "}" at the end f my script. Well it seems as though that is not true in my case, because it is not missing any "}". I even tried adding an extra "}" at the end, and yet it still said the same thing. So it only clears the error when I put another "}" directly after the opening "{" after

void OnApplicationQuit() which doesn't make any sense. But when I do, it then says another error at

void OnApplicationQuit() (to be specific: the beginning of OnApplicationQuit() of void OnApplicationQuit() ) and that I can't use methods or functions for that namespace, which I don't know what that means, and I don't think that's true. I believe that the second error is only triggered because I had to put void OnApplicationQuit() {} . What is going on here and how in the world do I fix it? Another thing: I constructed my Save/Load script after researching on how to do that, but how does the code know when I collect a keycard1? Do I have to make a script in the keycard1 that tells the Save/Load script when I collect it? And will this result in me having to add more scripts in the Save/Load script to detect the keycard1 script telling the Save/Load script that I picked it up? I'm still new to the whole C# part of Unity and I'm entirely self-taught. You see, I'm just beginning to make my first serious project. So I need to know what exactly are the save and load routines in my save/load script that I use to call save and load; because I need to make a menu screen with buttons that when pressed, call the save or load routine. So when I press he Save or Load button(s), looking at my script, will the Script know that I have the KeyCard, or will I have to manually put that into the script? And lastly, how do I make a script that calls a save when I obtain, say, KeyCard2?

Sincerely,

Wasabi.

Please don't copy

I assure you that I don't even want to ^^


What is your second snippet supposed to do?

You have a method declaration OnApplicationQuit() and within that method you declare public static fields and other methods.

-> None of this is allowed in c#.

  • your method OnApplicationQuit() should be inside of a type of type MonoBehaviour {...}
  • and then you can't have access modifiers inside a method. You rather want to simply call that static method SaveLoad.Save() .

You would rather have a GameObject in your scene with a component attached like

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

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

See OnApplicationQuit .

Note herefor that every component in Unity needs to be written in a individual and equally named file. So in the example it should be in SaveLoadBehaviour.cs (where the .cs is hidden inside Unity)


Actually alternative to this you might want to rather use eg RuntimeInitializeOnLoadMethod and Application.quitting this way you don't need the afore mentioned component and GameObject at all:

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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