Save Games / Player Prefs

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:

Error building Player: Exception: Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.
Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.
Error: type `System.Xml.XmlTextWriter` doesn't exist in target framework.

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.:shock: 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 :slight_smile:

using UnityEngine; 
using System;
using System.Collections; 
using System.Xml; 
using System.Xml.Serialization; 
using System.IO; 
using System.Text; 
 
public class SavedGame: MonoBehaviour { 
 
	public static string fileLocation,fileName, fileAndroid; 
	UserData myData; 
	string _data; 
	public static int levelNumberRef;
    
	StreamWriter writer;
	int currentLevel;
	int currentDifficulty;

   void Start () 
	{  
		currentLevel = Application.loadedLevel;
		fileName="SaveGame.xml";
     	        fileLocation= Application.persistentDataPath;
		fileAndroid = fileLocation + "/" + fileName;
		FileInfo fileExisting = new FileInfo(fileAndroid);
      	        myData=new UserData(); 
		
		if(currentLevel > 3)
		{
			myData._iUser.levelNumber = currentLevel; 
					_data = SerializeObject(myData); 
		CreateXML(); 
		Debug.Log(_data);
		Debug.Log(fileAndroid);
		}

		if (Application.loadedLevel == 0  fileExisting.Exists) 
		{ 
			LoadXML();
			Debug.Log(fileAndroid);
			if(_data.ToString() != "") 
			{ 
				myData = (UserData)DeserializeObject(_data); 
				levelNumberRef = myData._iUser.levelNumber;
			}
		} 
   } 
 
   string UTF8ByteArrayToString(byte[] characters) 
   {      
      UTF8Encoding encoding = new UTF8Encoding(); 
      string constructedString = encoding.GetString(characters); 
      return (constructedString); 
   } 
 
   byte[] StringToUTF8ByteArray(string pXmlString) 
   { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      byte[] byteArray = encoding.GetBytes(pXmlString); 
      return byteArray; 
   } 
 
   string SerializeObject(object pObject) 
   { 
      string XmlizedString = null; 
      MemoryStream memoryStream = new MemoryStream(); 
      XmlSerializer xs = new XmlSerializer(typeof(UserData));
      XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); 
      xs.Serialize(xmlTextWriter, pObject); 
      memoryStream = (MemoryStream)xmlTextWriter.BaseStream; 
      XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray()); 
      return XmlizedString; 
   } 
 
   object DeserializeObject(string pXmlizedString) 
   { 
      XmlSerializer xs = new XmlSerializer(typeof(UserData)); 
      MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString)); 
      //XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); 
      return xs.Deserialize(memoryStream); 
   } 
 
   void CreateXML() 
   { 
      writer = File.CreateText(fileAndroid); 
      writer.Write(_data); 
      writer.Close(); 
      Debug.Log("File written."); 
   } 
 
   void LoadXML() 
   { 
      StreamReader r = File.OpenText(fileAndroid); 
      string _info = r.ReadToEnd(); 
      r.Close(); 
      _data=_info; 
      Debug.Log("File Read"); 
   } 
} 
 
 public class UserData 
 { 
   public DemoData _iUser; 
   public UserData() {} 
   public struct DemoData 
   { 
      public int levelNumber; 
   } 
}

Found a solution and got it working. Thanks.

Would be nice if you could post a solution here, in case somebody else runs into a similar problem.

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:

using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Collections.Generic;

public class Saver : MonoBehaviour
{ 
	public int levelNumber = 0;
	public int score = 0;
	public int difficultyLevel = 0;

	public static int levelCall;
	public static int scoreCall;
	public static int diffCall;

	
 public void Start()
	{
//Scenes 4 upwards automatically save data when started
		if(Application.loadedLevel > 3)
		{
			levelNumber = Application.loadedLevel;
			score = TurretScript.score;
			difficultyLevel = Difficulty.difficultyLevelSelected;
			PlayerPrefs.SetInt("levelSaver", levelNumber);
			PlayerPrefs.SetInt("scoreSaver", score);
			PlayerPrefs.SetInt("diffSaver", difficultyLevel);
			PlayerPrefs.Save();
		}

// On loading the first scene of my game the saved data is loaded to 
//three variables (levelCall ,scoreCall ,diffCall )
		if(Application.loadedLevel == 0)
		{
			levelCall = PlayerPrefs.GetInt("levelSaver");
			scoreCall = PlayerPrefs.GetInt("scoreSaver");
			diffCall = PlayerPrefs.GetInt("diffSaver");
		}
	}	
}

So then in my menu options it loads the game with the saved data that I stored when the first scene was loaded.

if (GUI.Button(new Rect(buttonXPos, Screen.height/2.0f - Screen.height/4f, buttonWidth, buttonHeight),"Load Previous Game"))
			{
				loadGame = true;
				Application.LoadLevel(Saver.levelCall);
				Game.score = Saver.scoreCall ;
				Difficulty.difficultyLevelSelected = Saver.diffCall ;
			}