Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Storing a list of scripts in a scriptable object

Discussion in 'Scripting' started by Winzlo, May 31, 2022.

  1. Winzlo

    Winzlo

    Joined:
    Jun 17, 2013
    Posts:
    4
    Hi, I have a bunch of scriptable objects that all need to interact with this system, but some objects require different "rules" (conditions that must be met) in order to execute the functionality. So I created an abstract rules class that I can derive from to create as many rules scripts as I want and then I added a List<BaseAbstractClass> to the scriptable object code. Unfortunately this leads to the list not appearing in the inspector unless I derive the base class from monobehaviour and even then it does not let me drag the rules scripts into the scriptable object inspector. I have no idea what to do in regards to this.
     
  2. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,303
    You can use [SerializeReference] to properly store interfaces/abstract implementations
    Edit: Yeah, actually Drag and Drop of a type won't work

    You can choose/add those implementations from the inspector though, with an implementations dropdown list and an add button or something, you will have to do that on your own, because unity doesn't provide this right now.


    These will be useful resources if that's what you want:

    I haven't tried this yet, but it supposedly provides a way to list and add specific implementations automatically for your inspectors
    https://forum.unity.com/threads/serializereference-genericserializedreferenceinspectorui.813366/

    This is how you would implement it yourself for a specific type. But in your case, instead of fetching implementations of an interface, you would fetch derived classes of an abstract class.
    https://medium.com/@trepala.aleksander/serializereference-in-unity-b4ee10274f48
     
    Last edited: Jun 1, 2022
  3. Winzlo

    Winzlo

    Joined:
    Jun 17, 2013
    Posts:
    4
    I don't really understand which part I am supposed to put the [SerializeReference] tag is it on the base class, derived class or the List field?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,964
    You can't just drag a script into a field in the editor. You drag a specific instance of a script living on a GameObject into a specific instance of that reference type.

    You also can never drag references from your scene (which are very transient) into an asset on disk, for obvious reasons: scenes come and go every time you press PLAY, whereas assets on disk are forever.

    So if you have a prefab on disk with an instance of a script on it, you may drag that prefab into the ScriptableObject's field of the correct type (eg, that script, or else GameObject).

    I use this in my GameObjectCollection class as a way to group prefabs together, like
    LargeRocks
    or
    SmallTrees
    or
    ZombieVariations
    for instance.

    https://gist.github.com/kurtdekker/68b3fd9d4202888b4afc17b32eed6790

    But again, you could never drag something from the scene into there.
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    6,015
    You'd use SerializeReference on the list of the base class.

    Code (CSharp):
    1. [SerializeReference]
    2. private List<YourBaseClass> baseClassList = new List<YourBaseClass>();
    As mentioned above this requires custom inspectors or addons from the package store to be usable though.

    EDIT: Both base class and derived classes also need to be decorated with [System.Serializable] too.