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