private void RestoreMode(string serializedMode) { // Parse JSON back to objects var modeParams = JsonUtility.FromJson <ModeParameters>(serializedMode); // Build list that contains Components (only necessary information) var trackableComponentsList = modeParams.Parameters.Select(i => i.ComponentName); // Build list of gameObject's components that present in prev list var trackableComponents = gameObject.GetComponents(typeof(UnityEngine.Component)).Where(c => trackableComponentsList.Contains(c.GetType().ToString())); // Go through particular gameObject's components only foreach (var component in trackableComponents) { // Get type of component Type type = component.GetType(); // Go through each field in this component foreach (var f in type.GetFields().Where(i => i.IsPublic)) { // Find if there is a record for this field in ModeParameters var prm = modeParams.Parameters.FirstOrDefault(i => i.ComponentName == type.ToString() && i.ParamName == f.Name); // If record was found if (prm != default(Parameter)) { // If this is simple type then restore value if (prm.ParamType != "CachedUnityObject") { object obj = null; var converter = TypeDescriptor.GetConverter(f.FieldType); if (!converter.CanConvertFrom(typeof(String))) { if (f.FieldType == typeof(Vector3)) { obj = UnityTypesConverter.Vector3FromString(prm.Value); } if (f.FieldType == typeof(Quaternion)) { obj = UnityTypesConverter.QuaternionFromString(prm.Value); } } else { obj = converter.ConvertFromString(prm.Value); } f.SetValue(component, obj); } // Othervise take object from cache else { var cachedObj = this.cachedUnityObjects.FirstOrDefault(i => i.Key == prm.Value && i.ModeGUID == modeParams.GUID); if (cachedObj != default(CachedParameter)) { f.SetValue(component, cachedObj.Value); } } } } // Go through each property in this component BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; foreach (var p in type.GetProperties(flags)) { // Find if there is a record for this field in ModeParameters var prm = modeParams.Parameters.FirstOrDefault(i => i.ComponentName == type.ToString() && i.ParamName == p.Name); // If record was found if (prm != default(Parameter)) { // If this is simple type then restore value if (prm.ParamType != "CachedUnityObject") { object obj = null; var converter = TypeDescriptor.GetConverter(p.PropertyType); if (!converter.CanConvertFrom(typeof(String))) { if (p.PropertyType == typeof(Vector3)) { obj = UnityTypesConverter.Vector3FromString(prm.Value); } if (p.PropertyType == typeof(Quaternion)) { obj = UnityTypesConverter.QuaternionFromString(prm.Value); } } else { obj = converter.ConvertFromString(prm.Value); } p.SetValue(component, obj, null); } // Othervise take object from cache else { var cachedObj = this.cachedUnityObjects.FirstOrDefault(i => i.Key == prm.Value && i.ModeGUID == modeParams.GUID); if (cachedObj != default(CachedParameter)) { p.SetValue(component, cachedObj.Value, null); } } } } } }