- Home /
 
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?
Answer by Bunny83 · Jul 11, 2014 at 02:09 PM
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. =)
updated for universal render pipeline:
 // 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("Universal Render Pipeline/Lit");
     }
 
     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.SetTexture("_BaseMap", tex);
                 AssetDatabase.CreateAsset(mat, path);
             }
         }
         finally
         {
             AssetDatabase.StopAssetEditing();
             AssetDatabase.SaveAssets();
         }
     }
 }
                 Answer by kleber-swf · Jul 11, 2014 at 02:06 PM
You could create an editor script to do this using AssetDatabase.CreateAsset as shown in
http://docs.unity3d.com/ScriptReference/AssetDatabase.CreateAsset.html
(the example creates a material, btw)
Thank you for replying. For some reason I couldn't even find that in the docs. =\
Your answer