在 Unity 中保存场景数据的原理主要涉及数据的收集、序列化以及存储这几个关键步骤,下面为你详细介绍:
数据收集
场景数据包含了场景中各种游戏对象的属性和状态信息,在保存场景时,需要收集这些数据。具体来说,要收集的数据可能包括但不限于以下几类:
游戏对象的基本信息
位置、旋转和缩放:游戏对象在三维空间中的位置(Transform.position)、旋转角度(Transform.rotation)以及缩放比例(Transform.localScale)。这些信息决定了游戏对象在场景中的空间状态。
名称和标签:游戏对象的名称(GameObject.name)用于标识对象,标签(GameObject.tag)可用于对对象进行分类和筛选。
组件数据
每个游戏对象可能挂载了多个组件,不同组件具有不同的属性,这些属性也需要保存。例如:
渲染组件:如 MeshRenderer 的材质信息、SpriteRenderer 的精灵纹理等。
物理组件:像 Rigidbody 的质量、重力开关,Collider 的形状和大小等。
自定义脚本组件:如果游戏对象挂载了自定义的脚本,脚本中定义的公共变量或需要保存的状态信息也应被收集。
序列化
序列化是将收集到的数据转换为可以存储或传输的格式的过程
保存场景数据的代码
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
// <summary>
/// 保存所有的游戏场景,每个场景的数据都会保存到XML,网上都有,只是方便自己用.
/// </summary>
public class ExportSceneInfoToXML : Editor {
[MenuItem("GameObject/ExportXML")]
static void ExportXML()
{
string filepath = Application.dataPath + @"/StreamingAssets/my.xml";
if (!File.Exists(filepath))
{
File.Delete(filepath);
}
XmlDocument xmlDoc = new XmlDocument();
XmlElement root = xmlDoc.CreateElement("gameObjects");
//遍历所有的游戏场景
foreach (UnityEditor.EditorBuildSettingsScene S in UnityEditor.EditorBuildSettings.scenes)
{
//当场景启用
if (S.enabled)
{
//得到场景的名称
string name = S.path;
//打开这个场景
EditorApplication.OpenScene(name);
XmlElement scenes = xmlDoc.CreateElement("scenes");
scenes.SetAttribute("name", name);
foreach (GameObject obj in Object.FindObjectsOfType(typeof(GameObject)))
{
if (obj.transform.parent == null)
{
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");
position_x.InnerText = obj.transform.position.x + "";
XmlElement position_y = xmlDoc.CreateElement("y");
position_y.InnerText = obj.transform.position.y + "";
XmlElement position_z = xmlDoc.CreateElement("z");
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");
rotation_x.InnerText = obj.transform.rotation.eulerAngles.x + "";
XmlElement rotation_y = xmlDoc.CreateElement("y");
rotation_y.InnerText = obj.transform.rotation.eulerAngles.y + "";
XmlElement rotation_z = xmlDoc.CreateElement("z");
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");
scale_x.InnerText = obj.transform.localScale.x + "";
XmlElement scale_y = xmlDoc.CreateElement("y");
scale_y.InnerText = obj.transform.localScale.y + "";
XmlElement scale_z = xmlDoc.CreateElement("z");
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);
}
}
}
}
//刷新Project视图, 不然需要手动刷新哦
AssetDatabase.Refresh();
}
}
如需其他扩展请自行添加即可