Renaming serialized MonoBehaviours results in null references

Issue #9 resolved
Ivan created an issue

The node serialization appears to be somewhat fragile. Components are referenced by name, so if you manually rename a script it's very easy to result in a null reference.

Steps to Repro

Create the following scripts:

public class TestScript {
    int testInt;
}
public class ListTest : MonoBehaviour {
    [OdinSerialize]
    List<TestScript> testScripts;
}
  1. Create a GameObject and attach the ListTest component. Add a test script.
  2. Save the scene.
  3. Rename "TestScript" to "NewTestScript" (as well as its references in ListTest.cs).
  4. Reopen the scene and see that the testScripts list has a single null reference.

Potential fix

Instead of serializing by name, it might be better to serialize by the script's guid?

Comments (4)

  1. Tor Esa Vestergaard
    • changed status to open

    This is currently the case for serialization of all types, not merely Unity objects. It is not so much a bug, as it is a feature that is very hard to implement.

    Unity, in fact, also loses data of any type when you rename them - only Unity's own special types are saved from this, and they have access to internal unmanaged engine state that we don't, that they can use to piece things back together. We do have access to some things in the editor, such as script guids, but our serialization cannot depend on the editor to work - it also needs to be able to deserialize properly in builds.

    That said, there are some things that can be done to mitigate this issue. Some are fairly straight-forward, and solve the problem partially. Many of them are not at all straight-forward, however, and would be challenging to implement in a safe way.

    This may not be something that will see a complete solution in the near future. We are however aware of the problem, and I will try to see if I can implement and test some of the partial solutions some time in the next week or so. These would at the very least resolve what is happening in your particular example.

    This is a longer-term issue. I'll leave it open for the duration.

  2. Ivan reporter

    I see, thanks for explaining! I didn't realize script guids were only accessible in the editor and not in builds.

    Random thought-- maybe you could add a editor-only serialization mode that uses guids, and in real builds fall back to names. After all, renaming is only an issue during development, and shouldn't pose any problems when the game is actually built. But that is probably a larger design decision for you guys.

    In the meantime, I've gotten around renames by writing a script to find and replace the names in scenes and prefabs, so no worries there.

  3. Julien Heimann

    Or you could introduce an attribute, like the unity one (FormerlySerializedAs("x")) only for classes, and use that to remap the data. In this case it would be up to the user to control the remapping (or even leave it out intentionally).

  4. Log in to comment