Hello,
I have the following ScriptableObject:
using System;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "Materials Override", menuName = "MyMenu/Materials Override")]
public class MaterialsOverride : ScriptableObject
{
public MaterialAndGameObjects[] MaterialsAndGameObjects;
[Serializable]
public class MaterialAndGameObjects
{
public List<Material> OverrideMaterial;
public List<GameObject> GameObjects;
}
}
I create an instance of it, and I can see the lists being correctly exposed in the editor:

Now, for testing, I create an empty GameObject in the hierarchy. I try to drag and drop it onto the âGame Objectsâ list of the ScriptableObject, but I canât (little âforbiddenâ sign shows up).
I can drag and drop some prefabs that are located in my Assets, but nothing from my hierarchy.
Can you help me understand why?
Thanks a lot!
A general rule of Unity is: Scene objects can reference assets, but assets canât reference scene objects. This is true not just for scriptable objects.
Reason being that scenes are only ever temporary constructs initially built from itâs scene asset data.
2 Likes
A scriptable object that is stored as asset can only reference other assets. Assets live in the project / in the asset database and are always âloadedâ when your game starts or is loaded. Objects in a scene of course lives in that scene. When the scene is not loaded, the object simply does not exist anywhere.
So an asset can never reference an object in a scene. For that matter itâs irrelevant what kind of asset. So a prefab also canât reference something that lives in a scene. Though the opposite is always possible. So objects in a scene can reference any asset that lives in the project since those are always available.
2 Likes
Ok, that makes sense indeed!
Then what would be the way to achieve what I want?
Iâd like to have the opportunity to create such lists in the editor, so that in play mode I know which GameObjects have which âOverride Materialsâ.
I guess one way to go would be to make prefabs out of the GameObjects I want to list, but I feel that wouldnât be my preferred option.
The (only?) other option would be to have these lists in a Monobehaviour assigned to some GameObject?
Thanks a lot!
I think a two-pronged approach will work here.
One, a scriptable object that holds all the materials used for overrides. And two, a component that references this SO and also the game objects you care about.
2 Likes