Prefab creation with variant materials (in editor script)

I am trying to develop some Editor-based PCG tools. I call PrefabUtility.InstantiatePrefab to create a new instance as follows:

            GameObject newGameObject = UnityEditor.PrefabUtility.InstantiatePrefab(prefab) as GameObject;

Once the new game object is created, I want to modify the color of the material. I have tried the three options below and they all have problems (Note, this is by clicking a button in the editor - NOT runtime or during Play). I have 3 possible work-arounds (below), but wanted to see if I am doing something wrong.

        public async Task ApplyAsync(GameObject prefab)
        {
            Renderer renderer = prefab.GetComponent<Renderer>();
            if(renderer != null)
            {
                Color newColor = randomColor.GetNext();
                // Option 1: Editor give error - use sharedMaterial. Prefab materials are broken when dragged into folder.
                //renderer.material.color = newColor;
                // Option 2: All prefabs have the same color.
                //renderer.sharedMaterial.color = newColor;
                // Option 1: Prefab materials are broken when dragged into folder. New materials are lost.
                var newMaterial = new Material(renderer.sharedMaterial);
                newMaterial.SetColor("_Color", newColor);
                renderer.material = newMaterial;
            }
            await Task.CompletedTask;
        }

Hopefully someone has an easy fix to this problem. I have searched quite a bit and cannot find a solution. Some possible work-arounds:

  • Explicitly Save the materials (even duplicates) somehow. I am looking at 1000’s of instances.

  • Use a predefined Material palette and set the material to that.

  • Add a script to the prefab that will change the color at runtime (will not be able to see the results in the editor at design time though).

I am having this issue as well. The API seems way too ambiguous and complicated to figure out how this should be done.