Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Serialize/Deserialize a custom type/class

Discussion in 'Scripting' started by Bobbypin, Feb 8, 2020.

  1. Bobbypin

    Bobbypin

    Joined:
    Oct 2, 2019
    Posts:
    4
    Hello,

    I'm pretty new to this so I'm sorry if my lack of correct terminology makes my question unclear but I'll try to explain as best I can about the problem I'm having.

    I am making a visual novel which works with a FSM story manager which moves from page to page. Each class is a page in the game. That all works. But when it comes to saving the game data, I don't know how to save, and then load the current state in the FSM, otherwise the page in the story, into my current save format.

    I tried saving the current class name as a string and then loading a new instance of it using system.activator.createinstance(Type.GetType(stringClassName)), however that spits out a null value so either I'm not using it correctly, or I've gone about this in totally the wrong way. I am not against completely reworking my save/load system if that is what needs to be done.

    So here is some code showing what I am currently using. The save/load system works fine for the default types, so I know there isn't anything wrong with the read/write functionality.

    This is the savegame class:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. [System.Serializable]
    5. public class Save
    6. {
    7.     public string thisPage;
    8.     public int gameDifficulty;
    9.     public string playerName;
    10.     public int playerID;
    11.  
    12.     public int decision1;
    13.     public int decision2;
    14.     public int decision3;
    15.     public int decision4;
    16.     public int decision5;
    17.     public int decision6;
    18.     public int decision7;
    19.     public int decision8;
    20.     public int decision9;
    21.     public int decision10;
    22.     public int decision11;
    23.     public int decision12;
    24.     public int decision13;
    25.     public int decision14;
    26.     public int decision15;
    27.     public int decision16;
    28.     public int decision17;
    29.     public int decision18;
    30.     public int decision19;
    31.     public int decision20;
    32.  
    33.  
    34. }
    This is how the contents is saved:

    Code (CSharp):
    1.     private void SaveGame(string saveFileName)
    2.     {
    3.         GameObject canvas = GameObject.Find("Canvas");
    4.         GameManagerScript = canvas.GetComponent<GameManager>();
    5.  
    6.         Save newSaveData = CreateSaveGameObject();
    7.         string ApplicationFolder = Application.dataPath;
    8.         Directory.CreateDirectory(Path.Combine(ApplicationFolder, "Saves"));
    9.         string saveGameDirectory = Path.Combine(ApplicationFolder, "Saves");
    10.         BinaryFormatter saveGameBF = new BinaryFormatter();
    11.         FileStream saveFile = File.Create(Path.Combine(saveGameDirectory, saveFileName + ".save"));
    12.         saveGameBF.Serialize(saveFile, newSaveData);
    13.         saveFile.Close();
    14.  
    15.         GameManagerScript.HandleInformPlayerGameSaved();
    16.         Debug.Log("GameSaved as :" + saveFileName);
    17.     }
    18.     private Save CreateSaveGameObject()
    19.     {
    20.         Save newSave = new Save();
    21.         newSave.thisPage = _thisPage;
    22.         newSave.gameDifficulty = _gameDifficulty;
    23.         newSave.playerName = _playerName;
    24.         newSave.playerID = _playerID;
    25.         newSave.decision1 = _decision1;
    26.         newSave.decision2 = _decision2;
    27.         newSave.decision3 = _decision3;
    28.         newSave.decision4 = _decision4;
    29.         newSave.decision5 = _decision5;
    30.         newSave.decision6 = _decision6;
    31.         newSave.decision7 = _decision7;
    32.         newSave.decision8 = _decision8;
    33.         newSave.decision9 = _decision9;
    34.         newSave.decision10 = _decision10;
    35.         newSave.decision11 = _decision11;
    36.         newSave.decision12 = _decision12;
    37.         newSave.decision13 = _decision13;
    38.         newSave.decision14 = _decision14;
    39.         newSave.decision15 = _decision15;
    40.         newSave.decision16 = _decision16;
    41.         newSave.decision17 = _decision17;
    42.         newSave.decision18 = _decision18;
    43.         newSave.decision19 = _decision19;
    44.         newSave.decision20 = _decision20;
    45.         return newSave;
    46.     }
    This is how the content is loaded and played :

    Code (CSharp):
    1.     public void PlayerLoadGameData(string loadGameName)
    2.     {
    3.         string loadName = loadGameName;
    4.         Debug.Log("Attempting to load game with the filename: " + loadName);
    5.             BinaryFormatter loadGameBF = new BinaryFormatter();
    6.             string ApplicationFolder = Application.dataPath;
    7.             string saveGameDirectory = Path.Combine(ApplicationFolder, "Saves");
    8.             FileStream loadFile = File.Open(Path.Combine(saveGameDirectory,loadName), FileMode.Open);
    9.             Save load = (Save)loadGameBF.Deserialize(loadFile);
    10.             loadFile.Close();
    11.  
    12.             _thisPage = load.thisPage;
    13.             _gameDifficulty = load.gameDifficulty;
    14.             _playerName = load.playerName;
    15.             _playerID = load.playerID;
    16.             _decision1 = load.decision1;
    17.             _decision2 = load.decision2;
    18.             _decision3 = load.decision3;
    19.             _decision4 = load.decision4;
    20.             _decision5 = load.decision5;
    21.             _decision6 = load.decision6;
    22.             _decision7 = load.decision7;
    23.             _decision8 = load.decision8;
    24.             _decision9 = load.decision9;
    25.             _decision10 = load.decision10;
    26.             _decision11 = load.decision11;
    27.             _decision12 = load.decision12;
    28.             _decision13 = load.decision13;
    29.             _decision14 = load.decision14;
    30.             _decision15 = load.decision15;
    31.             _decision16 = load.decision16;
    32.             _decision17 = load.decision17;
    33.             _decision18 = load.decision18;
    34.             _decision19 = load.decision19;
    35.             _decision20 = load.decision20;
    36.         TakeLoadGameAndPlay();
    37.     }
    38.  
    39.     public void TakeLoadGameAndPlay()
    40.     {
    41.         GameObject Canvas = GameObject.Find("Canvas");
    42.         GameManagerScript = Canvas.GetComponent<GameManager>();
    43.         GameManagerScript.HandleCloseGameMenu();
    44.         GameManagerScript.HandleLoadGameDataAndPlay(_thisPage,
    45.                             _gameDifficulty,
    46.                             _language,
    47.                             _playerName,
    48.                             _playerID,
    49.                             _decision1,
    50.                             _decision2,
    51.                             _decision3,
    52.                             _decision4,
    53.                             _decision5,
    54.                             _decision6,
    55.                             _decision7,
    56.                             _decision8,
    57.                             _decision9,
    58.                             _decision10,
    59.                             _decision11,
    60.                             _decision12,
    61.                             _decision13,
    62.                             _decision14,
    63.                             _decision15,
    64.                             _decision16,
    65.                             _decision17,
    66.                             _decision18,
    67.                             _decision19,
    68.                             _decision20
    69.                         );
    70.     }
    71.  
    72.     public void LoadGameDataAndPlay(string thisPage,
    73.                                 int gameDifficulty,
    74.                                 int language,
    75.                                 string playerName,
    76.                                 int playerID,
    77.                                 int decision1,
    78.                                 int decision2,
    79.                                 int decision3,
    80.                                 int decision4,
    81.                                 int decision5,
    82.                                 int decision6,
    83.                                 int decision7,
    84.                                 int decision8,
    85.                                 int decision9,
    86.                                 int decision10,
    87.                                 int decision11,
    88.                                 int decision12,
    89.                                 int decision13,
    90.                                 int decision14,
    91.                                 int decision15,
    92.                                 int decision16,
    93.                                 int decision17,
    94.                                 int decision18,
    95.                                 int decision19,
    96.                                 int decision20
    97.                             )
    98.         {
    99.  
    100.             GameManagerScript.HandleCloseGameMenu();
    101.         Debug.Log("thispage = " + thisPage);
    102.         object loadThisPageFromString = Activator.CreateInstance(Type.GetType(thisPage));
    103.         Debug.Log("thispageTypeIs = " + loadThisPageFromString.ToString());
    104.         IPageState loadThisPageToClassType = (IPageState)loadThisPageFromString;
    105.  
    106.             ThisPage = loadThisPageToClassType;
    107.             _gameDifficulty = gameDifficulty;
    108.             _language = language;
    109.             _playerName = playerName;
    110.             _playerID = playerID;
    111.             _decision1 = decision1;
    112.             _decision2 = decision2;
    113.             _decision3 = decision3;
    114.             _decision4 = decision4;
    115.             _decision5 = decision5;
    116.             _decision6 = decision6;
    117.             _decision7 = decision7;
    118.             _decision8 = decision8;
    119.             _decision9 = decision9;
    120.             _decision10 = decision10;
    121.             _decision11 = decision11;
    122.             _decision12 = decision12;
    123.             _decision13 = decision13;
    124.             _decision14 = decision14;
    125.             _decision15 = decision15;
    126.             _decision16 = decision16;
    127.             _decision17 = decision17;
    128.             _decision18 = decision18;
    129.             _decision19 = decision19;
    130.             _decision20 = decision20;
    131.  
    132.         ThisPage.Run(this);
    133.  
    134.         }
    135.  
    For reference this is an example of a page class:

    Code (CSharp):
    1. public interface IPageState
    2. {
    3.     void Run(FSMStoryHandler storyHandler);
    4.     void OnExitDecision(FSMStoryHandler storyHandler, int pathChosen);
    5. }
    6.  
    7. public class R0B0P2 : FSMStoryHandler, IPageState
    8. {
    9.     public void Run(FSMStoryHandler storyHandler)
    10.     {
    11.         storyHandler._narrationText = "";
    12.         storyHandler._narrationBoxHide = false;
    13.         storyHandler._OCNameText = "";
    14.         storyHandler._OCSpeechText = "..." + _playerName + "?";
    15.         storyHandler._MCSpeechText = "";
    16.         storyHandler._BGMPlaying = "PalacePeaceful";
    17.         storyHandler._BGMEnvironmentPlaying = "";
    18.         storyHandler._background = "BedroomPalace";
    19.         storyHandler._MCSprite = "hide";
    20.         storyHandler._pos1Sprite = "hide";
    21.         storyHandler._pos1SpriteExpression = "";
    22.         storyHandler._pos2Sprite = "";
    23.         storyHandler._pos2SpriteExpression = "";
    24.  
    25.         storyHandler.ViewChange();
    26.         storyHandler.PreviousPage = new R0B0P2();
    27.         storyHandler.ThisPage = new R0B0P2();
    28.         storyHandler.NextPage = new R0B0P3();
    29.     }
    30.     public void OnExitDecision(FSMStoryHandler storyHandler, int PathChosen)
    31.     {
    32.  
    33.     }
    34. }
     
  2. Bobbypin

    Bobbypin

    Joined:
    Oct 2, 2019
    Posts:
    4
    Ok I got it to work.

    I used:

    Code (CSharp):
    1.         Assembly assembly = typeof(IPageState).Assembly;
    2.         Type type = assembly.GetType(thisPage);
    3.         IPageState loadThisPageFromString = (IPageState)Activator.CreateInstance(type);
    Instead of:

    Code (CSharp):
    1.         Debug.Log("thispage = " + thisPage);
    2.         object loadThisPageFromString = Activator.CreateInstance(Type.GetType(thisPage));
    3.         Debug.Log("thispageTypeIs = " + loadThisPageFromString.ToString());
    4.         IPageState loadThisPageToClassType = (IPageState)loadThisPageFromString;