Unity generates unwanted prefab overrides when making a new prefab

I have such object:

public class MDDObjectRenderer : MonoBehaviour
{
    [SerializeField]
    public GameObject targetObject;
  
    [SerializeField]
    public List< MDDPositions > animations = new List< MDDPositions >();
}

And a sub object:

[Serializable]
public class MDDPositions : ScriptableObject
{
   [SerializeField]
   public string mddFilePath;
}

And I have one instance in my scene, with one MDDPositions scriptable object inside the list.


I can switch to another scene or even close Unity editor - when I come back to my scene I can see my object saved properly, with one element in the animations list

Now I drag this object into assets library to make it a prefab.


As you can see, animations list and the MDDPositions object in that list are still there, but blue left edge and bold font indicate these are prefab overrides.

So I look at the prefab:


And as you can see, prefab asset contains a list wth one null element.

When I open the prefab asset and change contents of that list, the only thing that is actually being saved in the prefab asset is the list size - contents will always be null.

So what’s the proper way of creating a list of SerializableObjects that can be saved inside a prefab?
Do I need to mark my SerializableObject with some specific tags?
Or maybe I should not be using SerializableObject inside a prefab?

I will probably get rid of the list and turn my MDDPositions from ScriptableObject to Component - I assume this will work, but I would still prefer to have one component with an internal list.

Hi @KSzczech

You have two options, either save the ScriptableObjects into separate assets (or just one with subassets) before saving the Prefab:

AssetDatabase.CreateAsset(mddPositionsInstance, "Assets/pos.asset");
AssetDatabase.AddObjectToAsset(otherMDDPositionsInstance, mddPositionsInstance);

// Add more if required

PrefabUtility.SaveAsPrefabAssetAndConnect(prefabInstance, "Assets/MyPrefab.prefab");

or you add the ScriptableObject to the Prefab asset after creating the Prefab:

var prefabAsset = PrefabUtility.SaveAsPrefabAssetAndConnect(prefabInstance, "Assets/MyPrefab.prefab");
AssetDatabase.AddObjectToAsset(mddPosition, prefabAsset);

// Add more if required

PrefabUtility.ApplyPrefabInstance(prefabInstance);

Notice the Apply at the end to update the references in the Prefab asset.

1 Like

Thanks man!

I’ve already converted my solution to just adding MDDPositions as additional components (MonoBehaviours) and it works, but it’s far from ideal.

My goal is to have multiple MDDObjectRenderer components on one game object, each one maintaining its own list of MDDPositions, so going with ScriptableObjects is my target solution.

Now you made it possible for me :slight_smile:
Have a great day!