public override void OnBeforeSerialize(Type storageType, object instance) { CompRef cref = instance as CompRef; SavedComponent comp = cref.component; if (comp != null) { cref.isNull = false; if (blueprint) { cref.entity_ID = comp.Entity.blueprintID; } else { cref.entity_ID = comp.Entity.ID; } cref.component_ID = comp.componentID; cref.entityName = comp.Entity.name; } else { cref.isNull = true; } cref.component = null; }
static void SetDataForComponent(SavedComponent comp, SaveData data) { Type t = comp.GetType(); var field = findDataField(t); if (field != null) { field.SetValue(comp, data); } }
/// <summary> /// Attempts to deserialize a value from a serialized state. /// </summary> public fsResult TryDeserialize(fsData data, Type storageType, Type overrideConverterType, ref object result) { if (data.IsNull) { result = null; var processors = GetProcessors(storageType); Invoke_OnBeforeDeserialize(processors, storageType, ref data); Invoke_OnAfterDeserialize(processors, storageType, null); return(fsResult.Success); } // Convert legacy data into modern style data ConvertLegacyData(ref data); try { // We wrap the entire deserialize call in a reference group so // that we can properly deserialize a "parallel" set of // references, ie, a list of objects that are cyclic w.r.t. the // list _references.Enter(); List <fsObjectProcessor> processors; var r = InternalDeserialize_1_CycleReference(overrideConverterType, data, storageType, ref result, out processors); if (r.Succeeded) { Invoke_OnAfterDeserialize(processors, storageType, result); if (result != null) { if (typeof(SavedComponent).IsAssignableFrom(storageType)) { SavedComponent component = result as SavedComponent; component.OnAfterLoad(); } else if (typeof(SavedScriptable).IsAssignableFrom(storageType)) { SavedScriptable scriptable = result as SavedScriptable; scriptable.OnAfterLoad(); } } } return(r); } finally { _references.Exit(); } }
static SaveData GetDataFromComponent(SavedComponent comp) { if (comp == null) { return(null); } Type t = comp.GetType(); var field = findDataField(t); if (field != null) { var data = field.GetValue(comp) as SaveData; return(data); } else { return(null); } }
/// <summary> /// Serialize the given value. /// </summary> /// <param name="storageType"> /// The type of field/property that stores the object instance. This is /// important particularly for inheritance, as a field storing an /// IInterface instance should have type information included. /// </param> /// <param name="overrideConverterType"> /// An fsBaseConverter derived type that will be used to serialize the /// object instead of the converter found via the normal discovery /// mechanisms. /// </param> /// <param name="instance"> /// The actual object instance to serialize. /// </param> /// <param name="data">The serialized state of the object.</param> /// <returns>If serialization was successful.</returns> public fsResult TrySerialize(Type storageType, Type overrideConverterType, object instance, out fsData data) { var processors = GetProcessors(instance == null ? storageType : instance.GetType()); Invoke_OnBeforeSerialize(processors, storageType, instance); if (instance != null) { if (typeof(SavedComponent).IsAssignableFrom(storageType)) { SavedComponent component = instance as SavedComponent; component.OnBeforeSave(); } else if (typeof(SavedScriptable).IsAssignableFrom(storageType)) { SavedScriptable scriptable = instance as SavedScriptable; scriptable.OnBeforeSave(); } } // We always serialize null directly as null if (ReferenceEquals(instance, null)) { data = new fsData(); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); return(fsResult.Success); } var result = InternalSerialize_1_ProcessCycles(storageType, overrideConverterType, instance, out data); Invoke_OnAfterSerialize(processors, storageType, instance, ref data); return(result); }
static void ProcessEntity(SaveObject file, SaveEntity ent, HashSet <int> bp_ids, Transform root) { EntityObject eobj = new EntityObject(); SaveEntity entity = ent; bool isBlueprint = bp_ids != null; file.isBlueprint = isBlueprint; CompRefSerializationProcessor.blueprint = isBlueprint; if (isBlueprint && entity.blueprintID == 0) { entity.blueprintID = SaveSystemUtilities.GetUniqueID(bp_ids); } eobj.blueprint_ID = entity.blueprintID; Transform tr = entity.transform; eobj.database_ID = entity.entityID; eobj.instance_ID = entity.instanceID; eobj.prefabPath = SaveEntityDatabase.GetPrefabPath(entity.entityID); eobj.Enabled = ent.gameObject.activeSelf; if (isBlueprint) { eobj.position = root.InverseTransformPoint(tr.position); eobj.rotation = tr.localRotation.eulerAngles; } else { eobj.position = tr.position; eobj.rotation = tr.rotation.eulerAngles; } bool hasParent = tr.parent != null; SavedComponent parentComp = null; if (hasParent) { parentComp = tr.parent.GetComponent <SavedComponent>(); } if (tr.parent != root && parentComp) { eobj.parentIsComponent = true; if (isBlueprint) { eobj.parent_entity_ID = parentComp.Entity.blueprintID; } else { eobj.parent_entity_ID = parentComp.Entity.ID; } eobj.parent_component_ID = parentComp.componentID; } else { SaveEntity parentEntity = null; if (hasParent) { parentEntity = tr.parent.GetComponent <SaveEntity>(); } if (tr.parent != root && parentEntity) { eobj.parentIsEntity = true; if (isBlueprint) { eobj.parent_entity_ID = parentEntity.blueprintID; } else { eobj.parent_entity_ID = parentEntity.ID; } } else { if (isBlueprint) { eobj.parentName = "null"; } else { eobj.parentName = tr.parent == null ? "null" : tr.parent.name; } } } eobj.gameObjectName = entity.name; file.entities.Add(eobj); getComponentsSwapList.Clear(); entity.GetComponentsInChildren <SavedComponent>(true, getComponentsSwapList); foreach (var comp in getComponentsSwapList) { if (comp.componentID == 0) { //Debug.Log("Skipping component without ID : " + comp.GetType(), entity.gameObject); continue; } comp.SendMessage("OnBeforeSave", SendMessageOptions.DontRequireReceiver); ComponentObject cobj = new ComponentObject(); cobj.component_ID = comp.componentID; cobj.data = GetDataFromComponent(comp); cobj.initialized = comp.Initialized; cobj.enabled = comp.enabled; Dictionary <int, ComponentObject> entityComponents = null; if (isBlueprint) { file.components.TryGetValue(entity.blueprintID, out entityComponents); } else { file.components.TryGetValue(entity.instanceID, out entityComponents); } if (entityComponents == null) { entityComponents = new Dictionary <int, ComponentObject>(); if (isBlueprint) { file.components.Add(entity.blueprintID, entityComponents); } else { file.components.Add(entity.instanceID, entityComponents); } } if (entityComponents.ContainsKey(comp.componentID)) { Debug.LogError("Super fatal error with duplicate component id's on entity.", entity.gameObject); } entityComponents.Add(comp.componentID, cobj); if (cobj.data != null) { Type t = cobj.data.GetType(); var fields = t.GetFields(); foreach (var f in fields) { if (f.FieldType == typeof(CompRef)) { file.comprefs.Add(f.GetValue(cobj.data) as CompRef); } } } } }
public static void UnboxSaveObject(SaveObject save, Transform root) { if (save == null) { Debug.LogError("Save object is null"); return; } var initializedfield = typeof(SavedComponent).GetField("m_initialized", BindingFlags.NonPublic | BindingFlags.Instance); Dictionary <int, SaveEntity> bp_entity = null; Dictionary <int, Dictionary <int, SavedComponent> > bp_parent_component = null; Dictionary <int, Dictionary <int, SavedComponent> > bp_all_comp = new Dictionary <int, Dictionary <int, SavedComponent> >(); if (save.isBlueprint) { bp_entity = new Dictionary <int, SaveEntity>(); bp_parent_component = new Dictionary <int, Dictionary <int, SavedComponent> >(); bp_all_comp = new Dictionary <int, Dictionary <int, SavedComponent> >(); } bool blueprintEditorMode = save.isBlueprint && !Application.isPlaying; Dictionary <int, ComponentObject> cobjects = null; Dictionary <int, Dictionary <int, SavedComponent> > allComps = new Dictionary <int, Dictionary <int, SavedComponent> >(); Dictionary <int, SaveEntity> allEntities = new Dictionary <int, SaveEntity>(); Dictionary <EntityObject, SaveEntity> toParent = new Dictionary <EntityObject, SaveEntity>(); List <SavedComponent> allComponents = new List <SavedComponent>(); foreach (var eobj in save.entities) { var prefab = SaveEntityDatabase.GetPrefab(eobj.database_ID); if (!prefab) { Debug.LogError("When loading, database entity: " + eobj.database_ID + " was not found, this probably means you saved an entity that is not registered in database. Make it a prefab in Entity folder and run database scan."); continue; } bool prefabState = prefab.activeSelf; prefab.SetActive(false); GameObject gameobj = null; #if UNITY_EDITOR if (blueprintEditorMode) { gameobj = PrefabUtility.InstantiatePrefab(prefab) as GameObject; } else { gameobj = GameObject.Instantiate(prefab); } #else gameobj = GameObject.Instantiate(prefab); #endif gameobj.name = eobj.gameObjectName; var tr = gameobj.transform; GameObject parentGo = null; if (eobj.parentName != "null") { parentGo = GameObject.Find(eobj.parentName); } if (save.isBlueprint) { tr.parent = root; tr.localPosition = eobj.position; tr.localRotation = Quaternion.Euler(eobj.rotation); } else { tr.position = eobj.position; tr.rotation = Quaternion.Euler(eobj.rotation); tr.parent = eobj.parentName == "null" ? root : parentGo == null ? root : parentGo.transform; } var entity = gameobj.GetComponent <SaveEntity>(); Dictionary <int, SavedComponent> ecomps = null; Dictionary <int, SavedComponent> bpcomps = null; if (save.isBlueprint) { bp_entity.Add(eobj.blueprint_ID, entity); bp_all_comp.TryGetValue(eobj.blueprint_ID, out bpcomps); if (bpcomps == null) { bpcomps = new Dictionary <int, SavedComponent>(); bp_parent_component.Add(eobj.blueprint_ID, bpcomps); } bp_parent_component.TryGetValue(eobj.blueprint_ID, out ecomps); if (ecomps == null) { ecomps = new Dictionary <int, SavedComponent>(); bp_parent_component.Add(eobj.blueprint_ID, ecomps); } } else { allEntities.Add(eobj.instance_ID, entity); } entity.instanceID = eobj.instance_ID; entity.blueprintID = eobj.blueprint_ID; if (eobj.parentIsComponent || eobj.parentIsEntity) { toParent.Add(eobj, entity); } var comps = gameobj.GetComponentsInChildren <SavedComponent>(true); if (comps.Length != 0) { if (save.isBlueprint) { save.components.TryGetValue(entity.blueprintID, out cobjects); } else { save.components.TryGetValue(entity.instanceID, out cobjects); } if (cobjects != null) { foreach (var component in comps) { if (save.isBlueprint) { ecomps.Add(component.componentID, component); } ComponentObject cobj = null; cobjects.TryGetValue(component.componentID, out cobj); if (cobj != null) { SetDataForComponent(component, cobj.data); initializedfield.SetValue(component, cobj.initialized); component.enabled = cobj.enabled; } //Storing for later reference injection Dictionary <int, SavedComponent> injectionDict = null; allComps.TryGetValue(entity.ID, out injectionDict); if (injectionDict == null) { injectionDict = new Dictionary <int, SavedComponent>(); allComps.Add(entity.ID, injectionDict); } injectionDict.Add(component.componentID, component); allComponents.Add(component); } } } if (save.isBlueprint) { entity.instanceID = 0; } prefab.SetActive(prefabState); if (eobj.Enabled) { entity.gameObject.SetActive(true); } else { entity.InitializeDisabled(); } //HACK change this to something like interface. //entity.gameObject.BroadcastMessage("OnAfterLoad", SendMessageOptions.DontRequireReceiver); } if (CompRefSerializationProcessor.refs != null && CompRefSerializationProcessor.refs.Count > 0) { foreach (var compref in CompRefSerializationProcessor.refs) { if (!compref.isNull) { Dictionary <int, SavedComponent> comps = null; SavedComponent cbase = null; if (save.isBlueprint) { bp_parent_component.TryGetValue(compref.entity_ID, out comps); } else { allComps.TryGetValue(compref.entity_ID, out comps); } if (comps != null) { if (save.isBlueprint) { bp_parent_component[compref.entity_ID].TryGetValue(compref.component_ID, out cbase); } else { comps.TryGetValue(compref.component_ID, out cbase); } if (cbase != null) { compref.component = cbase; } else { Debug.LogError("CompRef linker could not find component with id: " + compref.component_ID + " on entity: " + compref.entityName); } } else { Debug.LogError("CompRef linker could not find entity with id: " + compref.entity_ID + " on entity: " + compref.entityName); } } } } #if UNITY_EDITOR if (blueprintEditorMode) { foreach (var e in bp_entity) { var go = PrefabUtility.FindPrefabRoot(e.Value.gameObject); PrefabUtility.DisconnectPrefabInstance(go); PrefabUtility.ReconnectToLastPrefab(go); } } #endif if (save.isBlueprint) { if (blueprintEditorMode) { #if UNITY_EDITOR foreach (var pair in toParent) { SaveEntity e = pair.Value; var go = PrefabUtility.FindPrefabRoot(e.gameObject); PrefabUtility.DisconnectPrefabInstance(go); EntityObject eobj = pair.Key; Transform parent = null; if (eobj.parentIsComponent) { parent = bp_parent_component[eobj.parent_entity_ID][eobj.parent_component_ID].transform; } else if (eobj.parentIsEntity) { parent = bp_entity[eobj.parent_entity_ID].transform; } e.transform.SetParent(parent); PrefabUtility.ReconnectToLastPrefab(go); } #endif } else { foreach (var pair in toParent) { SaveEntity e = pair.Value; EntityObject eobj = pair.Key; Transform parent = null; if (eobj.parentIsComponent) { parent = bp_parent_component[eobj.parent_entity_ID][eobj.parent_component_ID].transform; } else if (eobj.parentIsEntity) { parent = bp_entity[eobj.parent_entity_ID].transform; } e.transform.SetParent(parent); } } } else { foreach (var pair in toParent) { SaveEntity e = pair.Value; EntityObject eobj = pair.Key; Transform parent = null; if (eobj.parentIsComponent) { parent = allComps[eobj.parent_entity_ID][eobj.parent_component_ID].transform; } else if (eobj.parentIsEntity) { parent = allEntities[eobj.parent_entity_ID].transform; } e.transform.SetParent(parent); } } foreach (var comp in allComponents) { comp.SendMessage("OnAfterLoad", SendMessageOptions.DontRequireReceiver); } }