public void Load(GameobjectSaveData fullSave) { foreach (var save in fullSave.saves) { try { Type type = save.GetSaveType(); Component comp = GetComponent(type); if (comp == null) { throw new Exception("No component of type " + type.ToString() + " on gameobject " + gameObject.name); } ISaveableComponent saveable = (ISaveableComponent)comp; if (saveable == null) { throw new Exception("Component of type " + type.ToString() + " on gameobject " + gameObject.name + " is not a ISaveable"); } saveable.Load(save); } catch (Exception e) { Debug.LogError("Error when loading component due to " + e.ToString()); } } }
/// <summary> /// Returns default not unique id for specified saveable component. /// Returns Id specified in <see cref="SaveableComponentIdAttribute"/>. If there is no attribute then returns class name. /// </summary> /// <param name="saveableComponent">Saveable component.</param> /// <returns>Default not unique id for specified saveable component.</returns> private static string GetBaseIdForSaveableComponent(ISaveableComponent saveableComponent) { var type = saveableComponent.GetType(); var idAttribute = (SaveableComponentIdAttribute)type .GetCustomAttributes(typeof(SaveableComponentIdAttribute), true).FirstOrDefault(); var identifier = idAttribute != null ? idAttribute.Id : type.Name; return(identifier); }
public static void restoreData(Dictionary <string, object> source, ISaveableComponent target, Type lastSerializedType) { FieldInfo[] fields = getFieldsFromType(target.GetType(), lastSerializedType); foreach (KeyValuePair <string, object> entry in source) { fields.Where(field => field.Name == entry.Key).First(). setValue(target, getValue(entry.Value)); } }
/// <summary> /// Useful if you want to dynamically add a saveable component. To ensure it /// gets registered. /// </summary> /// <param name="identifier">The identifier for the component, this is the adress the data will be loaded from </param> /// <param name="iSaveableComponent">The interface reference on the component. </param> /// <param name="reloadData">Do you want to reload the data on all the components? /// Only call this if you add one component. Else call SaveMaster.ReloadListener(saveable). </param> public void AddSaveableComponent(string identifier, ISaveableComponent iSaveableComponent, bool reloadData = false) { _saveableComponents.Add(identifier, iSaveableComponent); if (reloadData) { // Load it again, to ensure all ISaveableComponent interface are updated. SaveSystemSingleton.Instance.GameStateManager.LoadSaveable(this); } }
/// <summary> /// Returns unique id for specified saveable component. /// </summary> /// <param name="saveableComponent"></param> /// <returns></returns> private string GenerateIdForSaveableComponent(ISaveableComponent saveableComponent) { var identifier = GetBaseIdForSaveableComponent(saveableComponent); while (!IsIdentifierUnique(identifier)) { int guidLength = SaveSettings.Get().componentGuidLength; string guidString = Guid.NewGuid().ToString().Substring(0, guidLength); identifier = string.Format("{0}-{1}", identifier, guidString); } return(identifier); }
List <ISaveableComponent> GetSaveableComponents() { List <ISaveableComponent> saveables = new List <ISaveableComponent>(); var comps = GetComponents <Component>(); foreach (Component c in comps) { ISaveableComponent saveable = c as ISaveableComponent; if (saveable != null) { saveables.Add(saveable); } } return(saveables); }
/// <inheritdoc/> public void Load(JObject state) { if (loadOnce && _hasLoaded) { return; } // Ensure it loads only once with the loadOnce parameter set to true _hasLoaded = true; if (_container == null) { _container = new SaveableContainerJObject("Saveable GameObject Container"); } _container.Load(state); foreach (var pair in _saveableComponents) { string saveableComponentId = pair.Key; ISaveableComponent saveableComponent = pair.Value; if (saveableComponent == null) { Debug.LogError( $"Failed to load component with id: {saveableComponentId}. Component is potentially destroyed."); } else { if (_container.TryGetValue(saveableComponentId, out var data, saveableComponent.SaveDataType)) { saveableComponent.Load(data); } } } // clear empty records if any foreach (var emptyKey in _saveableComponents.Where(pair => pair.Value == null).Select(pair => pair.Key) .ToArray()) { _saveableComponents.Remove(emptyKey); } }
public string Context => gameObject.scene.name; // todo cache? /// <inheritdoc/> public JObject Save() { foreach (var saveableComponent in _saveableComponents) { string getIdentification = saveableComponent.Key; ISaveableComponent getSaveableComponent = saveableComponent.Value; if (getSaveableComponent == null) { Debug.LogError(string.Format("Failed to save component: {0}. Component is potentially destroyed.", getIdentification)); } else { if (!_hasStateReset && !getSaveableComponent.OnSaveCondition()) { continue; } var data = getSaveableComponent.Save(); if (data == null) { Debug.LogError($"Saveable component returned null data. Id: {getIdentification}", gameObject); } else { _container.Set(getIdentification, data); } } } // clear empty records if any foreach (var emptyKey in _saveableComponents.Where(pair => pair.Value == null).Select(pair => pair.Key) .ToArray()) { _saveableComponents.Remove(emptyKey); } _hasStateReset = false; return(_container.Save()); }
protected virtual void componentRestored(ISaveableComponent c, IComponentAssigner assigner) { }
protected virtual void componentAdded(ISaveableComponent c) { }
public ISaveableComponent addComponent(GameObject gameObject, IComponentRecycler recycler) { createdComponent = (ISaveableComponent)recycler.getNextComponent(savedComponentType); componentAdded(createdComponent); return(createdComponent); }
protected override void componentRestored(ISaveableComponent c, IComponentAssigner assigner) { ((IHybridComponent)c).restoreComponent(assigner); }
protected override void componentRestored(ISaveableComponent c, IComponentAssigner assigner) { ((BaseSaveableMonoBehaviour)c).onBehaviourLoaded(); }
protected override void componentAdded(ISaveableComponent c) { ((BaseSaveableMonoBehaviour)c).WasCreated = true; }
public void OnValidate() { if (Application.isPlaying) { return; } if (GetComponent <IGuidProvider>() == null) { Undo.AddComponent <GuidComponent>(gameObject); } List <ISaveableComponent> obtainSaveables = new List <ISaveableComponent>(); GetComponentsInChildren(true, obtainSaveables); for (int i = 0; i < externalListeners.Count; i++) { if (externalListeners[i] != null) { obtainSaveables.AddRange(externalListeners[i].GetComponentsInChildren <ISaveableComponent>(true) .ToList()); } } for (int i = serializedSaveableComponents.Count - 1; i >= 0; i--) { if (serializedSaveableComponents[i].component == null) { serializedSaveableComponents.RemoveAt(i); } } if (obtainSaveables.Count != serializedSaveableComponents.Count) { if (serializedSaveableComponents.Count > obtainSaveables.Count) { for (int i = serializedSaveableComponents.Count - 1; i >= obtainSaveables.Count; i--) { serializedSaveableComponents.RemoveAt(i); } } int saveableComponentCount = serializedSaveableComponents.Count; for (int i = saveableComponentCount - 1; i >= 0; i--) { if (serializedSaveableComponents[i] == null) { serializedSaveableComponents.RemoveAt(i); } } ISaveableComponent[] cachedSaveables = new ISaveableComponent[serializedSaveableComponents.Count]; for (int i = 0; i < cachedSaveables.Length; i++) { cachedSaveables[i] = serializedSaveableComponents[i].component as ISaveableComponent; } ISaveableComponent[] missingElements = obtainSaveables.Except(cachedSaveables).ToArray(); for (int i = 0; i < missingElements.Length; i++) { CachedSaveableComponent newSaveableComponent = new CachedSaveableComponent() { identifier = GenerateIdForSaveableComponent(missingElements[i]), component = missingElements[i] as Component }; serializedSaveableComponents.Add(newSaveableComponent); } UnityEditor.EditorUtility.SetDirty(this); UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene); } }
public ISaveableComponent addComponent(GameObject gameObject, IComponentRecycler recycler) { ISaveableComponent result = (ISaveableComponent)recycler.getNextComponent(getGenericType()); return(result); }