Interface serialization refers to the prefab instead of the prefab instance

Issue #157 resolved
William Besnard
created an issue

Hi,

In the version you sent me by email the interface now properly serializes to the prefab, but not from the prefab: When I place the prefab on the scene, all my interfaces references linked within the prefab now refer to the one in the prefab itself instead of the instance of the prefab. When trying to relink it to the interface present in the instance of the prefab, and then applying the change to the prefab, I get an exception: bug1.PNG

Additionally, it looks like some of my MonoBehaviors contained in the same prefab take their in play values from the prefab instead of the prefab instance: bug2.PNG the value in bold is supposed to be an instance value, yet during play it takes the value of the prefab (which is false instead of true in that case).

The above script does not have any link to Odin Inspector, it is just present in a prefab that contains some Odin Serializer classes.

Comments (11)

  1. Tor Esa Vestergaard

    After a great deal of attempts late last night and this morning, I'm afraid I've proven completely unable to replicate either of your bugs. I've tried in Unity 5.3 (the version we develop Odin in), and in Unity 2017.1. I'll outline the things I've tried, here. If they match what you've been doing, then I'm not sure what's going on. I checked the commit log, and it doesn't seem like anything that would affect prefabs has been changed since I sent you that build.

    To replicate your first bug, I have created a MyMonoBehaviour derived from SerializedMonoBehaviour, containing a field of type ISomeInterface and a bool field, both serialized by Odin. MyMonoBehaviour also implements ISomeInterface (merely an empty interface). I have then in the scene constructed a fairly deep gameobject hierarchy, with every gameobject in the hierarchy having a MyMonoBehaviour attached. I then populated the interface fields in every component with references that went all over the internal hierarchy of the root gameobject. I then turned that root gameobject into a prefab by dragging it down into the project view. I checked the references on the prefab, and on what is now a prefab instance in the scene, and everything checked out. Finally, I dragged that prefab into the scene again, creating a new instance of it, and checked all the references. All of the references were still the same local references that were internal to the prefab instance - nowhere did anything refer to anything on the prefab itself. I tried a few variations of this, but couldn't get it to break.

    Then, to try and replicate the prefab's bool value being used instead of the prefab instance's, I tried changing some of the bool values on the prefab instance, and then changing some of them on the prefab (just to see that the unchanged ones changed correctly on the instances - they did). Then I entered and exited play mode a few times while fiddling with the bool values. They all worked as I would expect, and were set to what I saw them set to in the inspector when out of play mode, whether they were modified from the prefab or not.

    So, I don't know if these were the correct steps to reproduce, but so far, I haven't been able to. I'm afraid I'll have to ask for a more detailed set of steps to reproduce. Also, perhaps some other factor is relevant here. Which exact OS and Unity version are you on?

  2. William Besnard reporter

    I am using Windows 10 and Unity 2017.1.0.f3.

    As of how to reproduce the issue, I could do that by applying the local changes inside the editor, which are now applied to the prefab, and then drag and drop the prefab back into the scene as a new instance of the prefab, and then making some local changes on the prefab instance: this is when the issue occurred. I am going to try to reproduce the issue right now on another machine, and see if the problem is still there.

  3. William Besnard reporter

    I found another way to reproduce the issue: it seems that when I recompile the game from visual studio modifying any class, the prefab linking is broken the way I described it earlier. Clicking applying on the prefab once again after the compilation seems to solve the issue, as it takes back the local reference.

  4. William Besnard reporter

    I just realized I also forgot to mention something very important :/ This happens when you hit play, not right away in the editor: hitting play willl see all the reference link to the prefab, and when back in the editor as well, but applying the changes to the prefab once again fixes the issue, but only when not in play.

  5. Tor Esa Vestergaard

    That helped me reproduce it, thanks! I'm looking into what exactly is going on now. Sorry for the late reply - I'm technically on a family holiday, and some remote locations have spotty cell network coverage at best, so I didn't get any notification mails with your replies until recently. I'll let you know as soon as I figure this out, and send you a hotfix once I've got one that seems to hold up.

  6. Tor Esa Vestergaard

    Alright, I've identified what the exact issue is. Before, we'd blissfully been deserializing prefab instances from their prefab's data, first and foremost, and then applying modifications. Way back when I first wrote this, I (stupidly) didn't realize that of course, an unmodified prefab instance's data isn't the exact same as the prefab's - the Unity object references can be different! So we're deserializing with the prefab's data, and thus breaking things, except in a few special cases where we don't deserialize from the prefab's own data, such as when applying, and when reverting. Unity is just full of these little gotchas, though this one is admittedly embarassing on my part.

    Now I just need to figure what to do in order to fix it. This should hopefully be a fairly simple fix. I will have time later today to sit down and have a good go at it.

  7. Log in to comment