I’ve run into a problem setting the sharedMaterial on renderers and I’m stumped. I’d really appreciate a sanity check. A simplified version of what’s happening is presented below.
First, I have an EditorWindow script that iterates over some renderers for the selected game objects and replaces their sharedMaterial array:
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using System.IO;
public class DuplicateMaterials : EditorWindow
{
[MenuItem("Window/DuplicateMaterials")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(DuplicateMaterials));
}
public void OnGUI()
{
if (GUILayout.Button("Duplicate materials"))
Execute();
}
private void Execute()
{
Transform[] transforms = Selection.GetTransforms(SelectionMode.TopLevel|SelectionMode.Editable|SelectionMode.ExcludePrefab);
if (transforms == null || transforms.Length == 0)
return;
Shader defaultShader = Shader.Find("Sprites/Default");
foreach (Transform transform in transforms)
{
GameObject gameObject = transform.gameObject;
SpriteRenderer[] renderers = gameObject.GetComponentsInChildren<SpriteRenderer>();
for (int i=0; i<renderers.Length; ++i)
{
SpriteRenderer renderer = renderers[i];
string assetPath = "Assets/stub " + gameObject.name + ".mat";
Material material = new Material(defaultShader);
AssetDatabase.CreateAsset(material, assetPath);
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
Material[] stub = renderer.sharedMaterials;
stub[0] = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
renderer.sharedMaterials = stub;
EditorUtility.SetDirty(renderer);
}
EditorUtility.SetDirty(gameObject);
}
}
}
The code works when selecting single game objects. When selecting multiple objects, however, the materials set in this fashion are not sticky - unselecting and doing a multiselect of the game objects in the Hierarchy will end up replacing all the materials with one of the generated materials:

I’d appreciate any insight any reader can offer, I’m out of ideas for the moment.