Вот нактдал небольшой пример.
Вспомогательные экстеншены
Используется csharp
using UnityEngine;
namespace SDS.Extensions
{
public static class Extensions
{
public static T[] GetJaggedArrayItems<T>(this T[][] arr)
{
var items = new System.Collections.Generic.List<T>();
for (int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < arr[i].Length; j++)
{
items.Add(arr[i][j]);
}
}
return items.ToArray();
}
public static GameObject[][] GetAllSceneObjects(this UnityEngine.SceneManagement.Scene scene)
{
GameObject[] rootObjects = scene.GetRootGameObjects();
GameObject[][] tree = new GameObject[rootObjects.Length][];
for (int i = 0; i < rootObjects.Length; i++)
{
Transform[] children = rootObjects[i].GetComponentsInChildren<Transform>(true);
GameObject[] branch = new GameObject[children.Length];
for (int j = 0; j < children.Length; j++)
branch[j] = children[j].gameObject;
tree[i] = branch;
}
return tree;
}
}
}
Эта хрень собирает инфу об объектах при старте сцены, и в нужный ммент находит объекты, создынные после запуска и сериализует их (толком не работает с иерархией чилдов).
Используется csharp
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using SDS.Extensions;
namespace SDS
{
[System.Serializable]
class SceneDiffWrapper
{
public NewObjectsData[] Objects;
}
[System.Serializable]
class NewObjectsData
{
public string Name;
public string Parent; // Check
public Vector3 Position;
public Quaternion Rotation;
private NewObjectsData() { }
public static NewObjectsData Create(GameObject obj)
{
return new NewObjectsData()
{
Name = obj.name,
Parent = obj.transform.parent ? obj.transform.parent.name : null,
Position = obj.transform.position,
Rotation = obj.transform.rotation
};
}
}
public class SceneDiffSerializer
{
private const string PPKEY = "last_scene_diff";
private List<int> _dump;
public static SceneDiffSerializer GetSerializer
{
get
{
return new SceneDiffSerializer()
{
_dump = Dump(
SceneManager.GetActiveScene()
.GetAllSceneObjects()
.GetJaggedArrayItems()
)
.ToList()
};
}
}
public void Save()
{
GameObject[] objects = SceneManager.GetActiveScene().GetAllSceneObjects().GetJaggedArrayItems();
var diff = new List<NewObjectsData>();
for (int i = 0; i < objects.Length; i++)
{
if (!_dump.Contains(objects[i].GetInstanceID()))
{
Debug.Log(objects[i]);
diff.Add(NewObjectsData.Create(objects[i]));
}
}
var wrapper = new SceneDiffWrapper()
{
Objects = diff.ToArray()
};
PlayerPrefs.SetString(PPKEY, JsonUtility.ToJson(wrapper));
}
public void Recreate()
{
SceneDiffWrapper wrapper = JsonUtility.FromJson<SceneDiffWrapper>(PlayerPrefs.GetString(PPKEY));
foreach (var obj in wrapper.Objects)
{
var newObj = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
// try set parent
if (obj.Parent != null)
{
GameObject parent = GameObject.Find(obj.Parent);
if (parent) newObj.transform.SetParent(parent.transform);
}
newObj.name = obj.Name;
newObj.position = obj.Position;
newObj.rotation = obj.Rotation;
Material mat = new Material(Shader.Find("Standard"));
mat.color = new Color(0.5f, 0, 0, 1);
newObj.GetComponent<MeshRenderer>().material = mat;
}
}
public void Flush()
{
PlayerPrefs.DeleteKey(PPKEY);
}
private static int[] Dump(GameObject[] objects)
{
int[] ids = new int[objects.Length];
for (int i = 0; i < objects.Length; i++)
ids[i] = objects[i].GetInstanceID();
return ids;
}
}
}
Отсюда упраляем
Используется csharp
using UnityEngine;
using SDS;
public class SDSTest : MonoBehaviour
{
private SceneDiffSerializer _serializer;
void Start()
{
_serializer = SceneDiffSerializer.GetSerializer;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
_serializer.Save();
}
if (Input.GetKeyDown(KeyCode.F))
{
_serializer.Flush();
}
if (Input.GetKeyDown(KeyCode.L))
{
_serializer.Recreate();
}
}
}
Код сырой кнч, так как пример, но можешь отсюда копать, впринципе инфа исчерпывающая по теме.