Hello World!


Hello World!

Hello everyone, I'm creating this blog with the purpose of sharing my and your ideas with all hungry for game development.

Follow Tweeter

empty space


Sunday, April 3, 2011

XML - Writing to an existing xml file

Continuing with XML, in this simple example I'll show you how to write to a xml file and then load and transform strings to float.




This is the prototype of the xml file, written by hand.

  
    values
    values
    values
  


Save the XML file into your project, if you want you can delete rotation node because the program will create everything automatically.

Below, the main program code with the functions WriteToXml () and LoadFromXML ().

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
 
 
public class ReadXmlData : MonoBehaviour // the Class.
{
 public GameObject CubeObject; // object to get a apply the transforms.
 public GUISkin customSkin;
 
 private Rect windowRect = new Rect((Screen.width/2)-250, 20, 500, 200);
 
 private string x = ""; // string to work with the xml file.
 private string y = ""; // string to work with the xml file.
 private string z = ""; // string to work with the xml file.
 
 private float X = 0; // we will apply the values ​​of the strings here.
 private float Y = 0; // we will apply the values ​​of the strings here.
 private float Z = 0; // we will apply the values ​​of the strings here.
 
 void Update()
 {
  x = CubeObject.transform.rotation.eulerAngles.x.ToString(); // taking the values ​​of transformation.
  y = CubeObject.transform.rotation.eulerAngles.y.ToString(); // taking the values ​​of transformation.
  z = CubeObject.transform.rotation.eulerAngles.z.ToString(); // taking the values ​​of transformation.
 }
 
 void OnGUI()
 {
  if(customSkin)
    GUI.skin = customSkin;
    else
    Debug.Log("StartMenuGUI : GUI Skin object missing!");
 
  windowRect = GUILayout.Window(0, windowRect, DoMyWindow, "Transforms");
 
  GUILayout.BeginArea(new Rect(Screen.width/2-100,110,150,100));
   GUILayout.Label("Click and drag the cube!");
  GUILayout.EndArea();
 }
 
 void DoMyWindow(int windowID)
 {
   GUILayout.BeginHorizontal();
    GUILayout.Label("Angles  X:");
    x = GUILayout.TextField(x,10);
   
    GUILayout.Label("  Y:");
    y = GUILayout.TextField(y,10);
 
    GUILayout.Label("  Z:");
    z = GUILayout.TextField(z,10);
    GUILayout.FlexibleSpace();
   GUILayout.EndHorizontal();
   
   GUILayout.BeginHorizontal();
    if(GUILayout.Button("Save"))
    {
     WriteToXml(); // calls the function when the button is pressed.
    }
    if(GUILayout.Button("Restore"))
    {
     LoadFromXml(); // calls the function when the button is pressed.
    }
    GUILayout.FlexibleSpace();
   GUILayout.EndHorizontal();
       
    }
 
 public void WriteToXml()
 {
 
     string filepath = Application.dataPath + @"/Data/gamexmldata.xml";
  XmlDocument xmlDoc = new XmlDocument();
 
  if(File.Exists (filepath))
  {
   xmlDoc.Load(filepath);
   
   XmlElement elmRoot = xmlDoc.DocumentElement;
   
    elmRoot.RemoveAll(); // remove all inside the transforms node.
   
    XmlElement elmNew = xmlDoc.CreateElement("rotation"); // create the rotation node.
   
     XmlElement rotation_X = xmlDoc.CreateElement("x"); // create the x node.
      rotation_X.InnerText = x; // apply to the node text the values of the variable.
   
     XmlElement rotation_Y = xmlDoc.CreateElement("y"); // create the y node.
      rotation_Y.InnerText = y; // apply to the node text the values of the variable.
   
     XmlElement rotation_Z = xmlDoc.CreateElement("z"); // create the z node.
      rotation_Z.InnerText = z; // apply to the node text the values of the variable.
   
   elmNew.AppendChild(rotation_X); // make the rotation node the parent.
   elmNew.AppendChild(rotation_Y); // make the rotation node the parent.
   elmNew.AppendChild(rotation_Z); // make the rotation node the parent.
   elmRoot.AppendChild(elmNew); // make the transform node the parent.
   
   xmlDoc.Save(filepath); // save file.
  }
 }
 
 public void LoadFromXml()
 {
  string filepath = Application.dataPath + @"/Data/gamexmldata.xml";
  XmlDocument xmlDoc = new XmlDocument();
 
  if(File.Exists (filepath))
  {
   xmlDoc.Load(filepath);
   
   XmlNodeList transformList = xmlDoc.GetElementsByTagName("rotation");
 
   foreach (XmlNode transformInfo in transformList)
   {
    XmlNodeList transformcontent = transformInfo.ChildNodes;
   
    foreach (XmlNode transformItens in transformcontent)
    {
     if(transformItens.Name == "x")
     {
      X = float.Parse(transformItens.InnerText); // convert the strings to float and apply to the X variable.
     }
     if(transformItens.Name == "y")
     {
      Y = float.Parse(transformItens.InnerText); // convert the strings to float and apply to the Y variable.
     }
     if(transformItens.Name == "z")
     {
      Z = float.Parse(transformItens.InnerText); // convert the strings to float and apply to the Z variable.
     }
     
    }
   }
  }
  CubeObject.transform.eulerAngles =new Vector3(X,Y,Z); // Apply the values to the cube object.
 
 }
 
}


Here the full project source, give your comments and enjoy it!

30 comments:

  1. Cool!

    So you could use this to write save games to remember the exact position and status of everything in the engine from objects to variables?

    ReplyDelete
  2. nice! hope that thou shalt continue! =)

    ReplyDelete
  3. ¡EXCELENTE!
    Muchas gracias.

    ReplyDelete
  4. may be in javascript

    ReplyDelete
  5. Amazing! The only con. is that its not crypted so its editable by anyone, but exactly that characteristic will fit into my project!!! Thank you VERY VERY Much for the help!!! does it works with free unity version?

    ReplyDelete
  6. Yes, in fact, was done in the free version. thanks for the comments.

    ReplyDelete
  7. Thanks good script but how its work? at what i must add the script, and how use it in game for save data or load

    ReplyDelete
  8. You can download the full project in the end of the post, and then study how it was done.

    ReplyDelete
  9. Hi I try this code and it works for my almost perfect. I've got some problem with export it to web player. It stops in line 79 "if(File.Exists (filepath))". If I skip this code stops in line 81 "xmlDoc.Load(filepath);". I don't known where is problem and how to make it works.

    Thanks for any help.

    ReplyDelete
    Replies
    1. Try this :

      string url = "http://unitynoobs/StreamingAssets/gamexmldata.xml" // your host

      WWW www = new WWW(url);

      XmlDocument xmlDoc = new XmlDocument();

      xmlDoc.Load(www.url);

      Delete
    2. I still have a problem with it. I found log for this webpalyer file and it says
      "
      MethodAccessException: Attempt to access a private/protected method failed.
      at System.Security.SecurityManager.ThrowException (System.Exception ex) [0x00000] in :0

      at ReadXmlData.WriteToXml () [0x00000] in :0

      at ReadXmlData.DoMyWindow (Int32 windowID) [0x00000] in :0

      at UnityEngine.GUILayout+LayoutedWindow.DoWindow (Int32 windowID) [0x00000] in :0

      at UnityEngine.GUI+_Window.Do () [0x00000] in :0

      at UnityEngine.GUI.BeginWindows (Int32 skinMode, UnityEngine.IDList idlist, Int32 editorWindowInstanceID) [0x00000] in :0
      "

      Delete
    3. Unfortunately are still very few functional tutorials on the net about xml parsing.
      and also unfortunately the.... "Try this" option does not work in any version.
      It looks like url xml parsing is completely inaccessible at the moment....

      Delete
  10. This comment has been removed by the author.

    ReplyDelete
  11. A million Thanks! :)
    I want a system in which I can save multiple entries with a time stamp (instead of only one set of transforms in the XML)
    Can you please tell me how to do it? :)

    ReplyDelete
  12. Thank u yaar... i'll try it...

    ReplyDelete
  13. Excellent work, thanks for sharing

    ReplyDelete
  14. Thanks for sharing!

    ReplyDelete
  15. Hey I'm using a very similar method for a data logger when saving but I'm running into an odd issue. The xml document gets saved but will only update if I leave switch from Unity to another program, then back to Unity. Any ideas why?

    ReplyDelete
    Replies
    1. Finally found a solution!
      For anyone else that runs into this issue, the problem isn't that the xml file isn't getting saved, it's that Unity's TextAsset that represents the xml file is not getting updated.
      Simply throwing AssetDatabase.Refresh(); after the save will fix the issue.

      Delete
  16. Why when I try to save string and load it back it is this: System.Xml.XmlElement

    ReplyDelete

  17. Hi, it works well in editor, but I get MethodAccessException : Attempt to Acess a provate/protected method failed.

    when I run from web player build

    Thanks in Advance!!

    ReplyDelete
  18. does this works on android devices ?

    ReplyDelete
  19. this is very useful thank u so much

    ReplyDelete
  20. Hello , After finishing the game i Build the game on win standalone . i faced problem when saving into Xml .
    it does not work until i open the game as Admin . do you have a way to fix it ?

    ReplyDelete
  21. Hey ,
    i want to do the same thing but xml is not in project ...it will come from some url ..... I am using www .... iwas getting dat from there but its not getting saved(post)... any help on it how to that?

    ReplyDelete
  22. I watched your video on youtube and commented way too early. Was confused why you didn't show any of the code that actually saved the information. Must apologize for that. Found this site and am so extremely grateful for your help! This was exactly what I was looking for to get started with what I am trying to do. Much much thanks for your work!

    ReplyDelete
  23. Thanks A bunch. This is likely the best tutorial for someone who is just starting the basics of this.. You Rock!

    ReplyDelete
  24. This comment has been removed by the author.

    ReplyDelete
  25. This comment has been removed by the author.

    ReplyDelete