Skip to content

Instantly share code, notes, and snippets.

@SorraTheOrc
Last active April 20, 2025 22:33
Show Gist options
  • Save SorraTheOrc/251c49c435cc52dff3553daba5d9fa12 to your computer and use it in GitHub Desktop.
Save SorraTheOrc/251c49c435cc52dff3553daba5d9fa12 to your computer and use it in GitHub Desktop.
Apply a material to all models in a folder.
using UnityEngine;
using UnityEditor;
namespace WizardsCode.Models {
/// <summary>
/// A custom Unity Editor window that allows users to find and process 3D models in a specified folder,
/// applying a selected material to all renderers within the models.
///
/// This is useful when an asset is published in which the models do not have materials applied. For things
/// like terrain details this is problematic and since there are usually many models for details the manual
/// process of applying the material can be tedious. This editor window automates that process in a single click.
///
/// However, it is currently limited to models that are in the same folder as the material. That is, it will only
/// truly be useful when the models are using a material atlas.
/// </summary>
public class ModelMaterialSetterEditor : EditorWindow
{
/// <summary>
/// The folder path where the models are located. This is selected by the user through the editor interface.
/// </summary>
private string folderPath;
/// <summary>
/// The material to be applied to the models' renderers. This is selected by the user through the editor interface.
/// </summary>
private Material selectedMaterial;
/// <summary>
/// Displays the "Model Material Finder" window in the Unity Editor.
/// </summary>
[MenuItem("Wizards Code/Model Material Finder")]
public static void ShowWindow()
{
GetWindow<ModelMaterialSetterEditor>("Model Material Finder");
}
/// <summary>
/// Draws the GUI for the editor window, allowing the user to select a folder, choose a material,
/// and process the models in the folder.
/// </summary>
private void OnGUI()
{
EditorGUILayout.LabelField("Select Folder and Material", EditorStyles.boldLabel);
// Folder path field
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Folder Path", GUILayout.Width(75));
folderPath = AssetDatabase.GUIDToAssetPath(
AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(
EditorGUILayout.ObjectField(
AssetDatabase.LoadAssetAtPath<Object>(folderPath), typeof(DefaultAsset), false) as DefaultAsset))
);
EditorGUILayout.EndHorizontal();
if (string.IsNullOrEmpty(folderPath))
{
EditorGUILayout.HelpBox("Please select a folder containing the models.", MessageType.Warning);
return;
}
// Material field
selectedMaterial = (Material)EditorGUILayout.ObjectField("Material", selectedMaterial, typeof(Material), false);
if (selectedMaterial == null)
{
EditorGUILayout.HelpBox("Please select a material to apply to the models.", MessageType.Warning);
return;
}
EditorGUILayout.Space();
if (GUILayout.Button("Process Models"))
{
if (string.IsNullOrEmpty(folderPath) || selectedMaterial == null)
{
EditorUtility.DisplayDialog("Error", "Please select a folder and a material before processing.", "OK");
}
else
{
ProcessModels();
}
}
}
void ProcessModels()
{
int count = 0;
string[] guids = AssetDatabase.FindAssets("t:Model", new[] { folderPath });
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
EditorUtility.DisplayProgressBar("Processing Models", $"Processing {assetPath}", (float)count / guids.Length);
GameObject model = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
if (model != null)
{
Renderer[] renderers = model.GetComponentsInChildren<Renderer>();
foreach (var renderer in renderers)
{
renderer.sharedMaterial = selectedMaterial;
}
EditorUtility.SetDirty(model);
count++;
}
}
EditorUtility.ClearProgressBar();
if (count > 0) {
EditorUtility.DisplayDialog("Processing Complete", $"{count} of {guids.Length} models were processed and updated with the selected material.", "OK");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
else {
EditorUtility.DisplayDialog("No Models Found", "No models were found in the selected folder.", "OK");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment