Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Generics serialization

Discussion in '2020.1 Beta' started by AlkisFortuneFish, Sep 17, 2019.

  1. print_helloworld

    print_helloworld

    Joined:
    Nov 14, 2016
    Posts:
    231
    Nice, refactoring made easier
     
  2. AdamRamberg

    AdamRamberg

    Joined:
    Dec 8, 2016
    Posts:
    22
    First of all, great work! This feature simplifies so many cases and workflows.

    Got a question for you. In my project I defined the following generic ScriptableObjects:
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. [Serializable]
    5. public class BaseFoo<T> : ScriptableObject
    6. {
    7.   [SerializeField]
    8.   private T _bar;
    9. }
    10.  
    11. [CreateAssetMenu(menuName = "Foo", fileName = "FooSO")]
    12. public class Foo : BaseFoo<float> { }
    I then created an ScriptableObject asset from Foo. I also created a MonoBehaviour looking like this:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Baz : MonoBehaviour
    4. {
    5.     [SerializeField]
    6.     private BaseFoo<float> _foo;
    7. }
    8.  
    The field serializes and I'm able to assign my Foo ScriptableObject to the field. so that is great! However, the default search functionality for the property drawer is not finding Foo ScriptableObject (see attached screenshot).

    I guess this is because Foo is derived from BaseFoo<T> and instead of being a BaseFoo<T>. Is this something that is going to be fixed or is this the intended behaviour?
     

    Attached Files:

  3. quabug

    quabug

    Joined:
    Jul 18, 2015
    Posts:
    66
    Is it possible to support `SerializeReference` on generic type in the foreseeable future?
    It just show an error message if I try to add `SerializeReference` on a field of generic type.
    "This is not supported. You must create a non-generic subclass of your generic instance type and use that as the field type instead."​
     
    seblaf1 and Ghat-Smith like this.
  4. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    serializing of generics is coming in 2020.1. I don't know if this includes serialize reference, however
     
  5. quabug

    quabug

    Joined:
    Jul 18, 2015
    Posts:
    66
    Neither of 2020.1b nor 2020.2a have introduce this feature already.
    In the meanwhile, Odin(Serializer) provide alternative way to serialize generic field with `SerializeReference` attribute.
     
    Last edited: May 22, 2020
  6. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    659
    The Newtonsoft.Json package available in the Unity asset store puts the Unity serializer to shame. It can work off the main render thread and it supports a range of generic serialization options. I prefer it because it works server-side so that I get the same serialized JSON on game clients and server.
     
  7. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    Yeah, been using that for many years now but you do have to remember that the scope and purpose of it is very different to the Unity serialiser and their use can be combined. We've had polymorphic serialisation with proper UnityEngine.Object references and inspectors that look like the regular properly drawers for years now, but performance is not amazing.

    Saying that, I wonder how the Json.Net package manager package behaves with AOT etc.
     
    stonstad likes this.
  8. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    In what Unity version was this introduced? I can't seem to find it anywhere in the 2019 Release Notes.
     
  9. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    This is a 2020.1 feature, which is why this thread is in the 2020.1 Beta forum section ;)
     
    KyryloKuzyk and Dextozz like this.
  10. Thimo_

    Thimo_

    Joined:
    Aug 26, 2019
    Posts:
    59
    Will the abstract be removed from an UnityEvent at the final release of unity 2020.1?

    [EDIT] Yes they did, awesome!
     
    Last edited: Jul 25, 2020
    OndrejP likes this.
  11. ShuheiAoki

    ShuheiAoki

    Joined:
    Oct 15, 2018
    Posts:
    2
    I am also having this exact problem. Its holding me back from using generics because of this
     
  12. michal-zetkowski

    michal-zetkowski

    Joined:
    Mar 11, 2015
    Posts:
    282
    Hey, I've read through this thread and I'm wondering if I understand the implications of the following point correctly:
    As far as I understand, it basically means that I can do this:
    Code (CSharp):
    1. public class GameEventListener : MonoBehaviour
    2. {
    3.     public UnityEvent<GameEventArgs> Response;
    4. }
    Instead of this:
    Code (CSharp):
    1. public class TypedUnityEvent : UnityEvent<GameEventArgs> { }
    2.  
    3. public class GameEventListener : MonoBehaviour
    4. {
    5.     public TypedUnityEvent Response;
    6. }
    It that it? I am aware that it saves a lot of boilerplate code, but I feel like there must be more to it. You gave some examples in this thread, but they were quite difficult for me to understand and I would be thankful if someone could point me towards some simple use cases.

    Secondly, I'm working on a event system and I would like to extend the code to accept different types of event args, something like this:
    Code (CSharp):
    1. public class GameEventListener<T> : MonoBehaviour where T : GameEventArgs
    2. {
    3.     public UnityEvent<T> Response;
    4. }
    I am aware that this is beyond the point that I quoted, but could you maybe point me towards some solution different than subclassing GameEventListener for each type of GameEventArgs? Thanks :)
     
    AlejMC likes this.
  13. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,657
    Nope, that's pretty much it.
     
    AlejMC likes this.
  14. Ghat-Smith

    Ghat-Smith

    Joined:
    Aug 16, 2016
    Posts:
    53
    Same question. I would love to directly serialize generic type by reference.
     
    Flying_Banana likes this.
  15. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    I get the warning "Generic MonoBehaviours are not supported!" when I call ScriptableObject.CreateInstance on a generic class extending ScriptableObject in Unity 2020.1.3f1. Shouldn't this be supported with the new generic serialization feature?
     
  16. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    No. You still need to derive a concrete UnityEngine.Object derived instance for the engine to actually support it. This feature is about normal classes.
     
  17. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    862
    Thanks, good to know. Does anyone know if the feature (serialization of generic classes derived from UnityEngine.Object) is planned? This would greatly influence the design of the system I am building.
     
    koirat likes this.
  18. AlejMC

    AlejMC

    Joined:
    Oct 15, 2013
    Posts:
    149
    I’m curious on exactly this too.
    I have been using (more likely abusing, tell no one) the Events as SOs idea from Ryan Hipple 2017s presentation. It’s so great specially at the prototyping phase or dropping incredibly flexible events on animations (as objects with a single hard coded function “RaiseEvent” on the animator).

    The main drawback is exactly what you say, having dynamic UnityEvent<T> calls would still require creating Listeners with the corresponding response type. It gets exponentially worse with UnityEvent<T1, T2> and more.
    Calling them is easy, can just RaiseEvent<T>(T value); that’s the raiser basically.
    It would be great to do something like:
    Code (CSharp):
    1. public class Listener<T> : Monobehavior
    2. {
    3.     public GameEvent<T> Event;
    4.     public UnityEvent<T> Response;
    5.  
    6.     // Register to event’s list
    7.     void OnEnable();
    8.  
    9.     // Deregister from event’s list
    10.     void OnDisable();
    11.  
    12. }
    And say, “I want this listener to listen to Vector3s” because the event happens to output positions that could be used by sound emitters, particles systems for effects, etc
     
    joshcamas and michal-zetkowski like this.
  19. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,073
    We need more we need serialization of generic interfaces.

    class MyDamnComponent<T>:MonoBehaviour,IInterface1<T>,IInterface2{}


    [SerializeField]
    public IInterface1<T> variable;
     
    MaskedMouse, seblaf1, Servail and 4 others like this.
  20. Servail

    Servail

    Joined:
    Jan 26, 2017
    Posts:
    9
    We need even more, we need unified interface serialization for both System.Objects and UnityEngine.Objects. And it's not that hard as it appears, e.g. you just check assignee Type and handle UnityReferences with old sturdy [SerializeField] mechanism. BTW, why bother [SerializeField] at all? To get dupes after deserialization? Same for arrays/lists. If you serialize one-of-a-kind reference to object, it still behaves as a unique object after, like it was a value. Then why these overcomplicated segregation and list-of-refs rules? That's serialization racism! Just use serialization context and serialize in place if there's none. Unified [SerializeReference] must be a "new" standard (I'd rather call it just [Serialize])! Unify it ASAP; for now it's just ridiculous! And work out all the generics of course. It still warns"This is not supported" on open generic type fields in generic classes, althought it meant to be concretized on declaration.
    P.S.: Incomatibility with legacy serialization system? Consider a conversion mechanism, to load as old and save as new. Everyone more or less experienced in Unity knows: that's the lesser "evil" that must be done. Serializer is the Editor's weakest point, that ruins solid C# workflow.
     
    Last edited: Jan 19, 2021
    quabug and Ghat-Smith like this.
  21. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Was / is there any chance that serialization of generics (other than List and friends) will make it into 2019 LTS?
     
    Ruhan-Bello and anisimovdev like this.
  22. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,277
    Since LTS is meant to be the longterm stable release, adding new features after the fact would probably be a bad idea.
     
  23. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Thank you for adding that! Do you work on the LTS team?
     
  24. quabug

    quabug

    Joined:
    Jul 18, 2015
    Posts:
    66
    For those of you are eager to have generic type support on `SerializeReference`, here's my workaround solution:
    https://github.com/quabug/GenericSerializeReference
     
    kaiyum likes this.
  25. kaiyum

    kaiyum

    Joined:
    Nov 25, 2012
    Posts:
    686
    Hi, thanks for the stuff. It's really good. However, can you support classes outside of the assembly. I am writing a library, so this is essential for me.
     
  26. quabug

    quabug

    Joined:
    Jul 18, 2015
    Posts:
    66
    This feature is sure keep in my mind for awhile, I just too busy to implement it recently.
    Please post an issue or comment on related issue (https://github.com/quabug/GenericSerializeReference/issues/6) if you have further question or suggestion.
     
    kaiyum likes this.
  27. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    Last edited: Sep 26, 2022
    swedishfisk likes this.
  28. jonagill

    jonagill

    Joined:
    Oct 5, 2019
    Posts:
    12
    For what its worth, in 2022.2 you can serialize generic types, and
    [CustomPropertyDrawer(typeof(MyGenericType<>))]
    now works. Not quite sure when those both got added.
     
    tsukimi likes this.
  29. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    2020.1, I'd tested
    [CustomPropertyDrawer(typeof(MyGenericType<>))]
    on the second post of this thread. That said, I bet there have been a bazillion fixes to this between 2020.1 and 2022.2.
     
  30. silentslack

    silentslack

    Joined:
    Apr 5, 2013
    Posts:
    393
    I just installed Unity 2022.2 and stilll [SerializeReference] cannot be used with generics.