Cannot serialize a custom class in inspector

Hello,

I’m implanting some voronoi script from github. I have this class :

// Copyright 2016 afuzzyllama. All Rights Reserved.
using System.Collections.Generic;
using UnityEngine;

namespace PixelsForGlory.ComputationalSystem
{
    /// <summary>
    /// Stores final information about a site that is returned in GenerateEdges
    /// </summary>
    public class VoronoiDiagramGeneratedSite<T> where T : new()
    {
        public int Index;
        public T SiteData;
        public Vector2 Coordinate;
        public Vector2 Centroid;
        public List<VoronoiDiagramGeneratedEdge> Edges;
        public List<Vector2> Vertices;
        public List<int> NeighborSites;

        public bool IsCorner;
        public bool IsEdge;

        public VoronoiDiagramGeneratedSite(int index, Vector2 coordinate, Vector2 centroid, T siteData, bool isCorner, bool isEdge)
        {
            Index = index;
            Coordinate = coordinate;
            Centroid = centroid;
            SiteData = siteData;
            IsCorner = isCorner;
            IsEdge = isEdge;
            Edges = new List<VoronoiDiagramGeneratedEdge>();
            Vertices = new List<Vector2>();
            NeighborSites = new List<int>();
        }
    }
}

I can to serialize this class on my inspector to see what’s inside. Can I do that ? Trying with that :

using PixelsForGlory.VoronoiDiagram;

public class TestScript : MonoBehaviour
{

    //Error here... Don't know how to set up this class.
    private VoronoiDiagramGeneratedSite<T> test = new VoronoiDiagramGeneratedSite<T>();
    

    // Start is called before the first frame update
    private void Start()
    {
    }
}

Pretty sure the Unity editor / inspector can only work with concrete classes, not generics.

You might be able to wrap it with another serializable container class, but even that I’m not sure about when you’re doing <T> stuff

First off, you haven’t even marked your class as [Serializable] so that immediately makes Unity unable to serialize it.

Second, You would need to actually provide a concrete type parameter for T, it can’t just guess which type you want.

1 Like

That was the case for the longest time. However since 2020.1 it seems that has changed . Though you still need to actually fill in an actual type when using a generic class :slight_smile:

1 Like

So I can’t use it because this class is generic ? I understand now. First time seeing this quite hard to understand…

Read the whole thread again - that’s not the conclusion at all.

This is new to me obviously… so you are saying this would work in the inspector:

public VoronoiDiagramGeneratedSite<Foo> VDGS;

where the class is marked [Serializable] and class Foo meets the where limitations?

Sure would. You’re living in the past a bit Kurt. ;p

2 Likes

To be fair, I actually haven’t tested this myself, though I heard about generic supports here and there. However I’m curious what the limits of the generics support currently is. I’m pretty sure too wild generic constructs would blow up at some point. So I would not expect to see support for Foo<Bar<List<int>,string[ ]>>, though who knows how well they implemented the generics support :slight_smile:

It should work so long as you don’t go outside of the usual limitations of Unity’s serialisation.

So something like this wouldn’t work:

[System.Serializable]
public class Foo<T> where T : class, new()
{
    public List<T> FooList = new();
}

public Foo<List<GameObject>> SomeFoo = new(); //no dice

As List<List> isn’t something Unity can handle.

Where as this:

[System.Serializable]
public class Foo<T0, T1>
    where T0 : class, new()
    where T1 : class
{
    public T0 FooZero = new();
 
    public T1 FooOne;
}

public Foo<List<GameObject>, string[]> SomeFoo = new();

Should be okay, if I haven’t got my constraints messed up (written in notepad++).

I have reported this post on the grounds of cruelty to compilers.

1 Like

Generic class is from a package on github. Is it a risk to update file directly downloaded from packages ?

There is an hash on their name file like this :

Library/PackageCache/com.pixelsforglory.voronoidiagram@e9deee9464/Runtime/VoronoiDiagramVertex.cs)

I don’t know if it’s a checksum or else. If this is the case I guess I must fork it.

What sort of risk do you anticipate? I assume you’re not planning to update the repository that you found it on or anything, right?

2 Likes

No just on my own project.

I’m still just curious about what sort of risk you are anticipating in editing this code. I’m not real familiar with git-hub-based unity packages but I assume the package manager simply downloads the files and puts them in a folder. I imagine that if you somehow mess-up the package, you could just re-install it too.

I guess one problem I can think of is if you later wanted to replace the Voronoi package file with a newer version (Like if the author adds features or fixes bugs) then you’ll need to copy your changes from the old file to the newer file. If you add the file to your own source control you could merge your changes back in, but we’re only talking about a very minor change at this point.

If you’re really worried about it, you could always write a wrapper class in your own project. but simply writing [Serializable] is far easier, so I’d try that first.

1 Like