Serializing references
Beyond the same basics that apply to serializing everything else, there are some extra rules when serializing references.
Persistent objects for everyone
If you have a MonoBehaviour
like this:
public class MyData : MonoBehaviour, ISaveable
{
[SaveThis] GameObject otherGO;
}
In order for the reference to be properly serialized, you need to add a PersistentObject
to both this object and the referenced one. This is required because only objects with a PersistentObject
component have a UID, and UIDs are how references are serialized. This also applies to referencing a Component
, like this:
public class MyData : MonoBehaviour, ISaveable
{
[SaveThis] Transform otherTransform;
[SaveThis] MB otherMonoBehaviour;
}
In the case above, the custom MonoBehaviour
class MB does not need to implement ISaveable
. The only important thing is that it is attached to a GameObject
that has a PersistentObject
.
Again all of this is necesary because the only objects with a UID are those with a PersistentObject
.
Wait... the only ones?
ScriptableObjects
You can reference ScriptableObjects
too! But wait, a ScriptableObject
can't have Components
... so how does it get a UID? Well, like this:
public class SO : SerializableScriptableObject{
}
The base class SerializableScriptableObject
does everything you need, so you just need to inherit from it. If you already have a complex inheritance tree with ropes and pulleys, and are despairing over not being able to use this, may I remind you that every tree has a root. If the base class derives from SerializableScriptableObject
, then they all do. And thus, they can all be referenced. Convenient!
If you are using a one-manager-per-scene setup, the UIDs of ScriptableObject
instances will be stored in all of them (it gets stored the first time you open the scene after creating the ScriptableObject
). This is fine, and actually desirable, as it means you can reference it from anywhere. However, when you delete the ScriptableObject
, its UID will only be removed from the manager which is currently open.
This won't break the system or anything, but if for some reason you are creating and deleting lots of ScriptableObjects
, it will create lots of useless entries in every UID manager, adding (a bit) to the memory footprint of the application for no good reason at all.
That's mainly why the one-manager-in-its-own-scene setup is preferable.
References inside a nested class
See Nesting classes. The TL;DR is this works as long as all the classes in the chain are marked as ISaveable.