Exemple #1
0
    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();
        }
    }
Exemple #2
0
    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();
    }