Search Unity

Save Games / Player Prefs

Discussion in 'Windows' started by UserX, Oct 25, 2013.

  1. UserX

    UserX

    Joined:
    Nov 7, 2012
    Posts:
    12
    Hey guys,
    I was wondering if you could help me out, I'm having some problems with my saved game file (thank you Zumwalt from http://wiki.unity3d.com) on Windows Phone and I've been trying to find a solution for a few days and I'm stuck.

    So, I get this error when I create a build:

    Code (csharp):
    1. Error building Player: Exception: Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.
    2. Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.
    3. Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.
    4.  
    I understand that its because its part of a library I can't use. Can anyone suggest an alternative to System.Xml.XmlTextWriter? I tried using StreamWriter but that didn't work. I've posted my full code below.

    I've also tried using the Player Prefs code from here instead http://wiki.unity3d.com/index.php/PlayerSave to work around the xml problem, but I ran into problems too. When I deployed it to the phone it worked fine on first launch ie. i could exit to the menu, hit load game and it would call the saved game perfectly, but when I closed the app and reopened it, it seemed to have lost the data.:eek: Has anyone encountered this? I don't have a delete method anywhere. I can post the code to this too if needed.

    Any help or a code sample of a fully working save game/player prefs solution for windows phone would be greatly appreciated. Thanks in advance :)

    Code (csharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Xml;
    5. using System.Xml.Serialization;
    6. using System.IO;
    7. using System.Text;
    8.  
    9. public class SavedGame: MonoBehaviour {
    10.  
    11.     public static string fileLocation,fileName, fileAndroid;
    12.     UserData myData;
    13.     string _data;
    14.     public static int levelNumberRef;
    15.    
    16.     StreamWriter writer;
    17.     int currentLevel;
    18.     int currentDifficulty;
    19.  
    20.    void Start ()
    21.     {  
    22.         currentLevel = Application.loadedLevel;
    23.         fileName="SaveGame.xml";
    24.                 fileLocation= Application.persistentDataPath;
    25.         fileAndroid = fileLocation + "/" + fileName;
    26.         FileInfo fileExisting = new FileInfo(fileAndroid);
    27.                 myData=new UserData();
    28.        
    29.         if(currentLevel > 3)
    30.         {
    31.             myData._iUser.levelNumber = currentLevel;
    32.                     _data = SerializeObject(myData);
    33.         CreateXML();
    34.         Debug.Log(_data);
    35.         Debug.Log(fileAndroid);
    36.         }
    37.  
    38.         if (Application.loadedLevel == 0  fileExisting.Exists)
    39.         {
    40.             LoadXML();
    41.             Debug.Log(fileAndroid);
    42.             if(_data.ToString() != "")
    43.             {
    44.                 myData = (UserData)DeserializeObject(_data);
    45.                 levelNumberRef = myData._iUser.levelNumber;
    46.             }
    47.         }
    48.    }
    49.  
    50.    string UTF8ByteArrayToString(byte[] characters)
    51.    {      
    52.       UTF8Encoding encoding = new UTF8Encoding();
    53.       string constructedString = encoding.GetString(characters);
    54.       return (constructedString);
    55.    }
    56.  
    57.    byte[] StringToUTF8ByteArray(string pXmlString)
    58.    {
    59.       UTF8Encoding encoding = new UTF8Encoding();
    60.       byte[] byteArray = encoding.GetBytes(pXmlString);
    61.       return byteArray;
    62.    }
    63.  
    64.    string SerializeObject(object pObject)
    65.    {
    66.       string XmlizedString = null;
    67.       MemoryStream memoryStream = new MemoryStream();
    68.       XmlSerializer xs = new XmlSerializer(typeof(UserData));
    69.       XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
    70.       xs.Serialize(xmlTextWriter, pObject);
    71.       memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
    72.       XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
    73.       return XmlizedString;
    74.    }
    75.  
    76.    object DeserializeObject(string pXmlizedString)
    77.    {
    78.       XmlSerializer xs = new XmlSerializer(typeof(UserData));
    79.       MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
    80.       //XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
    81.       return xs.Deserialize(memoryStream);
    82.    }
    83.  
    84.    void CreateXML()
    85.    {
    86.       writer = File.CreateText(fileAndroid);
    87.       writer.Write(_data);
    88.       writer.Close();
    89.       Debug.Log("File written.");
    90.    }
    91.  
    92.    void LoadXML()
    93.    {
    94.       StreamReader r = File.OpenText(fileAndroid);
    95.       string _info = r.ReadToEnd();
    96.       r.Close();
    97.       _data=_info;
    98.       Debug.Log("File Read");
    99.    }
    100. }
    101.  
    102.  public class UserData
    103.  {
    104.    public DemoData _iUser;
    105.    public UserData() {}
    106.    public struct DemoData
    107.    {
    108.       public int levelNumber;
    109.    }
    110. }
     
    Last edited: Oct 25, 2013
  2. UserX

    UserX

    Joined:
    Nov 7, 2012
    Posts:
    12
    Found a solution and got it working. Thanks.
     
  3. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Would be nice if you could post a solution here, in case somebody else runs into a similar problem.
     
  4. UserX

    UserX

    Joined:
    Nov 7, 2012
    Posts:
    12
    Sure, no problem.
    I couldn't find a direct solution to the issues I mentioned above, so in the end I opted to just use Player Prefs (http://docs.unity3d.com/Documentation/ScriptReference/PlayerPrefs.html) which got rid of the problem of data being lost when I restarted the game.

    I created this script and attached it to an object in all the scenes in my game:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4. using System;
    5. using System.Collections.Generic;
    6.  
    7. public class Saver : MonoBehaviour
    8. {
    9.     public int levelNumber = 0;
    10.     public int score = 0;
    11.     public int difficultyLevel = 0;
    12.  
    13.     public static int levelCall;
    14.     public static int scoreCall;
    15.     public static int diffCall;
    16.  
    17.    
    18.  public void Start()
    19.     {
    20. //Scenes 4 upwards automatically save data when started
    21.         if(Application.loadedLevel > 3)
    22.         {
    23.             levelNumber = Application.loadedLevel;
    24.             score = TurretScript.score;
    25.             difficultyLevel = Difficulty.difficultyLevelSelected;
    26.             PlayerPrefs.SetInt("levelSaver", levelNumber);
    27.             PlayerPrefs.SetInt("scoreSaver", score);
    28.             PlayerPrefs.SetInt("diffSaver", difficultyLevel);
    29.             PlayerPrefs.Save();
    30.         }
    31.  
    32. // On loading the first scene of my game the saved data is loaded to
    33. //three variables (levelCall ,scoreCall ,diffCall )
    34.         if(Application.loadedLevel == 0)
    35.         {
    36.             levelCall = PlayerPrefs.GetInt("levelSaver");
    37.             scoreCall = PlayerPrefs.GetInt("scoreSaver");
    38.             diffCall = PlayerPrefs.GetInt("diffSaver");
    39.         }
    40.     }  
    41. }
    So then in my menu options it loads the game with the saved data that I stored when the first scene was loaded.
    Code (csharp):
    1.  
    2. if (GUI.Button(new Rect(buttonXPos, Screen.height/2.0f - Screen.height/4f, buttonWidth, buttonHeight),"Load Previous Game"))
    3.             {
    4.                 loadGame = true;
    5.                 Application.LoadLevel(Saver.levelCall);
    6.                 Game.score = Saver.scoreCall ;
    7.                 Difficulty.difficultyLevelSelected = Saver.diffCall ;
    8.             }
    9.  
     
    Last edited: Nov 8, 2013