Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Wolfshadow · Apr 18, 2017 at 02:10 AM · error messageserializationtutorialsavingserialize

Serializer Script

Hello everyone, So, as per @sleepandpancakes advice on question save datasets at runtime I used this tutorial on how to create a serializer script, courtesy of Ryan Nielson. saving games in unity

I transcribed the scripts word for word, and now am trying to put them into my application in unity by dragging+dropping the script onto a gameobject, like normal. However, when I do this, I get the error message:

can't add because

  1. script needs to derive from monobehavior

  2. script class can't be abstract

Any ideas/people run into this problem before? and by the way, the scripts don't want to be not abstract, or use monobehavior. They are not supposed to (at least not in the tutorial)

Anyway, sorry for asking this "error message" question, but I haven't been able to find anything similar to this online. My bad if this is an obvious fix, but thank you all for your help.

Gratefully, Wolfshadow

scripts:

 using UnityEngine;
 
 using System.IO;
 using System.Runtime.Serialization.Formatters.Binary;
 using System;
 
 public static class SaveGameSystem 
 {
     
         
     public static bool SaveGame (SaveGame saveGame, string name)
     {
         BinaryFormatter formatter = new BinaryFormatter ();
         using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Create)) {
             try {
                 formatter.Serialize (stream, saveGame);
             } catch (Exception) {
                 return false;
             }
         }
         return true;
     }
 
     public static SaveGame LoadGame (string name)
     {
         if (!DoesSaveGameExist (name)) {
             return null;
         }
         BinaryFormatter formatter = new BinaryFormatter ();
         using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Open)) {
             try {
                 return formatter.Deserialize (stream) as SaveGame;
             } catch (Exception) {
                 return null;
             }
 
         }
     }
 
     public static bool DeleteSaveGame (string name)
     {
         try {
 
             File.Delete (GetSavePath (name));
         } catch (Exception) {
             return false;
         }
 
         return true;
     }
 
     public static bool DoesSaveGameExist (string name)
     {
         return File.Exists (GetSavePath (name));
     }
 
     private static string GetSavePath (string name)
     {
         return Path.Combine (Application.persistentDataPath, name + ".sav");
     }
 
 
 
 
 }
 

and

 using System;
 [Serializable]
 
 public class MySaveGame : SaveGame {
     public string playerName = "John";
     public int HighScore { get; set; }
 
     [NonSerialized]
     public string secret = "Nope";
 
     void Start ()
     {
         MySaveGame mySaveGame1 = new MySaveGame ();
         mySaveGame1.playerName = "John";
         mySaveGame1.HighScore = 20;
         mySaveGame1.secret =20.ToString ();
         SaveGameSystem.SaveGame (mySaveGame1, "MySaveGame");
 
     }
 }
 

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Vicarian · Apr 18, 2017 at 04:02 AM

@Wolfshadow Since all the methods in the base class SaveGame are static, instead of adding the script directly to a gameObject, you'd make a script to drive the SaveGame object and just call the static methods you need. Attempting to call instance methods from the derived class MySaveGame would result in a compiler error, because those methods aren't instanced. To call a static function, all you need to do is supply the Type and access the function you need:

 MySaveGame.SaveGame();

If you need the fields and property you defined in the derived class, then you'd add this class as an instance member of another script, then wrap the static methods into functions in the driver class.

SaveGameCaller.cs:

 using UnityEngine;
 
 public class SaveGameCaller : MonoBehaviour
 {
     MySaveGame mySaveGame = new MySaveGame()

      void Update ()
      {
          if (Input.GetKeyDown ("s")) {
              SaveGame ();
          }
 
          if (Input.GetKeyDown("l")) {
              LoadSaveGame ();
          }
 
          if (Input.GetKeyDown("d")) {
              DeleteSaveGame ();
          }
     }

     void Start() {
         mySaveGame.playerName = "John";
         mySaveGame.HighScore = 20;
         mySaveGame.secret =20.ToString ();
     
         SaveGame();
     }

     public void SaveGame()
     {
         // The first argument is an example of C#'s polymorphism functionality, 
         // which allows you to treat derived classes as their base class.
         SaveGameSystem.SaveGame(mySaveGame, "SomeName");
     }
     public void LoadSaveGame()
     {
         SaveGameSystem.LoadSaveGame("SomeName");
     }
     public void DeleteSaveGame()
     {
         SaveGameSystem.DeleteSaveGame("SomeName");
     }
 }

You'd add the above to a GameObject and hook up some UI elements to call those functions, or create states necessary for saving.

SaveGameSystem.cs

 using System;

  public static class SaveGameSystem 
  {
      
      private static MySaveGame mySaveGame;
      public static bool SaveGame (SaveGame saveGame, string name)
      {
          BinaryFormatter formatter = new BinaryFormatter ();
          using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Create)) {
              try {
                  formatter.Serialize (stream, saveGame);
              } catch (Exception) {
                  return false;
              }
          }
          return true;
      }
  
      public static SaveGame LoadGame (string name)
      {
          if (!DoesSaveGameExist (name)) {
              return null;
          }
          BinaryFormatter formatter = new BinaryFormatter ();
          using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Open)) {
              try {
                  return formatter.Deserialize (stream) as SaveGame;
              } catch (Exception) {
                  return null;
              }
  
          }
      }
  
      public static bool DeleteSaveGame (string name)
      {
          try {
  
              File.Delete (GetSavePath (name));
          } catch (Exception) {
              return false;
          }
  
          return true;
      }
  
      public static bool DoesSaveGameExist (string name)
      {
          return File.Exists (GetSavePath (name));
      }
  
      private static string GetSavePath (string name)
      {
          return Path.Combine (Application.persistentDataPath, name + ".sav");
      }
  }

MySaveGame.cs

  using System;
  using System.Collections;
  using UnityEngine;
 
  [Serializable]
 
  public class MySaveGame: SaveGame
  {
      public string playerName = "John";
      public int HighScore { get; set; }
 
      [NonSerialized]
      public string secret = "Nope";
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by SweatyChair · Apr 18, 2017 at 08:02 AM

SaveGameSystem is static so you cannot drag it and making it abstract (and you DON'T need to in 99% of the cases), just use it in your code anywhere. I would also keep the MySaveGame object reference in SaveGameSystem to make things easier as:

  public static class SaveGameSystem 
  {
      
      private static MySaveGame mySaveGame;
          
      public static bool SaveGame (string fileName)
      {
           if (mySaveGame == null)
                mySaveGame = new MySaveGame();
           ...
           formatter.Serialize (stream, mySaveGame);
           ...
      }

      public static void LoadGame (string fileName)
      {
           ...
           mySaveGame = formatter.Deserialize (stream) as SaveGame;
           ...
      }
 
      ...
 }

Then, you can save the current game anywhere by just calling:

 SaveGameSystem.Save(fileName);

You can make MySaveGame abstract and have other classes override it if you want. In my games, I have a abstract MySaveGame, and it's children class MyServerSaveGame (sync to PlayGames, etc) and MyLocalSaveGame (just works like PlayerPrefs in local):

 [System.Serializable]
 public abstract class MySaveGame
 {
     ...
 }
 
 [System.Serializable]
 public class MyServerSaveGame : MySaveGame
 {
     ...
 }


This is my game save system, syncing to PlayGames and iCloud using Prime31 plugin, if you wanna go further with it: GameSaveManager

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Wolfshadow · Apr 19, 2017 at 02:16 AM

@Vicarian , alright, so I did what you suggested, but, as I am new to c#, I am having some trouble implementing it. So, I have savegamesystem using System;

 public static class SaveGameSystem 
 {
     
     private static MySaveGame mySaveGame;
     public static bool SaveGame (SaveGame saveGame, string name)
     {
         BinaryFormatter formatter = new BinaryFormatter ();
         using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Create)) {
             try {
                 formatter.Serialize (stream, saveGame);
             } catch (Exception) {
                 return false;
             }
         }
         return true;
     }
 
     public static SaveGame LoadGame (string name)
     {
         if (!DoesSaveGameExist (name)) {
             return null;
         }
         BinaryFormatter formatter = new BinaryFormatter ();
         using (FileStream stream = new FileStream (GetSavePath (name), FileMode.Open)) {
             try {
                 return formatter.Deserialize (stream) as SaveGame;
             } catch (Exception) {
                 return null;
             }
 
         }
     }
 
     public static bool DeleteSaveGame (string name)
     {
         try {
 
             File.Delete (GetSavePath (name));
         } catch (Exception) {
             return false;
         }
 
         return true;
     }
 
     public static bool DoesSaveGameExist (string name)
     {
         return File.Exists (GetSavePath (name));
     }
 
     private static string GetSavePath (string name)
     {
         return Path.Combine (Application.persistentDataPath, name + ".sav");
     }
 
 
 
 
 }
 

that is working fine.

I have savegamecaller

 using UnityEngine;
 using System.Collections;
 
 public class SaveGameCaller : MonoBehaviour {
 
     MySaveGame mySaveGame = new MySaveGame ();
 
         public void SaveGame()
     {
 
         MySaveGame.SaveGame (mySaveGame, "SomeName");
     }
 
     public void LoadSaveGame()
     {
         MySaveGame.LoadSaveGame ("SomeName");
     }
 
     public void DeleteSaveGame()
     {
         MySaveGame.DeleteSaveGame ("SomeName");
     }
 }
 


as you suggested. Now, what problematic is mysavegame:

 using UnityEngine;
 using System.Collections;
     using System;
     [Serializable]
 
     public class MySaveGame: SaveGame
     {
         public string playerName = "John";
         public int HighScore { get; set; }
 
         [NonSerialized]
         public string secret = "Nope";
 
         void Start ()
         {
             MySaveGame mySaveGame1 = new MySaveGame ();
             mySaveGame1.playerName = "John";
             mySaveGame1.HighScore = 20;
             mySaveGame1.secret =20.ToString ();
             SaveGameSystem.SaveGame (mySaveGame1, "MySaveGame");
             
         }
 
     void Update ()
     {
         if (Input.GetKeyDown ("s")) {
             SaveGame ();
 
         }
 
         if (Input.GetKeyDown("l")) {
             LoadSaveGame ();
         }
 
         if (Input.GetKeyDown("d")) {
             DeleteSaveGame ();
         }
 
     }
 
     static public void SaveGame ()
     {
 
     }
 
     static public void LoadSaveGame ()
     {
 
     }
 
     static public void DeleteSaveGame()
     {
 
     }
 }
 

I get error cs1501, saying that no overload for method SaveGame (LoadSaveGame, etc.) takes 1 arguements. I know this must be an easy fix, but I can't find anything online.

Thank you for your help. Its bee really helpful for me, and I am grateful.

p.s. sorry for answer format, comments wasn't working right

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sleepandpancakes · Apr 19, 2017 at 02:29 AM 0
Share

SaveGame and $$anonymous$$ySaveGame are not $$anonymous$$onobehaviours, they are just simple serializable classes that hold the save data. Your $$anonymous$$ySaveGame script should not have any $$anonymous$$onoBehaviour functions (Start, Update, etc.) and doesn't need SaveGame(), LoadSaveGame(), or DeleteSaveGame(), because that's what the SaveGameSystem is for. I recommend taking a closer look at the source website.

avatar image Vicarian · Apr 19, 2017 at 03:38 PM 0
Share

@Wolfshadow I updated my original post to distinguish between the three files you'll be using. Drop SaveGameCaller onto a GameObject somewhere, and the Update() method on it will take care of you.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

74 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Saving Game Confussion 1 Answer

object list not serializing 2 Answers

IOException: Sharing violation on path 1 Answer

how to serialize unity variables? (Sprite, Image ...) 1 Answer

Saving players progress in ScriptableObject asset 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges