The scene in Unity resolves to JSON and XML and restores the scene

Source: Internet
Author: User
Tags sca

In fact about this part of the content, the Rain Pine Institute has written very clearly, but also more authoritative, link in this: http://www.xuanyusong.com/archives/1919, but now still want to according to their own ideas to tidy up

In fact, the principle is that all the parent objects in the hierarchy (that is, transform.parent = = null) are made into a preset, and then record the properties of each parent object's transform, log into the XML or JSON file, and then parse the file, Loading the presets into a new scene will give you the exact same scene as the original scene.

First create a new editor folder in Project, and create a new script MyEditor.cs

Using Unityengine;
Using System.Collections;
Using Unityeditor;
Using System.Collections.Generic;
Using System.Xml;
Using System.IO;
Using System.Text;
Using Litjson;

public class Myeditor:editor
{

This is to modify the compiler, in the menu bar Gameobject will be more exportxml options
[MenuItem ("Gameobject/exportxml")]
static void ExportXML ()
{
String FilePath = Application.datapath + "/streamingassets/my.xml";
String Prefabpath = Application.datapath + "/resources/prefabs";

if (! File.exists (FilePath))
{
File.delete (FilePath);
}

if (! Directory.Exists (Prefabpath))
{
Directory.CreateDirectory (Prefabpath);
}

XmlDocument xmldoc = new XmlDocument ();
XmlDeclaration Xmldec = xmldoc.createxmldeclaration ("1.0", "Utf-8", null);
Xmldoc.appendchild (XMLDEC);
XmlElement root = Xmldoc.createelement ("gameobjects");

Traverse all the game scenes
foreach (Unityeditor.editorbuildsettingsscene s in UnityEditor.EditorBuildSettings.scenes)
{
Open scene
Editorapplication.openscene (S.path);
XmlElement scenes = Xmldoc.createelement ("scenes");
Scenes. SetAttribute ("name", S.path);

foreach (Gameobject obj in Object.findobjectsoftype (typeof (Gameobject)))
{
is disabled
if (obj.transform.parent = = null && obj.activeself)
{
The object is made into a preset and stored in the prefabs of the resources directory.
Exportprefab (obj, prefabpath);

XmlElement gameobject = xmldoc.createelement ("gameobjects");
Gameobject.setattribute ("name", Obj.name);
Gameobject.setattribute ("asset", Obj.name + ". Prefab");

XmlElement transform = xmldoc.createelement ("transform");

XmlElement position = xmldoc.createelement ("position");
XmlElement position_x = xmldoc.createelement ("x");
XmlElement position_y = xmldoc.createelement ("y");
XmlElement position_z = xmldoc.createelement ("z");
Position_x.innertext = obj.transform.position.x + "";
Position_y.innertext = Obj.transform.position.y + "";
Position_z.innertext = Obj.transform.position.z + "";
Position. AppendChild (position_x);
Position. AppendChild (position_y);
Position. AppendChild (position_z);

XmlElement rotation = xmldoc.createelement ("rotation");
XmlElement rotation_x = xmldoc.createelement ("x");
XmlElement rotation_y = xmldoc.createelement ("y");
XmlElement rotation_z = xmldoc.createelement ("z");
Rotation_x.innertext = obj.transform.rotation.eulerangles.x + "";
Rotation_y.innertext = Obj.transform.rotation.eulerangles.y + "";
Rotation_z.innertext = obj.transform.rotation.eulerangles.z + "";
Rotation. AppendChild (rotation_x);
Rotation. AppendChild (rotation_y);
Rotation. AppendChild (rotation_z);

XmlElement scale = xmldoc.createelement ("scale");
XmlElement scale_x = xmldoc.createelement ("x");
XmlElement scale_y = xmldoc.createelement ("y");
XmlElement scale_z = xmldoc.createelement ("z");
Scale_x.innertext = obj.transform.localscale.x + "";
Scale_y.innertext = Obj.transform.localscale.y + "";
Scale_z.innertext = Obj.transform.localscale.z + "";
Scale. AppendChild (scale_x);
Scale. AppendChild (scale_y);
Scale. AppendChild (scale_z);

Transform. AppendChild (position);
Transform. AppendChild (rotation);
Transform. AppendChild (scale);

Gameobject.appendchild (transform);
Scenes. AppendChild (Gameobject);
Root. AppendChild (scenes);
Xmldoc.appendchild (root);
Xmldoc.save (FilePath);
}
}
}

Assetdatabase.refresh ();
Debug.Log ("XML export completed");
Debug.Log (Time.realtimesincestartup);
}

[MenuItem ("Gameobject/exportjson")]
static void Exportjson ()
{
String FilePath = Application.datapath + "/streamingassets/json.txt";
String Prefabpath = Application.datapath + "/resources/prefabs";

if (! File.exists (FilePath))
{
File.delete (FilePath);
}

if (! Directory.Exists (Prefabpath))
{
Directory.CreateDirectory (Prefabpath);
}

FileInfo t = new FileInfo (FilePath);
StreamWriter SW = T.createtext ();

StringBuilder sb = new StringBuilder ();
Jsonwriter writer = new Jsonwriter (SB);
Writer. Writeobjectstart ();
Writer. Writepropertyname ("gameobjects");
Writer. Writearraystart ();

Traverse all the game scenes
foreach (Unityeditor.editorbuildsettingsscene s in UnityEditor.EditorBuildSettings.scenes)
{
Open scene
Editorapplication.openscene (S.path);

Writer. Writeobjectstart ();
Writer. Writepropertyname ("scenes");
Writer. Writearraystart ();
Writer. Writeobjectstart ();
Writer. Writepropertyname ("name");
Writer. Write (S.path);
Writer. Writepropertyname ("Gameobject");
Writer. Writearraystart ();

foreach (Gameobject obj in Object.findobjectsoftype (typeof (Gameobject)))
{
if (obj.transform.parent = = null && obj.activeself)
{
The object is made into a preset and stored in the prefabs of the resources directory.
Exportprefab (obj, prefabpath);

Writer. Writeobjectstart ();
Writer. Writepropertyname ("name");
Writer. Write (Obj.name);

Writer. Writepropertyname ("position");
Writer. Writearraystart ();
Writer. Writeobjectstart ();
Writer. Writepropertyname ("X");
Writer. Write (obj.transform.position.x.tostring ("F5"));//f5 is a format conversion
Writer. Writepropertyname ("Y");
Writer. Write (obj.transform.position.y.tostring ("F5"));
Writer. Writepropertyname ("Z");
Writer. Write (obj.transform.position.z.tostring ("F5"));
Writer. Writeobjectend ();
Writer. Writearrayend ();

Writer. Writepropertyname ("rotation");
Writer. Writearraystart ();
Writer. Writeobjectstart ();
Writer. Writepropertyname ("X");
Writer. Write (obj.transform.rotation.eulerangles.x.tostring ("F5"));
Writer. Writepropertyname ("Y");
Writer. Write (obj.transform.rotation.eulerangles.y.tostring ("F5"));
Writer. Writepropertyname ("Z");
Writer. Write (obj.transform.rotation.eulerangles.z.tostring ("F5"));
Writer. Writeobjectend ();
Writer. Writearrayend ();

Writer. Writepropertyname ("scale");
Writer. Writearraystart ();
Writer. Writeobjectstart ();
Writer. Writepropertyname ("X");
Writer. Write (obj.transform.localscale.x.tostring ("F5"));
Writer. Writepropertyname ("Y");
Writer. Write (obj.transform.localscale.y.tostring ("F5"));
Writer. Writepropertyname ("Z");
Writer. Write (obj.transform.localscale.z.tostring ("F5"));
Writer. Writeobjectend ();
Writer. Writearrayend ();

Writer. Writeobjectend ();
}
}

Writer. Writearrayend ();
Writer. Writeobjectend ();
Writer. Writearrayend ();
Writer. Writeobjectend ();
}

Writer. Writearrayend ();
Writer. Writeobjectend ();

Sw. WriteLine (sb.) ToString ());
Sw. Close ();
Sw. Dispose ();
Assetdatabase.refresh ();
Debug.Log ("Json export completed");
Debug.Log (Time.realtimesincestartup);
}

private static void Exportprefab (Gameobject gameobject, String prefabpath)
{
if (directory.exists (Prefabpath))
{
Prefabutility.createprefab ("assets/resources/prefabs/" + Gameobject.name + ". Prefab", Gameobject, REPLACEPREFABOPTIONS.CONNECTTOPREFAB);
}
}
}

Compile the project and click on the ExportXML and Exportjson options under Gameobject, and you'll find Json.txt and My.xml in Streamingassets, as well as folders Resources/prefabs, The default in the folder is the default of the parent object in the Hirearchy.

Let's talk about parsing the file and restoring the scene.

This is the parsing of XML

Using Unityengine;
Using System.Collections;
Using System.Xml;
Using System.IO;

public class Xml:monobehaviour
{
void Start ()
{
String FilePath = Application.datapath + "/streamingassets/my.xml";

if (file.exists (FilePath))
{
XmlDocument xmldoc = new XmlDocument ();
Xmldoc.load (FilePath);
XmlNodeList nodeList = Xmldoc.selectsinglenode ("Gameobjects"). ChildNodes;

foreach (XmlElement scene in NodeList)
{
Debug.Log (scene. GetAttribute ("name"));
if (!scene. GetAttribute ("name"). Equals ("assets/scenes/demo.unity"))
Continue

foreach (XmlElement gameobjects in scene. ChildNodes)
{
String asset = "prefabs/" + gameobjects.getattribute ("name");

Vector3 position = Vector3.zero;
Vector3 rotation = Vector3.zero;
Vector3 scale = Vector3.zero;

foreach (XmlElement transform in Gameobjects.childnodes)
{
foreach (XmlElement info in transform. ChildNodes)
{
if (info. Name.equals ("position"))
{
foreach (XmlElement pos in info. ChildNodes)
{
Switch (pos. Name)
{
Case "X":
position.x = float. Parse (pos. InnerText);
Break
Case "Y":
POSITION.Y = float. Parse (pos. InnerText);
Break
Case "Z":
Position.z = float. Parse (pos. InnerText);
Break
}
}
}
else if (info. Name.equals ("rotation"))
{
foreach (XmlElement rot in info. ChildNodes)
{
Switch (rot. Name)
{
Case "X":
rotation.x = float. Parse (rot. InnerText);
Break
Case "Y":
ROTATION.Y = float. Parse (rot. InnerText);
Break
Case "Z":
Rotation.z = float. Parse (rot. InnerText);
Break
}
}
}
else if (info. Name.equals ("scale"))
{
foreach (XmlElement SCA in info. ChildNodes)
{
Switch (SCA. Name)
{
Case "X":
scale.x = float. Parse (SCA. InnerText);
Break
Case "Y":
Scale.y = float. Parse (SCA. InnerText);
Break
Case "Z":
Scale.z = float. Parse (SCA. InnerText);
Break
}
}
}
}

1. To instantiate an object by reading the corresponding preset from the resource
Gameobject obj = (gameobject) instantiate (Resources.load (asset), Position, Quaternion.euler (rotation));

Obj.transform.localScale = scale;
}
}
}

Debug.Log ("Xml Restore to Scene");
Debug.Log (Time.realtimesincestartup);
}
Else
{
Debug.Log ("File not Exist");
}
}
}

This is the parsing of JSON

Using Unityengine;
Using System.Collections;
Using System.IO;
Using Litjson;

public class Json:monobehaviour
{
void Start ()
{
String FilePath = Application.datapath + "/streamingassets/json.txt";
StreamReader sr = File.OpenText (FilePath);
String strLine = Sr. ReadToEnd ();
Jsondata JD = Jsonmapper.toobject (StrLine);
Jsondata Gameobjectarray = jd["Gameobjects"];

int I, j, K;
foreach (Jsondata gameobject in Gameobjectarray)
for (i = 0; i < Gameobjectarray.count; i++)
{
Jsondata Scenearray = gameobjectarray[i]["scenes"];

foreach (Jsondata scene in Scenearray)
for (j = 0; J < Scenearray.count; J + +)
{
String scenename = scenearray[j]["Name"]. ToString ();

if (!scenename.equals ("assets/scenes/demo.unity"))
Continue

Jsondata gameobjects = scenearray[j]["Gameobject"];

foreach (Jsondata obj in gameobjects)
for (k = 0; k < gameobjects.count; k++)
{
String objname = gameobjects[k]["Name"]. ToString ();
String asset = "prefabs/" + objname;
Vector3 position = Vector3.zero;
Vector3 rotation = Vector3.zero;
Vector3 scale = Vector3.zero;

Jsondata pos = gameobjects[k]["position"];
Jsondata rot = gameobjects[k]["Rotation"];
Jsondata SCA = gameobjects[k]["scale"];

position.x = float. Parse ((String) pos[0]["X"]);
POSITION.Y = float. Parse ((String) pos[0]["Y"]);
Position.z = float. Parse ((string) pos[0]["Z"]);

rotation.x = float. Parse ((String) rot[0]["X"]);
ROTATION.Y = float. Parse ((String) rot[0]["Y"]);
Rotation.z = float. Parse ((string) rot[0]["Z"]);

scale.x = float. Parse ((String) sca[0]["X"]);
Scale.y = float. Parse ((String) sca[0]["Y"]);
Scale.z = float. Parse ((string) sca[0]["Z"]);

Gameobject ob = (gameobject) instantiate (Resources.load (asset), Position, Quaternion.euler (rotation));
Ob.transform.localScale = scale;
}
}
}

Debug.Log ("Json Restore to Scene");
Debug.Log (Time.realtimesincestartup);
}
}

Is it quite simple, just create a new scene, build an empty object to hang the above script on the object, run to get the same scene as the original ~ ~

PS: FOR XML and JSON parsing and restore efficiency of the scene, I did the test, the following is the test results:

When the scene is a small scene, that is, the number of objects is less (4 for example), Draw call:110

Parse the scene time

Restore Time

File size

Xml

0.1372822

0.1477898

2k

Json

0.1357037

0.1179444

1k

When the scene is a large scene, that is, the number of objects is more (100 for example), Draw call:2848

Parse the scene time

Restore Time

File size

Xml

0.2660492

0.1703795

48k

Json

0.1601105

0.1329994

22k

When draw call is larger, the number of objects 130,draw call:26068 (CPU 45%, the computer has been compared card)

Parse the scene time

Restore Time

File size

Xml

0.3745174

0.176897

52k

Json

0.124469

0.136014

24k

Personally, JSON is a better one.

The scene in Unity resolves to JSON and XML and restores the scene

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.