SerializeReference Attribute?

Any quick word on what the SerializeReference Attribute mentioned in the release notes is?

[Apologies in advance: no time at present to download and install the alpha and its documentation to check if it's already documented there...]

3 Likes

The field attribute is for serializing reference types (c# class, not structs) by reference as opposed to by value (as is the default behaviour).

This allows:
- Expressing graphs without having to resort to ScritableObjects for each node in the graph.
- Polymorphic data, ex: List;
- Have null fields: Standard deserialization behaviour for fields that are null is to set them to a default value of the type.

contrived usage example:

interface INode{  }

[Serializable]
class RootNode : INode
{
   [SerializeReference] public INode left;
   [SerializeReference] public INode right;
}

[Serializable]
class SubNode : RootNode
{
   [SerializeReference] INode parent;
}

[Serializable]
class LeafNode : INode
{
   [SerializeReference] public INode parent;
}


class SomeThing : ScriptableObject
{
    [SerializeReference]
    public List<RootNode>  m_Trees;
}
44 Likes

This is very cool!

1 Like

Sweet, sweet heavens. @jasonm_unity3d that is huge. Is there going to be more information on this, perhaps posted in the blog? It seems to me that an update to the Serialization in Unity blog entry would be super handy. (This assumes the manual will get its own update, of course.)

6 Likes

A blog post is in the works, but I'm not in the loop as far as the eta.
The API documentation is ready but has yet to be published, docs team is looking into as we speak.

Note that [SerializedReference] does come with a slight performance hit, hard to measure as it depends on context. But it's there, so it is not advised for use for the general cases (where in general, performance considerations trump just about everything else).

But for those rare cases where the implementation/maintenance complexity does trump performance or it's a non issue as the final objects are not that big so they won't have measurable impact even if they are slower to deserialize, then this feature fits the bill.

8 Likes

It's... Beautiful

4544590--421621--tumblr_mzcos91INP1qd2l0fo1_250.gif

24 Likes

[quote=“jasonm_unity3d”, post:5, topic: 743433]
Note that [SerializedReference] does come with a slight performance hit, hard to measure as it depends on context. But it’s there, so it is not advised for use for the general cases (where in general, performance considerations trump just about everything else).
[/quote]
Can you quantify “performance hit” in some way?

We’ll have to benchmark our own code, of course, in the long run. We already serialize references with Serialization Callback shenanigans. My fingers are crossed that the new built-in approach is at least as fast as our custom solution…

2 Likes

the extra overhead is impacted by how many types are involved and how many objects.
In some scenarios, you I have seen slight speed ups (large graphs, small nodes), in other scenarios i've seen slowdown: Many small ScriptableObjects with one small field that is serialized by reference.

The nature of the data model being serialized has to much of an impact to be able to say: "you can expect x% slow down, y% speed up".

Purely anecdotally, one small lists (~20 items) with 2-3 types involved and 4-5 fields per type, one test run that I remember was .5% slower. But again, that was a synthetic test case and doesn't mean much. Will be very interesting to hear actual reports come back from our users for real world usage...

7 Likes

Will this serialize dictionaries, mainly because that's an old request and we can finally put it to bed if this solves it?

Sweet Lord, at last!
runs in circles in tears of happiness

5 Likes

Holy shit. Does that mean we'll be able to serialize interfaces? I'll finally be able to use interfaces without feeling like Unity is fighting me by not letting me reference them in the inspector.

4 Likes

Nice!
Does this means we will also get a way to get System.Object reference from SerializedProperty?
pretty please :smile:

Wow! I can't believe this isn't mentioned in https://discussions.unity.com/t/743421

Serialisation support for references and polymorphic data? Are you kidding? It is always such a massive pain to write complex tools for unity because you need to restructure your data to work around Unity's serializer. This will make things so much easier.

9 Likes

After some messing about, it seems very flexible so long as you are exclusively using custom classes. Also, (kind of expected) the inspector gets really weird really quickly and is frequently causes crashes when editing values of data that has been tagged as SerialiseReference. (It really likes crashing the editor!) The data does serialize and deserialize correctly - it's just that the rendering is a little broken in the inspector.

If you need complex data structures like this that support reference serialization then you are probably putting together something relatively complex, so you will probably be manipulating this data with a custom editor of some sort...so its not such a big deal! In my test, I was able to 'poke' the data on my monobehaviour using 'ContextMenu' methods and verify that references are maintained as expected.

Overall, very very very cool! It is a shame that we still can't reference UnityEngine.Object's via their interfaces though..! But at this point I'll take what I can get...!

1 Like

ouch. this is exactly what I wanted it to do (being able to code against interfaces and the implementation can be either a MonoBehaviour or a ScriptableObject…)

1 Like

Hell is officially affected by climate change!

6 Likes
  • API link: https://docs.unity3d.com/2019.3/Documentation/ScriptReference/SerializeReference.html

  • UnityEngine.Object cannot be stored in fields with the [SerializeReference] attribute, so the interface restriction remains. I don't expect that limitation to ever be lifted as it's actually a fundamental design limitation of who the serialization system is leveraged all over the unity code base.

  • Unfortunately no, Dictionary serialization is still not supported.

  • Does this means we will also get a way to get System.Object reference from SerializedProperty?
    Not sure what is ment by that but, you can have [SerializeReference] List<System.Object> data;. You can then access it through serialziedObject/Property and fetch the fields from the instance's class not just the System.Object class. If that makes sense?

  • Does that mean we'll be able to serialize interfaces?
    Yes, but will reject objects that are descendants of UnityEngine.Object.

And, if you happy about this feature: Please, please, please, be diligent in reporting any and all bugs through the editor as this feature was very invasive and will need love to stabilize and be rock solid.

cheers
-J

21 Likes

[quote=“jasonm_unity3d”, post:17, topic: 743433]

I have wondered for a while, whether there should be some way to apply an attribute to a collection, rather than the elements. Ever since the change was made to apply attributes to the elements of the collection, there has been no way to apply attributes to a collection itself, requiring custom inspectors to override collection drawing behaviour, which was annoying but not a showstopper.

Now that there’s an attribute that fundamentally alters serialization to this extent, it sounds like this should be looked at.

Granted, if I must serialise a collection by internal reference I could wrap it in a class, but it would be great not to have to.

good point! I added it. And I will add hyperlinks as soon as I get some preliminary documentation.

2 Likes

The initial proposal for Serializing References did support that specific use case, but it was later rejected during peer review: was deemed a ‘nice to have’ but not common enough to be worth the added dev time & complexity.

If enough people ask for it, who knows…

2 Likes