Is it possible to automate material creation with new textures?

I have many textures that I need to turn in to materials. Is there a fast way to do this or script this?

For example if I could right click a single or group of textures and select from the right click menu (or use a pop up menu) “Create Material/s from Textures” that would then create materials with the same name and maybe an appendance of _mat or similar?

1 Like

2 Answers

2

Sure, just use a script like this:

// CreateMaterialsForTextures.cs
// C#
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;

public class CreateMaterialsForTextures : Editor
{
	[MenuItem("Tools/CreateMaterialsForTextures")]
	static void CreateMaterials ()
	{
		try
		{
			AssetDatabase.StartAssetEditing();
			var textures = Selection.GetFiltered(typeof(Texture), SelectionMode.Assets).Cast<Texture>();
			foreach(var tex in textures)
			{
				string path = AssetDatabase.GetAssetPath(tex);
				path = path.Substring(0,path.LastIndexOf("."))+".mat";
				if (AssetDatabase.LoadAssetAtPath(path,typeof(Material)) != null)
				{
					Debug.LogWarning("Can't create material, it already exists: " + path);
					continue;
				}
				var mat = new Material(Shader.Find("Diffuse"));
				mat.mainTexture = tex;
				AssetDatabase.CreateAsset(mat,path);
			}
		}
		finally
		{
			AssetDatabase.StopAssetEditing();
			AssetDatabase.SaveAssets();
		}
	}
}

Keep in mind this is an editor script and need to be placed in a folder called “editor”. Once you have this script in your project and it is compiled you can select one or multiple textures in your project panel and then click “Tools->CreateMaterialsForTextures” in the menubar.

Note: if the script just was compiled the Tools menu might not be visible yet but when you just click any menuitem it should appear.

This script will create a material next to the texture with the same name. However if there is already a material with that name it does nothing.

edit
Here’s the same script but turned into a wizard which allows you to select a different shader before you create the materials:

// CreateMaterialsForTextures.cs
// C#
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;

public class CreateMaterialsForTextures : ScriptableWizard
{
	public Shader shader;

	[MenuItem("Tools/CreateMaterialsForTextures")]
	static void CreateWizard ()
	{
		ScriptableWizard.DisplayWizard<CreateMaterialsForTextures>("Create Materials", "Create");

	}

	void OnEnable()
	{
		shader = Shader.Find("Diffuse");
	}

	void OnWizardCreate ()
	{
		try
		{
			AssetDatabase.StartAssetEditing();
			var textures = Selection.GetFiltered(typeof(Texture), SelectionMode.Assets).Cast<Texture>();
			foreach(var tex in textures)
			{
				string path = AssetDatabase.GetAssetPath(tex);
				path = path.Substring(0,path.LastIndexOf("."))+".mat";
				if (AssetDatabase.LoadAssetAtPath(path,typeof(Material)) != null)
				{
					Debug.LogWarning("Can't create material, it already exists: " + path);
					continue;
				}
				var mat = new Material(shader);
				mat.mainTexture = tex;
				AssetDatabase.CreateAsset(mat,path);
			}
		}
		finally
		{
			AssetDatabase.StopAssetEditing();
			AssetDatabase.SaveAssets();
		}
	}
}

ps: I used the default "Diffuse" shader when creating the material. If you want something else, either change the script, or create a wizard.

Oh that is beautiful. Exactly what I needed. I am going to study this a bit, because I originally wanted to try and script this out myself. Scripting / Coding is not my usual thing. Thanks so much. =)

Omit "SaveAssets". CreateAsset doesn't leave those assets in some kind of "unsaved" state.

You could create an editor script to do this using AssetDatabase.CreateAsset as shown in

(the example creates a material, btw)

Thank you for replying. For some reason I couldn't even find that in the docs. =\