-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoadingManager.cs
284 lines (199 loc) · 9.32 KB
/
LoadingManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.SceneManagement;
public class LoadingManager : MonoBehaviour
{
/*
* LoadingManager handles all saving and loading in the game
* This includes permanent Player requested saves, as well as temporary scene-to-scene data persistence
* It makes the files on the player's computer and manages them as necessary
* It's also the main controller of switching between scenes, and syncs up data from other managers as necessary
* Which data gets saved from which types of objects and other more specific details handled in SaveableClasses.cs
*/
public static LoadingManager mainController;
// used by ImportantMans , we have to make sure we don't have two LoadingMans when we go from scene to scene
public bool saveMe; // performs a scene save only (not that useful)
public bool loadMe;
public bool forRealSave; // performs a real save as if player had requested
public bool deleteSaveData;
// These four bools are for in-editor testing w/o building full debug menu
private string permanentPath = "PermaSaveData";
private string tempPath = "TempSaveData";
// path names where data will be saved on machine
// permanent save data is data that has been commited to a SAVE from the Player
// temp save data is data that might have changed from room to room but hasn't actually been saved by the player
private static bool USDOLRan;
// indicates whether UpdateSaveDataOnLoad() has run
// making this STATIC was crucial -- otherwise it reset each scene
void Awake(){
if (deleteSaveData){
// if we trigger this bool while testing it will do the requested operation for us
// sometimes its useful to delete save data before the game starts loading anything in
Debug.Log("save data deleted");
deleteSaveData = false;
DeleteSaveData();
}
UpdateSaveDataOnLoad();
LoadSceneData();
}
void Update(){
// if we trigger one of these bools while testing it will do the requested operation for us
if(deleteSaveData){
Debug.Log("save data deleted ");
deleteSaveData = false;
DeleteSaveData();
TextSpeedMenu.SetTextSpeedAuto(true);
}
if (saveMe){
SaveSceneData();
saveMe = false;
}
if(loadMe){
loadMe = false;
LoadSceneData();
}
if(forRealSave){
forRealSave = false;
PlayerRequestsSave();
}
}
public void DeleteSaveData(){
// Called by player in start menu
File.Delete(Application.persistentDataPath + "/" + permanentPath + ".dat");
File.Delete(Application.persistentDataPath + "/" + tempPath + ".dat");
MakeSaveData();
MorningManager.setDay(0);
// Because day count is static value merely recorded by save data, deleting doesn't work -- we need to manually set it here
}
void UpdateSaveDataOnLoad(){
// runs once when LoadingManager comes into existence
// creates savedata if doesn't exist and syncs up perm data and temp data for this scene
if (!USDOLRan){
USDOLRan = true;
MakeSaveData();
AllSaveData data = load<AllSaveData> (permanentPath);
save<AllSaveData> (tempPath, data);
}
}
public void PlayerRequestsSave(){
// called mostly from player going to bed
SaveSceneData();
AllSaveData data = load<AllSaveData> (tempPath);
save<AllSaveData> (permanentPath, data);
}
public static void createFile (string path){
// creates file of the given name in the persistentDataPath folder
FileStream file;
file = File.Create(Application.persistentDataPath + "/" + path +".dat");
file.Close();
}
public static void save<T>(string path, T obj){
// these abstract save and load functions can be used to save any serializable class
// save does not create the file, just save it
FileStream file;
file = File.Open(Application.persistentDataPath + "/" + path +".dat", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(file, obj);
// we use the binaryformatter to at least slightly obfuscate the save data from anyone poking around in the files
// Lots of the chains of dependency on saved objects are kind of fragile so even a small smokescreen helps
file.Close();
}
public static T load<T> (string path){
// these abstract save and load functions can be used to save any serializable class
FileStream file;
BinaryFormatter bf = new BinaryFormatter();
var data = default (T);
if ( File.Exists (Application.persistentDataPath + "/" + path +".dat" )){
file = File.Open(Application.persistentDataPath + "/" + path + ".dat", FileMode.Open);
data = (T) bf.Deserialize(file);
file.Close();
}
return data;
}
public static T[] addItemToArray<T> (T[] myArray, T toAdd){
// helper function used throughout project.
// Stored here for historical reasons (used a lot in the various Saveable Classes files like AllSaveData)
// Could have used dictionaries more often, probably. Oops!
// ZooSim is a pretty lightweight game, so we aren't so focused on optimizing performance
T[] newArray = new T[myArray.Length + 1];
for (int i =0 ; i < myArray.Length; i++){
newArray[i] = myArray[i];
}
newArray[myArray.Length] = toAdd;
return newArray;
}
public void SaveSceneData(){
// happens just before we load the next scene in LoadScene()
// NOT a permanent player save, but to keep data persisting between different rooms
SaveMe[] allData = FindObjectsOfType<SaveMe>();
AllSaveData tempSaveSheet = load<AllSaveData>(tempPath);
for (int i = 0; i < allData.Length; i ++){
// run over all SaveMe objects
allData[i].forceUpdateArrays();
tempSaveSheet = tempSaveSheet.SaveAll(allData[i], tempSaveSheet);
}
save<AllSaveData>(tempPath, tempSaveSheet);
}
public void LoadSceneData(){
// WE should ALWAYS load the temp data each new room. We want to fix the temp data to become
// the default data only at Game Start time
// NOTICE: IF A SCENE HAS NO SAVE MES, loading and saving will simply no happen.
SaveMe[] allData = FindObjectsOfType<SaveMe>();
AllSaveData tempSaveSheet = load<AllSaveData>(tempPath);
for (int i = 0; i < allData.Length; i ++){ // iterate over ALL SaveMes
allData[i].forceUpdateArrays();
// AFTER WRITING new load for new saveMe type, don't forget to Instantiate a new ActionData in MakeSaveData.
tempSaveSheet.LoadAll(allData[i], tempSaveSheet);
}
if (allData.Length == 0){
Debug.Log("WARNING!!! NO SAVE MES IN THIS SCENE!! LOADING BROKEN!!");
}
}
public void MakeSaveData(){
// these two create the save datas as needed
if (!File.Exists(Application.persistentDataPath + "/" + tempPath +".dat") ){
createFile(tempPath);
AllSaveData dataDirectory = new AllSaveData();
dataDirectory.SetInitialRefernces();
save<AllSaveData> (tempPath, dataDirectory);
}
if (!File.Exists(Application.persistentDataPath + "/" + permanentPath + ".dat") ){
createFile(permanentPath);
AllSaveData dataDirectory = new AllSaveData();
save<AllSaveData> (permanentPath, dataDirectory);
}
}
public void LoadScene(string scene){
// called when player moves between rooms, such as by LoadingZone
TransitionFader fader = FindObjectOfType(typeof(TransitionFader)) as TransitionFader;
// the object that fades our screen to black when we switch rooms
SaveSceneData();
StartCoroutine(WaitForFade(fader, scene) );
}
IEnumerator WaitForFade(TransitionFader fader, string sceneName) {
// WaitForFade delays until both music and the TransitionFader have completed
// called by LoadScene()
// technically you should probably add wait for sfxFade as well?
// But currently I don't think this comes up anywhere
SFXMan sfxman = FindObjectOfType(typeof(SFXMan)) as SFXMan;
fader.fadeMeOut();
bool wait = fader.fadingActive || MusicMan.GetFadingMusicNow();
while (wait ){
yield return new WaitForSeconds(.05f);
wait = fader.fadingActive || MusicMan.GetFadingMusicNow() ;
}
SceneManager.LoadScene(sceneName); // ask unity to load the next room
}
public void IncrementDaysSinceData(){
// called by DaysManager in a specific moment of the day/night loop.
// Increments the game's day count
AllSaveData tempSaveSheet = load<AllSaveData>(tempPath);
SaveMe[] allData = FindObjectsOfType<SaveMe>();
tempSaveSheet.IncrementAllDaySinceData(tempSaveSheet, allData);
save<AllSaveData>(tempPath, tempSaveSheet);
}
}