void Load(Stream stream, DataFormat format = DataFormat.Binary) { var context = new DeserializationContext(); if (RequireSaveGameAttributeEverywhere) { context.Config.SerializationPolicy = _serializationPolicy; } var resolver = new ReferenceResolver(); context.IndexReferenceResolver = resolver; context.StringReferenceResolver = resolver; IDataReader reader = SerializationUtility.CreateReader(stream, context, format); // destroy old prefab instances foreach (SaveGameObject obj in GameObject.FindObjectsOfType <SaveGameObject>()) { GameObject.DestroyImmediate(obj.gameObject); } // set up resolver root objects GameObject[] rootObjects = gameObject.scene.GetRootGameObjects(); resolver.RootObjects = new Dictionary <string, Transform>(rootObjects.Length); foreach (GameObject go in rootObjects) { resolver.RootObjects[go.name] = go.transform; } Type type; if (reader.EnterNode(out type) && reader.CurrentNodeName == "prefabs") { // instantiate saved prefab instances var serializer = Serializer.Get <Transform>(); var prefabsByName = PrefabsByName(); while (reader.EnterNode(out type)) { string prefabName; if (reader.ReadString(out prefabName)) { Transform transform = serializer.ReadValue(reader); Transform instance = null; SaveGameObject prefabObj; if (prefabsByName.TryGetValue(prefabName, out prefabObj)) { instance = GameObject.Instantiate(prefabObj, transform).transform; } else { Debug.LogWarningFormat("Missing prefab {0} in SaveablePrefabs list", prefabName); } resolver.Register(instance); reader.ExitNode(); } } reader.ExitNode(); } if (reader.EnterNode(out type) && reader.CurrentNodeName == "saveables") { var serializer = Serializer.Get <MonoBehaviour>(); while (reader.EnterNode(out type)) { var saveable = serializer.ReadValueWeak(reader) as ISaveable; resolver.Register(saveable); if (saveable != null) { IFormatter formatter = FormatterLocator.GetFormatter(saveable.GetType(), _serializationPolicy); formatter.Deserialize(saveable, reader); saveable.Loaded = true; saveable.OnAfterLoad(); } reader.ExitNode(); } reader.ExitNode(); } }
void Save(Stream stream, DataFormat format) { var context = new SerializationContext(); if (RequireSaveGameAttributeEverywhere) { context.Config.SerializationPolicy = _serializationPolicy; } var resolver = new ReferenceResolver(); context.IndexReferenceResolver = resolver; context.StringReferenceResolver = resolver; var writer = SerializationUtility.CreateWriter(stream, context, format); var prefabs = new List <SaveGameObject>(); var saveables = new List <ISaveable>(); foreach (GameObject go in gameObject.scene.GetRootGameObjects()) { FindSaveableObjects(go.transform, prefabs, saveables); } #if UNITY_EDITOR if (UnitySerializationUtility.ForceEditorModeSerialization) { // ensure all types are visited for AOT scan foreach (var prefab in SaveablePrefabs) { FindSaveableObjects(prefab.transform, prefabs, saveables); } } #endif // for each prefab instance store the prefab name and a reference to its parent transform var transformSerializer = Serializer.Get <Transform>(); var prefabsByName = PrefabsByName(); writer.BeginStructNode("prefabs", null); foreach (SaveGameObject obj in prefabs) { if (prefabsByName.ContainsKey(obj.PrefabName)) { writer.BeginStructNode(null, null); writer.WriteString("prefab", obj.PrefabName); transformSerializer.WriteValue("parent", obj.transform.parent, writer); resolver.Register(obj.transform); writer.EndNode(null); } else { Debug.LogErrorFormat("Failed serialising {0} due to missing prefab {1} in SaveablePrefabs list", obj, obj.PrefabName); } } writer.EndNode("prefabs"); var saveableSerializer = Serializer.Get <MonoBehaviour>(); writer.BeginStructNode("saveables", null); foreach (ISaveable saveable in saveables) { MonoBehaviour unityObject = saveable as MonoBehaviour; writer.BeginStructNode(unityObject.name, unityObject.GetType()); saveableSerializer.WriteValueWeak("$object", unityObject, writer); resolver.Register(unityObject); saveable.OnBeforeSave(); IFormatter formatter = FormatterLocator.GetFormatter(unityObject.GetType(), _serializationPolicy); formatter.Serialize(saveable, writer); writer.EndNode(unityObject.name); } writer.EndNode("saveables"); writer.FlushToStream(); }