static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string importedAssetPath in importedAssets) { Debug.Log("AOnPostprocessAllAssets " + importedAssetPath); if (Path.GetExtension(importedAssetPath) == ".meta") { continue; } string assetPath = importedAssetPath.Replace('/', Path.DirectorySeparatorChar); //fix the path so that it uses the correct seperator for this system string assetFileName = Path.GetFileName(assetPath); string[] split = assetFileName.Split(templateSeperator); if (split.Length != 3) { continue; } string uuid = split[1]; string assetName = split[2]; string assetFolder = Path.GetDirectoryName(assetPath); if (assetPath.StartsWith(processingFolder)) //Looking for the copied .fbx file that resides in the projects processing/prefab folder { if (!assetPath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase)) //only check if .fbx is in the processing folder { continue; } GameObject modelAsset = AssetDatabase.LoadAssetAtPath <GameObject> (assetPath); //LOADING AN ASSET string jsonPath = Path.Combine(assetBundlesFolder, uuid + ".json"); if (!File.Exists(jsonPath)) { Debug.LogError("SKIPPING - The JSON file did not exist at path: " + jsonPath); continue; } ModelImporter modelImporter = ModelImporter.GetAtPath(assetPath) as ModelImporter; string jsonTxt = File.ReadAllText(jsonPath); AssetBundleUserJson userPrefs = (AssetBundleUserJson)JsonUtility.FromJson(jsonTxt, typeof(AssetBundleUserJson)); //RE-IMPORTED SECTION (SECOND-IMPORT): if (!Directory.Exists(prefabsFolder)) { Directory.CreateDirectory(prefabsFolder); } string modelFileName = Path.GetFileNameWithoutExtension(assetPath); string destinationPath = Path.Combine(prefabsFolder, modelFileName + ".prefab"); GameObject model = (GameObject)PrefabUtility.InstantiatePrefab(modelAsset); GameObject real = GameObject.Instantiate(model); //this is a game object that we can re-arange and change parenting or objects, then save as the original prefab later on real.SetActive(true); real.name = model.name; //remove "(clone) or any other discrepancies from name" GameObject.DestroyImmediate(model); //destroy the prefab as it will be overwritten by "real" var defaultController = Resources.Load <RuntimeAnimatorController>("DefaultAnimationController"); if (defaultController != null) { real.transform.root.GetComponentInChildren <Animator> ().runtimeAnimatorController = defaultController; } //Build the prop and set all data arrays var buildProp = real.AddComponent <BuildProp> (); buildProp.CreateEmptyContianers(real.name); GameObject.DestroyImmediate(buildProp); //no long need this component, so destroy it. string blenderJsonPath = Path.Combine(assetFolder, "blender.json"); Dictionary <string, MaterialsJson> materialsJson = null; if (File.Exists(blenderJsonPath)) { BlenderJsonObject blenderJsonArray = JsonUtility.FromJson <BlenderJsonObject> ( File.ReadAllText(blenderJsonPath) ); materialsJson = BuildMaterialsDict(blenderJsonArray.materials); } var childrenRenderers = real.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in childrenRenderers) { if (renderer == null) { continue; } renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; renderer.receiveShadows = true; foreach (var material in renderer.sharedMaterials) { //var material = renderer.sharedMaterial; var mainColor = material.GetColor("_Color"); mainColor.a = 1.0f; //always do this, just because unity is weird and seemingly random alpha values always appear material.SetColor("_Color", mainColor); if (materialsJson != null) { //THE NEW WAY (USING BLENDER MATERIALS JSON) //var textureFileName = Path.GetFileName (AssetDatabase.GetAssetPath (material.mainTexture)); //takes a full path to an texture asset, and returs the filename with extension (which is used as key for materials json) var was = Path.GetFileName(AssetDatabase.GetAssetPath(material.mainTexture)); var materialName = material.name; // Path.GetFileName (AssetDatabase.GetAssetPath (material.mainTexture)); //takes a full path to an texture asset, and returs the filename with extension (which is used as key for materials json) if (material.mainTexture != null) { materialName = Path.GetFileName(AssetDatabase.GetAssetPath(material.mainTexture)); //takes a full path to an texture asset, and returs the filename with extension (which is used as key for materials json) } materialName = Path.GetFileNameWithoutExtension(materialName); if (materialsJson.ContainsKey(materialName)) { //if (materialsJson.ContainsKey (textureFileName)) { //var blenderMaterial = materialsJson [textureFileName]; var blenderMaterial = materialsJson [materialName]; Texture2D diffTex = null; Texture2D bumpTex = null; Texture2D specularTex = null; Texture2D emissionTex = null; bool enableAlpha = false; float emit_factor = 0; var use_map_color_diffuse = false; var use_map_bump = false; var use_map_specular = false; var use_map_emit = false; foreach (var slot in blenderMaterial.texture_slots) //check all slots to see if there are any spec or emmit textures { if (slot.use_map_color_diffuse) { //var texPath = AssetDatabase.GetAssetPath (material.mainTexture); var texPath = Path.Combine(Path.GetDirectoryName(assetPath), slot.filename); if (File.Exists(texPath)) { var folder = Path.GetDirectoryName(texPath); diffTex = AssetDatabase.LoadAssetAtPath(Path.Combine(folder, slot.filename), typeof(Texture2D)) as Texture2D; TextureImporter A = (TextureImporter)AssetImporter.GetAtPath(Path.Combine(folder, slot.filename)); enableAlpha = blenderMaterial.use_transparency && A.DoesSourceTextureHaveAlpha(); } } if (slot.use_map_normal) { //Debug.Log("use_map_normal " + slot.filename); //var texPath = AssetDatabase.GetAssetPath (material.mainTexture); var texPath = Path.Combine(Path.GetDirectoryName(assetPath), slot.filename); if (File.Exists(texPath)) { var folder = Path.GetDirectoryName(texPath); bumpTex = AssetDatabase.LoadAssetAtPath(Path.Combine(folder, slot.filename), typeof(Texture2D)) as Texture2D; } } if (slot.use_map_specular) { //Debug.Log("use_map_specular " + slot.filename); //var texPath = AssetDatabase.GetAssetPath (material.mainTexture); var texPath = Path.Combine(Path.GetDirectoryName(assetPath), slot.filename); if (File.Exists(texPath)) { var folder = Path.GetDirectoryName(texPath); specularTex = AssetDatabase.LoadAssetAtPath(Path.Combine(folder, slot.filename), typeof(Texture2D)) as Texture2D; } } if (slot.use_map_emit) { //Debug.Log("use_map_emit " + slot.filename); //var texPath = AssetDatabase.GetAssetPath (material.mainTexture); var texPath = Path.Combine(Path.GetDirectoryName(assetPath), slot.filename); if (File.Exists(texPath)) { var folder = Path.GetDirectoryName(texPath); emissionTex = AssetDatabase.LoadAssetAtPath(Path.Combine(folder, slot.filename), typeof(Texture2D)) as Texture2D; } emit_factor = slot.emit_factor; } use_map_color_diffuse |= slot.use_map_color_diffuse; use_map_bump |= slot.use_map_normal; use_map_specular |= slot.use_map_specular; use_map_emit |= slot.use_map_emit; } var specIsBlack = (blenderMaterial.specular_color.r * blenderMaterial.specular_intensity) == 0 && (blenderMaterial.specular_color.g * blenderMaterial.specular_intensity) == 0 && (blenderMaterial.specular_color.b * blenderMaterial.specular_intensity) == 0; if (!specIsBlack || use_map_specular) { material.shader = Shader.Find("Standard (Specular setup)"); //the default fallback shader material.SetColor("_SpecColor", new Color( blenderMaterial.specular_color.r * blenderMaterial.specular_intensity * 0.25f, //default values are way too high for Standard shader so multiply by 0.25 blenderMaterial.specular_color.g * blenderMaterial.specular_intensity * 0.25f, blenderMaterial.specular_color.b * blenderMaterial.specular_intensity * 0.25f )); } if (use_map_color_diffuse) //set all white and adjust brightness based on diffuse intensity set from blender { material.SetColor("_Color", new Color( blenderMaterial.diffuse_color.r * blenderMaterial.diffuse_intensity, blenderMaterial.diffuse_color.g * blenderMaterial.diffuse_intensity, blenderMaterial.diffuse_color.b * blenderMaterial.diffuse_intensity, blenderMaterial.alpha )); } else { material.SetColor("_Color", new Color( // has no texture, thus pass through the color and adjust on diffuse intensity set from blender mainColor.r * blenderMaterial.diffuse_intensity, mainColor.g * blenderMaterial.diffuse_intensity, mainColor.b * blenderMaterial.diffuse_intensity, blenderMaterial.alpha )); if (blenderMaterial.use_transparency) //has no texture but alpha was set, so ensure to honor that { enableAlpha = true; } } if (enableAlpha) //change to opaque https://sassybot.com/blog/swapping-rendering-mode-in-unity-5-0/ { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } else //OPAQUE { material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; } if (use_map_color_diffuse) { material.SetTexture("_MainTex", diffTex); } if (use_map_bump) { material.SetTexture("_BumpMap", bumpTex); } if (use_map_emit) { material.EnableKeyword("_EMISSION"); //You must enable the correct Keywords for your required Standard Shader variant material.SetTexture("_EmissionMap", emissionTex); material.SetColor("_EmissionColor", new Color( emit_factor, emit_factor, emit_factor )); } if (use_map_specular) { material.EnableKeyword("_SPECGLOSSMAP"); //You must enable the correct Keywords for your required Standard Shader variant material.SetTexture("_SpecGlossMap", specularTex); } material.SetFloat("_GlossMapScale", blenderMaterial.specular_hardness / 511f); material.SetFloat("_Glossiness", blenderMaterial.specular_hardness / 511f); material.SetFloat("_Shininess", blenderMaterial.specular_hardness / 511f); //synonmus with _Glossiness if using legacy shaders if (!use_map_specular && !use_map_emit) { /*if (blenderMaterial.key.ToLower ().Contains ("hair")) { * material.shader = Shader.Find ("Hair/Standard Two Sided Soft Blend"); * material.SetFloat ("_Cutoff", 0.05f); * } else if ( * blenderMaterial.key.ToLower ().Contains ("eye") && ( * blenderMaterial.key.ToLower ().Contains ("lash") || || blenderMaterial.key.ToLower ().Contains ("brow") || )) { //if its hair sprites || material.shader = Shader.Find ("Sprites/Default"); || continue; //it's no longer a stander shader, nothing more to be done ||}*/ if (blenderMaterial.key.ToLower().Contains("hair")) { material.shader = Shader.Find("Hair/Standard Two Sided Soft Blend"); material.SetFloat("_Cutoff", 0.05f); } } } } else { /* * material.shader = Shader.Find ("Standard (Specular setup)"); //the default fallback shader * //THE OLD WAY - USE KEYWORDS IN MATERIAL NAME TO CONTROL SHADER KEYWORDS * * var color222 = material.GetColor ("_Color"); * * color222.a = 1.0f; //always do this, just because unity is weird and seemingly random alpha values always appear * material.SetColor ("_Color", color222); * * if (material.mainTexture != null) { * * string path = AssetDatabase.GetAssetPath (material.mainTexture); * TextureImporter A = (TextureImporter)AssetImporter.GetAtPath (path); * * if (!A.DoesSourceTextureHaveAlpha ()) {//change to opaque https://sassybot.com/blog/swapping-rendering-mode-in-unity-5-0/ * material.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); * material.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); * material.SetInt ("_ZWrite", 1); * material.DisableKeyword ("_ALPHATEST_ON"); * material.DisableKeyword ("_ALPHABLEND_ON"); * material.DisableKeyword ("_ALPHAPREMULTIPLY_ON"); * material.renderQueue = -1; * } * * var matTextureName = material.mainTexture.name.ToLower (); * //Debug.Log ("MAT NAME " + matTextureName); * var texPath = AssetDatabase.GetAssetPath (material.mainTexture); * var texName = Path.GetFileNameWithoutExtension (texPath); * * //Debug.Log ("matTextureName" + matTextureName); * //Debug.Log ("Texture Path" + texPath); * * Texture specularTex = GetFileByKeywords (texPath, new[] { * "_Spec", * "_spec", * "_Specularity", * "_specularity", * "_Specular", * "_specular" * }); * Texture metallicTex = GetFileByKeywords (texPath, new[] { "_Metallic", "_metallic" }); * * if (specularTex != null) { * //Debug.Log ("JUST SET SPECULAR SETUP!! " + specularTex); * material.shader = Shader.Find ("Standard (Specular setup)"); * material.EnableKeyword ("_SPECGLOSSMAP"); //You must enable the correct Keywords for your required Standard Shader variant * material.SetTexture ("_SpecGlossMap", specularTex); * material.SetColor ("_SpecColor", Color.white); * } else { * if (metallicTex != null) { * material.EnableKeyword ("_METALLICGLOSSMAP"); //You must enable the correct Keywords for your required Standard Shader variant * material.SetTexture ("_MetallicGlossMap", metallicTex); * } * } * * Texture emissionTex = GetFileByKeywords (texPath, new[] { "_Emission", "_emission" }); * if (emissionTex != null) { * material.EnableKeyword ("_EMISSION"); //You must enable the correct Keywords for your required Standard Shader variant * material.SetTexture ("_EmissionMap", emissionTex); * material.SetColor ("_EmissionColor", Color.white); * } * * if (specularTex == null && emissionTex == null) { * if (matTextureName.Contains ("_hair")) { * material.shader = Shader.Find ("Custom/Standard Two Sided Soft Blend"); * material.SetFloat ("_Cutoff", 0.05f); * } else if ( * matTextureName.Contains ("eyelash") || * matTextureName.Contains ("eyebrow")) { //if its hair sprites * material.shader = Shader.Find ("Sprites/Default"); * continue; //it's no longer a stander shader, nothing more to be done * } * } * } * * * if (material.HasProperty ("_Mode") && material.GetFloat ("_Mode").Equals (3)) { //if the exported material has transparency * //Debug.Log ("MODE 3 " + material); * if (color222.a >= 0.9f) { //because blender/unity are weird, and setting blender to 1 results in unity using opaque mode * color222.a = 1.0f; * material.SetColor ("_Color", color222); * } * //material.SetFloat("_Mode", 3); * //material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); * //material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); * //material.SetInt("_ZWrite", 0); * //material.DisableKeyword("_ALPHATEST_ON"); * //material.EnableKeyword("_ALPHABLEND_ON"); * //material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); * //material.renderQueue = 3000; * } */ } } //var shaderParams = renderer.gameObject.AddComponent<RendererShaderParams> (); //shaderParams.StoreParams (); //NOW USING RendererShaderParams.StoreAllRenderers (real); } RendererShaderParams.StoreAllRenderers(real); if (modelImporter.userData.Contains(processedTag)) { string json = JsonUtility.ToJson(userPrefs); using (StreamWriter sr = new StreamWriter(jsonPath)) // Create the file. { sr.WriteLine(json); } } PrefabUtility.SaveAsPrefabAsset(real, destinationPath); GameObject.DestroyImmediate(real); } else if (assetPath.StartsWith(prefabsFolder)) //ASSET BUNDLE FINAL PROCESSING { Debug.Log("ASSET BUNDLE FINAL PROCESSING 1"); var assetImport = AssetImporter.GetAtPath(assetPath); assetImport.SetAssetBundleNameAndVariant(Path.GetFileNameWithoutExtension(assetPath), assetBundleVariant); } else if (assetPath.StartsWith(assetBundlesFolder)) //ASSET BUNDLE FINAL PROCESSING { if (!Path.GetExtension(assetPath).Contains(assetBundleVariant)) { continue; //might be a .meta file, just ignore it } var rootObjs = new List <GameObject>(); foreach (var item in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects()) { if (item.activeSelf) //only store active go's, so that we may disable them during portrait pictures, them re-enable them { rootObjs.Add(item); } } string assetDestFolder = Path.Combine(assetBundlesFolder, Path.GetFileNameWithoutExtension(assetPath).ToLower()); string jsonPath = Path.Combine(assetFolder, uuid + ".json"); /*if (!File.Exists (jsonPath)) { * * if (Path.GetDirectoryName (assetPath).Equals(assetBundlesFolder)) { * * if (Directory.Exists (assetDestFolder)) { * FileUtil.DeleteFileOrDirectory( Path.Combine (assetDestFolder, assetFileName)); * File.Move(assetPath, Path.Combine (assetDestFolder, assetFileName)); * * var thumbnailFolderAbs = Path.Combine (assetDestFolder, "thumbnails"); * TakePortraitPictures (assetFileName, rootObjs, thumbnailFolderAbs); //update the portrait pictures * * AssetDatabase.Refresh (); * continue; * } * * } else { * continue; * } * * Debug.LogWarning ("SKIPPING - The JSON file did not exist at path: " + jsonPath); * continue; * }*/ if (!File.Exists(jsonPath)) { if (Path.GetDirectoryName(assetPath).Equals(assetBundlesFolder)) { //if (Path.GetFullPath(Path.GetDirectoryName (assetPath)).Equals(Path.GetFullPath(assetBundlesFolder))) { if (Directory.Exists(assetDestFolder)) { FileUtil.DeleteFileOrDirectory(Path.Combine(assetDestFolder, assetFileName)); File.Move(assetPath, Path.Combine(assetDestFolder, assetFileName)); var thumbnailFolderAbs = Path.Combine(assetDestFolder, "thumbnails"); TakePortraitPictures(assetFileName, rootObjs, thumbnailFolderAbs); //update the portrait pictures AssetDatabase.Refresh(); continue; } } else { continue; } Debug.LogWarning("SKIPPING - The JSON file did not exist at path: " + jsonPath); continue; } string jsonTxt = File.ReadAllText(jsonPath); AssetBundleUserJson userPrefs = (AssetBundleUserJson)JsonUtility.FromJson(jsonTxt, typeof(AssetBundleUserJson)); File.Delete(jsonPath); //no longer needed var to = Path.Combine(assetDestFolder, assetFileName); if (!Directory.Exists(Path.GetDirectoryName(to))) { Directory.CreateDirectory(Path.GetDirectoryName(to)); } if (File.Exists(to)) { File.Delete(to); } FileUtil.MoveFileOrDirectory(assetPath, to); DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(assetPath)); FileInfo[] info = dir.GetFiles(Path.GetFileNameWithoutExtension(assetFileName) + ".*"); foreach (FileInfo f in info) { File.Delete(f.FullName); } var thumbnailFolder = Path.Combine(assetDestFolder, "thumbnails"); TakePortraitPictures(assetFileName, rootObjs, thumbnailFolder); //take the initial portrait pictures //copy the .blend character file to the final assetbundle directory if it exists DirectoryInfo dir_blend = new DirectoryInfo(userPrefs.characterFolder); FileInfo blendInfo = dir_blend.GetFiles(Path.GetFileNameWithoutExtension(assetName) + ".blend").FirstOrDefault(); if (blendInfo == null) { Debug.LogWarning(String.Format("{0}.blend file could be copied.", Path.GetFileNameWithoutExtension(assetName))); } else { ZipFile.Compress(new FileInfo(blendInfo.FullName)); if (File.Exists(blendInfo.FullName + ".gz")) { var path_blend_gz = Path.Combine(assetDestFolder, Path.GetFileNameWithoutExtension(assetFileName) + ".blend.gz"); FileUtil.MoveFileOrDirectory(blendInfo.FullName + ".gz", path_blend_gz); } } AssetDatabase.Refresh(); AnimPrepAssetBuilder.ShowExplorer(assetDestFolder); } else { Debug.LogWarning(assetPath + " - WAS NOT A MEMBER OF FOLDERS: " + assetBundlesFolder + " - OR - " + processingFolder); } EditorUtility.UnloadUnusedAssetsImmediate(); System.GC.Collect(); } }