Polymorphic Scriptable Object

Everyone says ScriptableObjects can be used for inheritance.

  1. I create the scriptable object with Factory:
    ScriptableObjectFactory/Assets/Editor at master · liortal53/ScriptableObjectFactory · GitHub

The asset is successfully saved on project.

  1. I assign the scriptable object to my monobehavior.

  2. Everything works fine.

  3. I hit play mode.

  4. Everything works fine.

  5. i exit play mode.

  6. Everything works fine.

  7. i switch to another scene or close unity editor with X button at top right.

  8. Scriptable objects get the message :

“The associated scripts can not be loaded …”

And monobehavior link shows : None (MyClass)

I am frustrated, why do my scriptable objects go missing?

Ps. I am not willing to remove OOP concepts, i rather switch to another game engine.

Edit / Progress: Still havent solved the problem but …

If in step 1 i use attribute [CreateAssetMenu],
The asset is still saved in project like before.
However the problem in step 9 gets fixed The monobehavior keeps the correct links to those assets and works perfectly. But now occurs problem 10.

  1. Unrefered scriptableobjects created by [CreateAssetMenu] become missing, cannot be used by the monobehavior, they still consume disk space in my project.

So to conclude every scriptableobject created by [CreateAssetMenu] is “Safe” if refered by another monobehavior, but those unrefered get deleted, even thought it persists in the projects and takes up space.

Code:

   [Serializable]
   public class MyCameraType : ScriptableObject
   {
      public virtual void Init(MonoBehaviour mono) {}
   }

   [Serializable]
   public class TopDownCamera : MyCameraType
   {
      public override void Init(MonoBehaviour mono)
      {
         Transform camera = Camera.main.transform;
         camera.eulerAngles = new Vector3(90, 0, 0);
         camera.position = new Vector3(0, 30, 0);
      }
   }

   [Serializable]
   public class ThirdPersonCamera : MyCameraType
   {
      public override void Init(MonoBehaviour mono)
      {
         Transform camera = Camera.main.transform;
         camera.eulerAngles = new Vector3(0, 0, 0);
         camera.position = new Vector3(0, 10, -20);
      }
   }

Edit: Revision 1: Applied Bunny83 code changes. Problem Still Persists.

Edit: Solution: Placing each script in a seperate file, fixed the problem.

I doubt that this is actually related to inheritance. Apart from your lost reference problem your “Init” method is not declared as virtual and not overridden in the derived classes, so all your OOP is pointless because you actually “hide” the Init method.

Assigning a concrete instance to a base class variable (of type MyCameraType) should store the reference just fine, however calling Init on the base class won’t call the derived Init as it’s not a virtual method. I’m not sure if that’s just a typo here on UA or if this is your actual code.

Also ScriptableObjects don’t need to be marked as “Serializable” as they are always serializable. In your case it would make more sense to make your Init method inside your MyCameraType class abstract. Abstract methods are also virtual but don’t have a body themselfs and require a derived class to override it. Abstract classes also can’t be instantiated.

public abstract class MyCameraType : ScriptableObject
{
    public abstract void Init(MonoBehaviour mono) {}
}

public class TopDownCamera : MyCameraType
{
    public override void Init(MonoBehaviour mono)
    {
        Transform camera = Camera.main.transform;
        camera.eulerAngles = new Vector3(90, 0, 0);
        camera.position = new Vector3(0, 30, 0);
    }
}

Turns out, the reason unity destroyed the scriptableobjects and created missing references had nothing to do with serialisation, nor the way the assets where created.

The problem was : “A class must have the same name as its physical file on disk”
A problem that neither c# nor unity complains about, and happily allows you to store more than one class in a file.

solution: Placing each script in a seperate file, fixed the problem.