Search Unity

Serialized variable lost its value after removing FormerSerializedAs

Discussion in 'Scripting' started by Deleted User, Jan 29, 2019.

  1. Deleted User

    Deleted User

    Guest

    I renamed a serialized variable and put FormerSerializedAs on top of it. Everything worked fine.
    According to this blog post, There should be no problems if I save all assets and remove FormerSerializedAs attribute. But my serialized fields are losing their value one by one.
    What's the problem?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    It's because not all prefabs/scenes have actually saved over that value updating its name in the yaml.

    And yes, even if you click save all/project (whatever it is) it doesn't necessarily update these values.

    If you went to each and every prefab/scene and modified it in some manner that it cleaned itself, then it would update... but otherwise no it won't.

    Keep the FormerlySerializedAs on there indefinitely unless you're 100% certain every prefab/scene has updated since then.

    ...

    I know this seems counter to what the save all/project implies... it annoyed me as well. But so it goes. I discovered this just because I did a FormerlySerializedAs, hit Save All, and then looked into my version control and so nothing really actually got changed.

    As far as I can tell though it just commits all dirty assets to disk.
     
    xVergilx, SparrowGS and Deleted User like this.
  3. Deleted User

    Deleted User

    Guest

    How about writing an editor script that marks all assets as dirty and then save all? Is it possible?
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    I'm willing to bet if you did that it might work.

    Haven't tested it... note you can save all from that same script.

    Do you have version control or something other diff'ing program? If so, do a test, see what all gets touched.

    If you don't just use something like grep or powershell (not sure your platform) and search all your files for the property you've renamed and see if the old name still exists (note your assets should all be in text mode via the editor project settings).

    Otherwise... I may check when I get home. At the office now so it won't be for at least 8 hours... and if I don't get drunk between the office and home... lol.
     
    Deleted User likes this.
  5. Deleted User

    Deleted User

    Guest

    I came up with this small script that seems to do the trick.
    After hitting Re-save all, it's safe to remove all FormerSerializedAs attributes.

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class ResaveAll : Editor
    5. {
    6.     [MenuItem("Edit/Re-save All")]
    7.     private static void Resave()
    8.     {
    9.         string[] assets = AssetDatabase.FindAssets("");
    10.        
    11.         Debug.Log($"Re-saving {assets.Length} assets");
    12.         foreach (string guid in assets)
    13.         {
    14.             string path = AssetDatabase.GUIDToAssetPath(guid);
    15.             var asset = AssetDatabase.LoadAssetAtPath<Object>(path);
    16.             EditorUtility.SetDirty(asset);
    17.         }
    18.        
    19.         AssetDatabase.SaveAssets();
    20.     }
    21. }
    22.  
     
    dan_ginovker, Neiist and lordofduct like this.
  6. Neiist

    Neiist

    Joined:
    Sep 18, 2012
    Posts:
    31
    Very nice, thank you, I just used it in my own project and modified it a bit to avoid some errors I encountered, if it can be useful to anyone else.

    Code (CSharp):
    1. // Original source: https://forum.unity.com/threads/serialized-variable-lost-its-value-after-removing-formerserializedas.621055/
    2. using UnityEngine;
    3. using UnityEditor;
    4.  
    5.  
    6. namespace YOUR_NAMESPACE_HERE
    7. {
    8.    internal class EditorForceSaveAll : Editor
    9.    {
    10.       [MenuItem("Tools/Force Save All")]
    11.       private static void ForceSaveAll()
    12.       {
    13.          // Gets the guid of assets present in the Assets folder only, assets in the Packages folder are immutable
    14.          // and trying to save the logs errors out even though it does not prevent the saving process to complete.
    15.          var guids = AssetDatabase.FindAssets(string.Empty, new[] { "Assets" });
    16.  
    17.          Debug.Log($"Forcefully re-saving {guids.Length} assets.");
    18.  
    19.          // Caching the length of the collection would be more relevant with a List<T>, but the array can be very long.
    20.          for (int i = 0, length = guids.Length; i < length; i++)
    21.          {
    22.             if (string.IsNullOrEmpty(guids[i]))
    23.                continue;
    24.  
    25.             var asset = AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GUIDToAssetPath(guids[i]));
    26.             if (asset == null)
    27.                continue;
    28.  
    29.             // Skips attempting to save assets such as implementations of `UnityEditor.ScriptableSingleton<T>`.
    30.             if ((asset.hideFlags & (HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor)) != 0)
    31.                continue;
    32.  
    33.             EditorUtility.SetDirty(asset);
    34.          }
    35.  
    36.          AssetDatabase.SaveAssets();
    37.       }
    38.    }
    39. }
     
    Last edited: Jan 15, 2024
    SanyaBane, dan_ginovker and Bunny83 like this.
  7. TheVague

    TheVague

    Joined:
    Nov 11, 2020
    Posts:
    1
    Neiist likes this.