Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

FormerlySerializedAs not working in 2018.3?

Discussion in 'Editor & General Support' started by Michael-Ryan, Jan 3, 2019.

  1. Michael-Ryan


    Apr 10, 2009
    Confirmed as a reproducible bug on 2018.3. Case #1114464

    My project has been around for a while, and it has been updated for various Unity releases over the years.

    We have a number of scripts that have used the FormerlySerializedAs attribute on MonoBehaviour fields. That has worked well for us until now. After upgrading the project to 2018.3, it seems like all prefabs that were serialized using old field names (that should be handled by FormerlySerializedAs) are not being loaded correctly, and the Inspector will show the default data. The data is still present in the scene file (the serialized YAML text shows the data with the old property name, but the value of that property does not show in the Inspector.

    For more recently placed objects of the same type, the data was read using the new field name and appears correctly in the Inspector.

    Is FormerlySerializedAs broken on 2018.3.0f2?

    Is there a way to proactively reserialize all project assets (under an older Unity version) so the YAML serialization shows only the new property names (not the legacy property names that would be handled by FormerlySerializedAs)?

    I have a script that will mark and asset as dirty and resave it, which tends to reserialize the asset, but this doesn't seem to work with Unity scene assets. It seems like I'd need to mark ever scene object and possibly every component on every scene object as dirty so get it to reserialize with the new property name.

    Does this make sense? Does anyone have any experience with this?
    Last edited: Jan 4, 2019
  2. Peter77


    Jun 12, 2013
  3. Michael-Ryan


    Apr 10, 2009
    Oh yeah. I forgot about "ForceReserializeAssets". I saw that it was introduced in 2017 or 2018 when I was still on 5.6. Thanks for the reminder.

    My original question about FormerlySerializedAs being broken in 2018.3 stands.

    I loaded the project in 2018.2.18f1 and scenes loaded correctly, including data attached to fields that were renamed and have the FormerlySerializedAs attribute. All data looked good. I wrote a script to get all scene objects and all components on those objects. The scene, all objects, and all components were marked dirty via script, and then the scene was saved.

    Looking at the scene diff, I saw that various components were updated and new YAML serialized data was added. For example, the GameObject's "serializedVersion" changed from 5 to 6. Also, data associated with FormerlySerializedAs fields were also included.

    I then dropped the updated scene file in the 2018.3 project, and everything is now working there. Data that was missing on objects prior to the manual 2018.2 reserialization now shows up in the 2018.3 Inspector.

    So it seems like 2018.3 just isn't recognizing the FormerlySerializedAs attribute or not handling it properly in some situations.
  4. Peter77


    Jun 12, 2013
    Could you please submit a bug-report, as described in this document:

    After you submitted the bug-report, you receive a confirmation email with a bug-report Case number. You can post this Case number here (in this forum thread) for Unity staff to pick up, in case they see it.
  5. Michael-Ryan


    Apr 10, 2009
    I already submitted a bug. It's in as case #1114464.

    I was able to reproduce the issue with a clean project. If anyone wants details:

    I tried using the
    , however, it did not seem to reserialize the scenes with the "new" field names. The YAML data still included only the "old" field names that the
    attribute should map to the new field names. Is this a bug?

    Using the following code, I was able to mark all scene GameObjects and components dirty, so that when the scene was saved, the scene and its dependencies were reserialized in a way that data associated with
    fields were saved with the new field name.

    Code (CSharp):
    1. namespace Greyborn.Editor.MenuItems
    2. {
    3.    using UnityEditor;
    4.    using UnityEditor.SceneManagement;
    6.    using UnityEngine;
    7.    using UnityEngine.SceneManagement;
    9.    public static class AssetsMenuItems
    10.    {
    11.       [MenuItem("Assets/Reserialize Scene", false, 80)]
    12.       public static void ForceReserializeSceneObjects()
    13.       {
    14.          var transforms = Resources.FindObjectsOfTypeAll<Transform>();
    15.          for (var i = 0; i < transforms.Length; i++)
    16.          {
    17.             var transform = transforms[i];
    18.             var components = transform.GetComponents<MonoBehaviour>();
    19.             for (var j = 0; j < components.Length; j++)
    20.             {
    21.                EditorUtility.SetDirty(components[j]);
    22.             }
    24.             EditorUtility.SetDirty(transform.gameObject);
    25.          }
    27.          var scene = SceneManager.GetActiveScene();
    28.          EditorSceneManager.MarkSceneDirty(scene);
    30.          AssetDatabase.SaveAssets();
    31.       }
    32.    }
    33. }
    The down side is that I needed to open each scene, run the command, and then save the scene. This needed to be performed on Unity 2018.2.18f1 or earlier. I could then submit the changes to SVN or copy the .unity files over to the 2018.3.0f2 project and they would load fine there.
    Last edited: Jan 4, 2019
    Peter77 likes this.
  6. schwar


    Oct 8, 2016