Add default ScriptableObjects to List of ScriptableObjects of another ScriptableObject upon creation

I have an Ability class that derives from ScriptableObject, and this class has a List of Tags.

[CreateAssetMenu]
public class Ability : ScriptableObject
{
    [SerializeField] private List<Tag> Tags = new();
}

Tag is also a class that derives from ScriptableObject.

[CreateAssetMenu]
public class Tag : ScriptableObject
{}

And in my project, I've created a Tag ScriptableObject asset called "Projectile" through the asset menu.

I'm looking for ways to avoid repetitive dragging in dropping in the Inspector whenever I create a ScriptableObject asset. My question is, is it possible to add the Projectile Tag asset as a default item of "List Tags" whenever I create an Ability ScriptableObject asset in my project files? If it is possible, how may I do that?

Thank you for your time. :)

Select the actual scriptable object script. From there you can assign the default values. Newly instantiated scriptable objects will have those default values

This only works in editor

2 Likes


That's actually a very important point. The Default References you can setup in the inspector of a script asset only affect instances created inside the editor. It's a pure editor feature. Adding default references when you already have created instances won't do anything to those existing instances. The Default References only affect newly created objects inside the editor. So it's like a template.

1 Like

Thank you, venediklee and Bunny83.

I was able to set some default values for some variables through the script itself, like my Transform Variable.

But unfortunately when it comes to Lists (and apparently some other variables) it seems that they can't be exposed in the inspector.

Here is my related code. ProjectileAbility still derives from ScriptableObject through Ability. Only the first two variables are exposed in the Inspector when the script itself is selected.

public class ProjectileAbility : Ability
{
    [Header("Projectile Ability Properties")]
    [SerializeField] private GameObject projectileToSpawnPrefab;
    [SerializeField] private TransformVariable spawnPoint;

    [Header("Projectile Properties")]

    [SerializeField] private FloatReference baseDamage;
    [SerializeField] private float baseTravelSpeed = 1000;
    [SerializeField] private float baseLifetime = 2;

    [Space(5)]

    [SerializeField] private List<Tag> projectileTags = new();
    [SerializeField] private List<ModifierData> abilityModifiers = new();
}


Yes, of course Lists don't work. Only direct references to UnityEngine.Objects derived types can be setup here. Also such references can only reference assets in the project, not things inside a scene, of course.

What you may want to do here instead is using a ScriptableObject as a data container that holds the list and you just reference that scriptable object. Using scriptable objects like that is actually quite common.

Of course every unique combination of List items would need to be stored as a separate SO. However if this is needed quite often, you may use a hybrid solution where each object still has it's own lists, but also the scriptable object as basis. So the class would check both, it's own list and the linked SO list, or you could create some editor code which would actually copy the list from the SO to the object's own list when it's created / Reset. (So inside the Reset method? Never tried that, might not work or may require a delayedCall inside the editor).

2 Likes

In that case, I'd recommend implementing a custom asset post processor for your projectiles etc., this way you can even add the tag to the previously created scriptableobjects(you'll just have to reimport them). These also only work in editor

They are a bit more difficult to work with at the start because you'll need to know a bit more editor programming but you'll be fine, just check the example scripts on each OnPostProcess... method

PS: since the asset post processor's can be hard to deal with, please commit any changes of your project before trying anything

2 Likes

Thank you so much for you replies again, venediklee and Bunny83. This has been helpful. You've pointed me to other directions I can try out. Thank you for your time and take care.

I'll try to update this thread once I settle on a solution.

1 Like