/// <summary> /// Cycles through all GameObjects in the Scene which has the SaveLoadBehavior and /// serializes them if they are set to be savable. /// The serialized file is then sent to the AssetServer using the specified save name. /// </summary> /// <param name="saveName">Name under which the save file should be put under</param> /// <param name="callBack">Optional Callback which gets called after sending the data (only way to check for errors)</param> public void SaveCurrentScene(string saveName, AssetManager.DataSentToServerFunc callBack = null) { if (_isSaving) { // TODO: 'Real' error handling, so the caller knows that there's another save-process running Debug.Log("Can't Save while another Save-Process is ongoing"); return; } _isSaving = true; SaveLoadBehavior[] all = GameObject.FindObjectsOfType <SaveLoadBehavior>(); if (all.Length == 0) { Debug.Log("There are no GameObjects designated to be saved in the scene!"); return; } SaveData data = null; SaveDataList dataList = new SaveDataList() { DataList = new List <SaveData>() }; GameObject obj = null; foreach (SaveLoadBehavior component in all) { if (!component.IsSavable) { continue; } obj = component.gameObject; data = new SaveData() { InstanceID = obj.GetInstanceID(), Name = obj.name, AssetBundle = component.AssetBundleName }; data.Serialize(obj); dataList.DataList.Add(data); } if (dataList.DataList.Count == 0) { Debug.Log("There are no GameObjects designated to be saved in the scene!"); } else { string strToSave = JsonUtility.ToJson(dataList, false); /* * // COMPRESSION MUCH? * using (var output = new System.IO.MemoryStream()) * { * using (DeflateStream gzip = new DeflateStream(output, CompressionMode.Compress)) * { * using (var writer = new System.IO.StreamWriter(gzip, System.Text.Encoding.ASCII)) * { * writer.Write(strToSave); * } * } * byte[] yay = output.ToArray(); * string bay = System.Text.Encoding.ASCII.GetString(yay); * AssetManagement.Instance.AssetManager.SendDataToServer(output.ToString(), string.Format("Scene/{0}", saveName), callBack); * } */ AssetManagement.Instance.AssetManager.SendDataToServer(strToSave, string.Format("Scene/{0}", saveName), callBack); } _isSaving = false; }
IEnumerator FetchScene(UnityWebRequest request, string saveName, bool cacheScene) { SaveDataList lst = null; _entitiesToLoad = 0; if (cacheScene && _sceneCache.ContainsKey(saveName)) { lst = _sceneCache[saveName]; } else { yield return(request.SendWebRequest()); if (request.isHttpError || request.isNetworkError) { _lastError = request.error; Debug.Log(string.Format("Couldn't fetch the Scene [{0}] due to: {1}", saveName, request.error)); yield break; } else { lst = JsonUtility.FromJson <SaveDataList>(request.downloadHandler.text); } } _entitiesToLoad = lst.DataList.Count; GameObject[] allObjects = GameObject.FindObjectsOfType <GameObject>(); if (_entitiesToLoad > 0) { foreach (var entitiyData in lst.DataList) { if (entitiyData.AssetBundle == "") { // Object was placed in the Editor. Search for the GameObject in current scene foreach (var go in allObjects) { if (go.GetInstanceID() == entitiyData.InstanceID) { // Hurray! We found the GameObject matching our saved data! entitiyData.Deserialize(go); _entitiesToLoad--; // TODO: Find out if it is of interest to signal the AssetLoaded-Event here break; } } } else { // Asset is not in the current scene (not placed in the editor), so we have to manually load it // from the server - therefore, put it into a list for further use if (!_entityCache.ContainsKey(entitiyData.AssetBundle)) { _entityCache[entitiyData.AssetBundle] = new List <SaveData>(); } _entityCache[entitiyData.AssetBundle].Add(entitiyData); } } if (_entitiesToLoad > 0) { foreach (var dispatchJob in _entityCache) { AssetManagement.Instance.AssetManager.RequestAsset(dispatchJob.Key, EntityFinishedLoading); } } } }