Unity has a very powerful scene editor that offers a lot of features and still keeps it simple. The feature I like the most is the possibility to customize this editor to adapt it to your needs.
For instance: automatically create prefabs from imported textures.
Lastly, I needed to create a high number of cubes with different colors using a single mesh and multiple textures.
So I created a subclass of AssetPostprocessor in order to retrieve textures just after the asset import process , and create a new prefab for each one.
The AssetPostprocessor class provides several event-like methods that you can hook up to (full list in the official doc) and the especially important OnPostprocessAllAssets method. Then you only need to save the class in the “Assets/Editor/” folder to have your code run on every asset import process.
Simple example (full code below):
public static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach(string assetPath in importedAssets) { //Check the folder in which the asset has been imported if (assetPath.IndexOf("/Textures") == -1) continue; //Load the asset and check if it is a texture or not Texture2D texture = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D)) as Texture2D; if (texture == null) continue; //Create temporary game object with required components GameObject go = new GameObject(texture.name); MeshFilter meshFilter = go.AddComponent(); MeshRenderer meshRenderer = go.AddComponent(); //Create material as an asset Material mat = new Material(Shader.Find ("Mobile/Diffuse")); mat.mainTexture = texture; mat.name = texture.name; AssetDatabase.CreateAsset(mat, "Assets/Materials/" + mat.name + ".mat"); //Assign material and model meshRenderer.material = mat; meshFilter.mesh = AssetDatabase.LoadAssetAtPath("Assets/Models/Model.fbx", typeof(Mesh)) as Mesh; //Create prefab PrefabUtility.CreatePrefab( "Assets/Prefabs/" + texture.name + ".prefab", go); //Destroy GameObject GameObject.DestroyImmediate(go); } }
using System; using UnityEditor; using UnityEngine; public class CubePostProcessor : AssetPostprocessor { static string TEXTURES_FOLDER = "/ColorCubes/"; static string PREFABS_FOLDER = "Assets/Prefabs/ColorCubes/"; static string MATERIALS_FOLDER = "Assets/Materials/ColorCubes/"; static string MODEL_PATH = "Assets/Models/Cube.fbx"; static string SHADER = "Mobile/Diffuse"; static string PREFAB_TAG = "MovingCubes"; public static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { int nbPrefabsCreated = 0; Mesh sharedModel = null; Shader sharedShader = null; foreach(string assetPath in importedAssets) { //Check if an asset has been imported in the folder we care about if (assetPath.IndexOf(TEXTURES_FOLDER) == -1) continue; //Load the asset and check if it is a texture or not Texture2D textureAsset = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D)) as Texture2D; if (textureAsset == null) continue; //Check if mesh is set if (sharedModel == null) sharedModel = AssetDatabase.LoadAssetAtPath(MODEL_PATH, typeof(Mesh)) as Mesh; //Check if shader is set if (sharedShader == null) sharedShader = Shader.Find(SHADER); //Stop if shader or model is null if ((sharedModel == null) || (sharedShader == null)) break; //Create a prefab from the curret texture and shared parameters if (CreateCubePrefab(textureAsset, sharedShader, sharedModel, PREFAB_TAG, PREFABS_FOLDER, MATERIALS_FOLDER)) nbPrefabsCreated++; } if (nbPrefabsCreated >0) Debug.Log(String.Format("Successfully created {0} prefabs from imported textures.", nbPrefabsCreated)); } private static bool CreateCubePrefab(Texture2D texture, Shader shader, Mesh model, string tag, string outPrefabFolder, string outMaterialFolder) { bool created; string materialName; string prefabName; GameObject tmpGameObject = null; try { materialName = prefabName = texture.name; //Create material as an asset Material mat = new Material(shader); mat.mainTexture = texture; mat.name = materialName; AssetDatabase.CreateAsset(mat, outMaterialFolder + mat.name + ".mat"); //Create temporary game object with required components tmpGameObject = new GameObject(prefabName); MeshFilter meshFilter = tmpGameObject.AddComponent(); MeshRenderer meshRenderer = tmpGameObject.AddComponent(); //Assign mesh & material meshFilter.mesh = model; meshRenderer.material = mat; //Assign tag if (!string.IsNullOrEmpty(tag)) tmpGameObject.tag = tag; //Create prefab PrefabUtility.CreatePrefab(outPrefabFolder + prefabName + ".prefab", tmpGameObject); created = true; } catch(Exception exc) { Debug.LogException(exc); created = false; } finally { //Destroy temporary game object if (tmpGameObject != null) GameObject.DestroyImmediate(tmpGameObject); } return created; } }