Best way to serialize a big array of a class

What is the best way of serializing a big array of a class, that will be loaded when the game starts?

Right now i’m doing this, storing everything in a scriptable object.

public class MeshData : ScriptableObject, ISerializationCallbackReceiver
{
    [SerializeField]
    [HideInInspector]
    internal Tiles[] tiles;

    [SerializeField]
    [HideInInspector]
    internal Vertex[] vertices;

    [SerializeField]
    [HideInInspector]
    internal Triangle[] triangles;

    public void OnBeforeSerialize()
    {
        if (triangles != null && Ready)
        {
            _serializing = true;
            SerializeTriangles();
            _serializing = false;
         }
     }

    public void OnAfterDeserialize()
    {
        _serializing = true;
        DeserializeTriangles();
        _serializing = false;
    }
}

It works as expected, tiles and vertices have only serializable ints and floats and they dont need a custom serialization, but triangles have pointers to vertex and to other triangles, so they need that serialization step. It works.

Only problem is, it takes a few seconds to load every time the game starts. Array sizes are of about 256x256 = 65536 for the tiles, which hold a float, a int and a bool each, and about 500 to 1000 vertices, and 1000 to 2000 triangles. Vertices have only 2 floats each. Triangles carry a lot of data, something like 20 to 30 floats or ints each.

  1. Should i worry about this start loading time? Is it normal? It takes up to 5 seconds.
  2. Is there a better way of storing these other than in a scriptable object?
  3. When using scriptable objects, should they be stored in a prefab? Or is it fine to leave them as a field on a object that is on the hierarchy. (See screenshot, that is all and the only reference there is to the scriptable object. no prefabs created, no nothing. The mesh class has a meshData variable which gets assigned to the MeshData.

57028-meshdata.jpg

I think i found the answer i was looking for using RGFloat textures for the 256x256 array. I might end up storing the vertices and maybe even the triangles if possible in textures as well.
I haven’t tested this solution enough, but it seems to be good enough this far.

Should i worry about this start loading time? Is it normal? It takes up to 5 seconds.

If loading takes that long and you don’t need it at startup, you could consider loading it asynchronously. If you need it at startup, try exporting your content into a file which you load and parse manually. I don’t know if you’ll get any performance boost but it can be worth a shot. If you need it at startup but either method is too slow, figure out if you can compress the contents. Etc.

Is there a better way of storing these other than in a scriptable object?

If you can represent the mesh data as a tilemap, it may be better to consume CPU to build the triangles at load rather than waiting for the file system to deliver the data. Also if it’s a tilemap like in most games, a lot of the tiles will be similar and can be RLE compressed for example.

When using scriptable objects, should they be stored in a prefab?

It is up to you how you want to store them. You can have a reference to it in your scene, or create an asset file or add it to an existing asset, such as a prefab.

Note that if you have it attached to an object in the scene, you’ll lose the scriptable object if you accidentally remove the game object that had the reference to it. Why? Because it is deemed unused and will be cleared as part of a usual Resources.UnloadUnusedAssets. To put it in other words, scriptable objects that are referenced by the scene game objects will be serialized in the scene, unless the scriptable object is an asset. In that case it just store a reference to the asset.