Hi there, I know the basics of SO and already used them, but one thing is unclear to me.
Let’s say we got a class “CarTemplate” which is the template for a couple different car scriptable objects. Obviously they can store data of variables. Also, there is the class “Engine”, which contains an array of “MaschineParts” objects (which is a class themself). The CarTemplate now got an object “Engine” and this got the array of maschinePart-objects.
If I create a car scriptable object, will it also save the attributes of the engine object and there the objects of maschineParts? Or do I have to create a scriptable object for each maschinePart and engine?
First of all, yes it would save the data you assigned via the inspector.
However, you would not be able to just re-use an engine in another car, unless the engine is an SO type. The same applies for the MachineParts. If they’re not an SO type, you’ll need to populate each engine. You can choose any combination depending on your needs. Anything is possible:
Car SO, Engine SO, Part SO
Car SO, Engine SO, Part
Car SO, Engine, Part SO
Car SO, Engine, Part
The most “modular” when working in the inspector is the first one, as you’ll be able to change a part in one place and all engines that use it would refer to that one instance.
But perhaps it’s enough when you configure engines and drag&drop those.
There’s likely going to be one problem though. If MachineParts is meant to be a base class for more specific parts and is NOT an SO, you’ll run into problems when you want to support polymorphism. As of Unity 2019.3 or something, there’s an additional attribute for serializing references, but this comes with some limitations as well.
If you need further assistance, you should include some more details about how you want to configure engines and all the parts.
In fact, the car was just an example. Actually, I’m about to rewrite a neural network that already exists. I just wanted to make it storable and improve the code quality (currently everything happens in 2 scripts).
To clarify what my goal is: Blobs are small creatures that are searching food to maximize their fitness. They should learn to walk towards food. In order to save the progress they made, I want to store the neural network as scriptable object.
The NeuralNetworkTemplate is the template for a scriptable object. It contains all layers. Each Layer contains its neurons and each Neuron contains its activation, bias and the float weights coming from the previous layer. One neural network scritable object later becomes the brain of multiple blobs.
Just created this class diagramm (I’m not used to it, don’t judge if I picked the wrong type of arrow ^^). As you can see, I want to use polymophism. The SO should be able to save an array of “Layers”, but there are 3 different layer types. What I did not understood was, what problem may occur with this?
Oh wait, when you talked about whether they save or not in the original post, you were referring to saving at runtime? That won’t work with scriptable objects. Changes to SOs at runtime (in builds) won’t be persistent, as these changes only exist in memory.
But you can still save them and export them as JSON, I am just not sure if this will happen recursively for references to ScriptableObjects inside ScriptableObjects, but it should work if you use one scriptableObject as container for c# classes. ^^
Each tutorial claimed that SO can be adjusted at runtime or does this not apply to the references they hold? In my case: the array of layers, that contain an array of neurons.
I just made an example project, using the car-example. Each car (SO) has a engine and each engine has an array of machineParts, which have a float variable themselfs. Using [System.Serializable] before each class that is supposed to be storabel. This worked well. I have not tried to build this though.
You can change the values at runtime, but the changes will not be persistent.
You could do what @John_Leorid suggested, Unity’s json utility follows almost the same rules as the normal serialization system that’s built-in. However, if you have references to other SOs, they’ll be serialized by instanceID, so I wouldn’t say that’s a reliable way to persist changes between multiple sessions when you deal with SOs referencing other SOs.
But you can still separate the actual data from the SOs if you need changes to persist. When you use this approach, you’d only need to load the data and populate it at start or on demand.
That works fine in the editor. When can change SO-Assets in plaly-mode, you’ll keep the changes, because you’re changing the actual asset. However, that won’t work in the build.