Search Unity

Polymorphic Serialization with ScriptableObject crashes Unity 4.2?

Discussion in 'Editor & General Support' started by Andy2222, Aug 22, 2013.

  1. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    Hi,

    i tried to confirm if the prefab problem and Polymorphic Serialization using scriptable objects still exists in unity 4.2 as described here:
    http://www.codingjargames.com/blog/2012/11/30/advanced-unity-serialization/

    To my surprise Unity 4.2 directly crashes if i try to use the code from the example?

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Base : ScriptableObject { public int myInt; }
    7.  
    8. public class Derived : Base { public string myString; }
    9.  
    10. public class TestClass : MonoBehaviour
    11. {
    12.     public Base _myBase;
    13.  
    14.     // This gets called in the Editor when you first create this MonoBehaviour.
    15.     public void Reset()
    16.     {
    17.         _myBase = ScriptableObject.CreateInstance<Derived>();
    18.     }
    19. }
    20.  
    If u try to attach TestClass to a gameobject, Unity 4.2 simply crashes. So in terms of Polymorphic Serialization, Unity got even worse?

    thx Andy


    PS: Coming from UDK it was a little shock, that i cant get a Polymorphic List<Baseclass> correctly serialized and usable in prefabs, since this works without problems in UDK.
     
    Last edited: Aug 22, 2013
  2. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    Did some more testing and also code variations from http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-Megapost now crashes Unity 4.2?

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. [System.Serializable]
    7. public class Base : ScriptableObject
    8. {
    9.     public int myInt;
    10.  
    11.     public void OnEnable()
    12.     {
    13.         hideFlags = HideFlags.HideAndDontSave;
    14.     }
    15. }
    16.  
    17. [System.Serializable]
    18. public class Derived1 : Base
    19. {
    20.     public string myString;
    21. }
    22.  
    23. [System.Serializable]
    24. public class Derived2 : Base
    25. {
    26.     public float myFloat;
    27. }
    28.  
    29. public class TestClass : MonoBehaviour
    30. {
    31.     public Base _myBase1;
    32.     public Base _myBase2;
    33.  
    34.     public void Start()
    35.     {
    36.         if (_myBase1 == null) {
    37.             _myBase1 = ScriptableObject.CreateInstance<Derived1>();
    38.         }
    39.  
    40.         if (_myBase2 == null) {
    41.             _myBase2 = ScriptableObject.CreateInstance<Derived2>();
    42.         }
    43.     }
    44. }
    45.  
     
  3. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
    I just recently discovered this in 4.2. Was surprised how easy it was to cause the editor to crash.

    I've submitted a bug report.

    Hope they'll clean this up soon (+1 for hot fix)
     
  4. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Hi, I just checked this in our 4.3 branch and it seems to be fixed there. So a fix _is_ incoming. I'll try and find who did the fix and see if it will be coming to a 4.2 hotfix.
     
  5. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
    Great. Thank you for that.

    Do we have a time frame for 4.3 ?
     
  6. Simon Says

    Simon Says

    Joined:
    Feb 23, 2013
    Posts:
    6
    I'll be waiting for the fix anxiously, since it's kind of a showstopper for me :( By the way, the issue is still present in 4.2.1.
     
    Last edited: Sep 13, 2013
  7. greg-h

    greg-h

    Joined:
    Jul 29, 2012
    Posts:
    17
    I changed your code so that instead of using ScriptableObject.CreateInstance<Derived>(), it simply called the constructor: _myBase = new Derived().

    It didn't crash. Instead, it complained that it could not find the type.

    So, I moved Base into its own file called Base.cs and Derived into Derived.cs. Unity ceased to crash while using CreateInstance<Derived>().

    Using Unity v4.2.0f4
     
  8. MikeMarcin

    MikeMarcin

    Joined:
    May 15, 2012
    Posts:
    17
    This is blocking me currently as well.

    Any news on this hotfix or 4.3 release schedule?
     
  9. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    Did you try moving the classes into separate files, as greg.h suggested? I've also had problems in the past with multiple concrete UnityEngine.Object-derived types in a single file, where moving them into separate files solved the problem, so it's worth a shot.
     
  10. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    I believe greg.h if he says this fixes the problem, however my main problem was correct serialization of polymorphic containers, which is not possible in Unity and i did not see any new info/feedback towards this. I just stumbled on the above problem as a result of trying to understand why serialization of polymorphic containers is not working at all.

    I would really like if i could just write: "public List<AbstarctBaseClass> MyList; " and in the inspector i get a list of all "derived : BaseClass" objects i can select and add to this list. This was possible out of the box in UDK and was very handy to design modular systems, that are setup via the editor/level designer. The only alternative i could came up with for Unity, was to use the gameObject itself as "container", but this has its limits, is much harder to maintain and setup, compared to a named polymorphic container inside a component.

    bye Andy
     
  11. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    Polymorphic serialisation of non-UnityEngine.Object types has been worked on recently, I believe, so the situation will improve eventually. I wouldn't expect to see it in 4.3 though.
     
  12. Andy2222

    Andy2222

    Joined:
    Nov 4, 2009
    Posts:
    81
    mhh the status on http://feedback.unity3d.com/suggestions/serialization-of-polymorphic-dat did not change since 2012?

    Will those changes to "Polymorphic serialisation of non-UnityEngine.Object types" allow to create a polymorphic List/HashSet's that get correctly serialized/deserialized?

    As a example we use a modular condition system, but because of this serialization problem, the only way to get this working is to wrap each condition as a Monobehaviour and use the gameobject itself as polymorphic container. This ofc only allows for one condition set per gameobject and only one class can/should use the condition set. What we actually want is to have the ability to store a "Condition Set" aka polymorphic List<BaseCondition> directly inside the using class as field, so we can have as many sets as needed per component/class as opposed to per gameobject.


    bye Andy
     
    Last edited: Oct 18, 2013
  13. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
  14. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    I'd like to share my solution to polymorphic serialization: <VFW> Well, not much can be done about it with Unity's current serialization system. So a custom system with a custom serializer must exist. I used FullSerializer as my backend serializer and managed to serialize pretty much all the types that Unity has trouble dealing with (properties, interfaces, abstract system objects, delegates etc)