Does Instantiate() ScriptableObject clone the sub-assets as well?

I just discovered AssetDatabase.AddObjectToAsset() and I am able to nest one ScriptableObject under another parent ScriptableObject, my understanding is that the whole thing becomes one .asset.

  • Suppose I have 3 ScriptableObjects, class names ASO, BSO, CSO,
  • and in the Editor, I create 3 assets A, B, C respectively. A, B, and C each referencing each other in public serialized variables.
  • Then in the Editor, I use AddObjectToAsset() to nest B and C under A, so that at the top level, there is only A.
  • A, B and C, all still maintains references to each other in Editor.

Now, I have a MB, and at design time, I assign the parent SO to the MB as such

public class Example : MonoBehaviour {
   [SerializeField] ASO config;

   void Start() {
           // clone ASO, I expect to clone all A, B, C and keep their references to the newly cloned instances
           config = Instantiate(config);
   }
}

Question: And then at runtime, if I clone the ScriptableObject by calling Instantiate on the parent SO. Can I be certain that the entire tree is cloned including the references to each other? OR, do I need to clone each of them individually and re-reference the newly cloned SOs?

This is super trivial to check for yourself. I would of course expect the references to be deserialized.

But this begs the question: what do you gain by doing so? A could just as well have references to B and C where they aren‘t ScriptableObject instances but merely C# classes or structs marked with the Serializable attribute. This would actually be easier to implement and incur less maintenance overhead compared to nested assets.

Don‘t make a circular dependency. A may have fields for B and C and in OnEnable A may call a method on B and C to assign itself as the parent object, which B and C assign to a non-serialized field.

1 Like

That’s what I suspect too, I just wanted to see if smart people here may recommend other methods that I not yet discovered. Of course no circular reference, I just presenting worst case scenario. The reason why there are so many ScriptableObject is because various editing tools and frameworks, XNode, may rely on creating many ScriptableObjects.

Still should just test it on your end to be sure. Wouldn’t take long.

I’d rather be using plain C# objects however, and use [SerializeReference] if I needed any non-linear references.

1 Like

Note to self: I managed to avoid circular references so I have not checked this case thoroughly.
TODO: Check this case and report back here.