/// <summary> /// Event calback. Collects all the things in saveable components into a GameObjectDataBlock. /// This is the second-most level from the top. /// The GameObjectDataBlock will then go into a list which will finally represent the savegame of a scene. /// </summary> public void OnSave(GameSavingEvent hook) { GameObjectDataBlock goBlock = new GameObjectDataBlock(uuid, gameObject.name, assetBundle, assetPath); var components = GetComponentsInChildren<Component>(); for (int i = 0; i < components.Length; ++i) { // Ignore components that are not to be saved. if (!components[i].GetType().IsDefined(typeof(SaveableComponentAttribute), true)) { continue; } var componentBlock = new ComponentDataBlock(components[i].GetType().ToString(), components[i].GetType().Assembly.GetName().Name); // Find all fields and properties that need saving. var type = components[i].GetType(); var memberSet = type.FieldsAndPropertiesWith(typeof(SaveableFieldAttribute)); for (int j = 0; j < memberSet.Count; ++j) { SaveableFieldAttribute a = memberSet[j].Attribute<SaveableFieldAttribute>(); switch (a.fieldType) { case SaveField.FIELD_PRIMITIVE: case SaveField.FIELD_SIMPLE_OBJECT: componentBlock.AddSimpleObject(memberSet[j].Name, components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_PROTOBUF_OBJECT: componentBlock.AddProtoObject(memberSet[j].Name, components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_COLOR: componentBlock.AddColor(memberSet[j].Name, (Color)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_VECTOR_2: componentBlock.AddVector2(memberSet[j].Name, (Vector2)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_VECTOR_3: componentBlock.AddVector3(memberSet[j].Name, (Vector3)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_QUATERNION: componentBlock.AddQuaternion(memberSet[j].Name, (Quaternion)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; default: // In case we have new data types and forgot to add it here for processing Debug.LogError(memberSet[j].Name + " is of unhandled data type " + a.fieldType); break; } } goBlock.AddComponentData(componentBlock); } hook.SceneData.AddGameObjectData(goBlock); }
public void CreateSave() { var hook = new GameSavingEvent(SceneManager.GetActiveScene().name); hook.Call(); string fileName = Application.persistentDataPath + "/" + SaveName + ".save"; SaveFile sf = null; // save file already exists. if (File.Exists(fileName)) { sf = DataSerializer.DeserializeProtoObject<SaveFile>(ZipTools.DecompressBytes(File.ReadAllBytes(fileName))); } else { sf = new SaveFile(SaveName); } sf.Add(hook.SceneData); using (MemoryStream saveFileData = new MemoryStream(DataSerializer.SerializeProtoObject(sf))) { // Holds final zipped file data bytes. saveFileData.Position = 0; File.WriteAllBytes(fileName, ZipTools.CompressBytes(saveFileData.ToArray())); } }