Unity propose un éditeur facile d’accès et assez complet par rapport à ses concurrents. Mais le plus intéressant c’est que vous pouvez très aisément le modifier, que ce soit dans sa forme ou dans les traitements de fond, pour l’adapter à vos besoin.
Par exemple : créer automatiquement des préfabs à partir des textures importées.
Dernièrement, j’avais besoin de créer une grande quantité de cubes de couleurs différentes à partir d’un unique modèle 3D et de plusieurs textures. J’ai donc créé une classe héritant de AssetPostprocessor pour récupérer les textures juste après leur import dans Unity et créer un prefab pour chacune d’entre elles.
La classe possède plusieurs évènements sur lesquels se brancher (voir la liste sur la doc officielle) et en particuler OnPostprocessAllAssets qui est appelé une fois l’import terminé. Ensuite il suffit de mettre la classe dans le dossier « Assets/Editor/ » pour que le code soit exécuté à chaque import !
Exemple simplifié (code complet plus bas) :
public static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach(string assetPath in importedAssets) { //On vérifie le dossier de l'asset importé if (assetPath.IndexOf("/Textures") == -1) continue; //On charge l'asset et on vérifie qu'il s'agit d'une texture Texture2D texture = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D)) as Texture2D; if (texture == null) continue; //On créé un GameObject temporaire avec ses composants GameObject go = new GameObject(texture.name); MeshFilter meshFilter = go.AddComponent(); MeshRenderer meshRenderer = go.AddComponent(); //On créé le material en tant qu'asset Material mat = new Material(Shader.Find ("Mobile/Diffuse")); mat.mainTexture = texture; mat.name = texture.name; AssetDatabase.CreateAsset(mat, "Assets/Materials/" + mat.name + ".mat"); //On assigne le material et le modèle 3D meshRenderer.material = mat; meshFilter.mesh = AssetDatabase.LoadAssetAtPath("Assets/Models/Model.fbx", typeof(Mesh)) as Mesh; //On créé le prefab PrefabUtility.CreatePrefab( "Assets/Prefabs/" + texture.name + ".prefab", go); //On détruit le GameObject temporaire GameObject.DestroyImmediate(go); } }
Code complet (cliquez sur « Show source ») :
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; } }