void createCombinedMaterialAssets(MB2_TextureBaker target, string pth) { MB2_TextureBaker mom = (MB2_TextureBaker)target; string baseName = System.IO.Path.GetFileNameWithoutExtension(pth); string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6); List <string> matNames = new List <string>(); if (mom.doMultiMaterial) { for (int i = 0; i < mom.resultMaterials.Length; i++) { matNames.Add(folderPath + baseName + "-mat" + i + ".mat"); AssetDatabase.CreateAsset(new Material(Shader.Find("Diffuse")), matNames[i]); mom.resultMaterials[i].combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[i], typeof(Material)); } } else { matNames.Add(folderPath + baseName + "-mat.mat"); AssetDatabase.CreateAsset(new Material(Shader.Find("Diffuse")), matNames[0]); mom.resultMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[0], typeof(Material)); } //create the MB2_TextureBakeResults AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <MB2_TextureBakeResults>(), pth); mom.textureBakeResults = (MB2_TextureBakeResults)AssetDatabase.LoadAssetAtPath(pth, typeof(MB2_TextureBakeResults)); AssetDatabase.Refresh(); }
void OnGUI() { GUILayout.Label("Time to bake textures: " + elapsedTime); if (GUILayout.Button("Combine textures & build combined mesh")) { MB2_MeshBaker meshbaker = target.GetComponent <MB2_MeshBaker>(); MB2_TextureBaker textureBaker = target.GetComponent <MB2_TextureBaker>(); //These can be assets configured at runtime or you can create them // on the fly like this textureBaker.textureBakeResults = ScriptableObject.CreateInstance <MB2_TextureBakeResults>(); textureBaker.resultMaterial = new Material(Shader.Find("Diffuse")); float t1 = Time.realtimeSinceStartup; textureBaker.CreateAtlases(); elapsedTime = Time.realtimeSinceStartup - t1; meshbaker.ClearMesh(); //only necessary if your not sure whats in the combined mesh meshbaker.textureBakeResults = textureBaker.textureBakeResults; //Add the objects to the combined mesh meshbaker.AddDeleteGameObjects(textureBaker.GetObjectsToCombine().ToArray(), null, true, false); meshbaker.Apply(); } }
public static void CreateNewTextureBaker() { MB2_TextureBaker[] mbs = (MB2_TextureBaker[])Editor.FindObjectsOfType(typeof(MB2_TextureBaker)); Regex regex = new Regex(@"(\d+)$", RegexOptions.Compiled | RegexOptions.CultureInvariant); int largest = 0; try{ for (int i = 0; i < mbs.Length; i++) { Match match = regex.Match(mbs[i].name); if (match.Success) { int val = Convert.ToInt32(match.Groups[1].Value); if (val >= largest) { largest = val + 1; } } } } catch (Exception e) { if (e == null) { e = null; //Do nothing supress compiler warning } } GameObject nmb = new GameObject("MaterialBaker" + largest); nmb.transform.position = Vector3.zero; MB2_TextureBaker tb = nmb.AddComponent <MB2_TextureBaker>(); tb.texturePackingAlgorithm = MB2_PackingAlgorithmEnum.MeshBakerTexturePacker; }
void bake(MB2_TextureBaker target) { MB_AtlasesAndRects[] mAndAs = null; try{ mAndAs = _bakeTexturesOnly(target); } catch (Exception e) { Debug.LogError(e); } finally { EditorUtility.ClearProgressBar(); if (mAndAs != null) { for (int j = 0; j < mAndAs.Length; j++) { MB_AtlasesAndRects mAndA = mAndAs[j]; if (mAndA != null && mAndA.atlases != null) { for (int i = 0; i < mAndA.atlases.Length; i++) { if (mAndA.atlases[i] != null) { MB_Utility.Destroy(mAndA.atlases[i]); } } } } } } }
public static void CreateCombinedMaterialAssets(MB2_TextureBaker target, string pth) { MB2_TextureBaker mom = (MB2_TextureBaker)target; string baseName = Path.GetFileNameWithoutExtension(pth); if (baseName == null || baseName.Length == 0) { return; } string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6); List <string> matNames = new List <string>(); if (mom.doMultiMaterial) { for (int i = 0; i < mom.resultMaterials.Length; i++) { matNames.Add(folderPath + baseName + "-mat" + i + ".mat"); AssetDatabase.CreateAsset(new Material(Shader.Find("Diffuse")), matNames[i]); mom.resultMaterials[i].combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[i], typeof(Material)); } } else { matNames.Add(folderPath + baseName + "-mat.mat"); Material newMat = new Material(Shader.Find("Diffuse")); if (mom.objsToMesh.Count > 0 && mom.objsToMesh[0] != null) { Renderer r = mom.objsToMesh[0].GetComponent <Renderer>(); if (r == null) { Debug.LogWarning("Object " + mom.objsToMesh[0] + " does not have a Renderer on it."); } else { if (r.sharedMaterial != null) { newMat.shader = r.sharedMaterial.shader; MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, r.sharedMaterial); } } } else { Debug.Log("If you add objects to be combined before creating the Combined Material Assets. Then Mesh Baker will create a result material that is a duplicate of the material on the first object to be combined. This saves time configuring the shader."); } AssetDatabase.CreateAsset(newMat, matNames[0]); mom.resultMaterial = (Material)AssetDatabase.LoadAssetAtPath(matNames[0], typeof(Material)); } //create the MB2_TextureBakeResults AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <MB2_TextureBakeResults>(), pth); mom.textureBakeResults = (MB2_TextureBakeResults)AssetDatabase.LoadAssetAtPath(pth, typeof(MB2_TextureBakeResults)); AssetDatabase.Refresh(); }
public override void OnInspectorGUI() { MB2_TextureBaker tb = (MB2_TextureBaker)target; if (GUILayout.Button(" MIGRATE COMPONENTS TO VERSION 3 ")) { GameObject go = tb.gameObject; MigrateTestureBakerToVersion3Component(go); MB2_MultiMeshBakerEditor.MigrateMultiMeshBakerToVersion3Component(go); MB2_MeshBakerEditor.MigrateMeshBakerToVersion3Component(go); } tbe.DrawGUI(tb, typeof(MB_MeshBakerEditorWindow)); }
void _init(MB2_TextureBaker target) { meshBaker = new SerializedObject(target); doMultiMaterial = meshBaker.FindProperty("doMultiMaterial"); fixOutOfBoundsUVs = meshBaker.FindProperty("fixOutOfBoundsUVs"); resultMaterial = meshBaker.FindProperty("resultMaterial"); resultMaterials = meshBaker.FindProperty("resultMaterials"); atlasPadding = meshBaker.FindProperty("atlasPadding"); resizePowerOfTwoTextures = meshBaker.FindProperty("resizePowerOfTwoTextures"); customShaderPropNames = meshBaker.FindProperty("customShaderPropNames"); objsToMesh = meshBaker.FindProperty("objsToMesh"); maxTilingBakeSize = meshBaker.FindProperty("maxTilingBakeSize"); textureBakeResults = meshBaker.FindProperty("textureBakeResults"); }
void _init(MB2_TextureBaker target) { textureBaker = new SerializedObject(target); doMultiMaterial = textureBaker.FindProperty("doMultiMaterial"); fixOutOfBoundsUVs = textureBaker.FindProperty("fixOutOfBoundsUVs"); resultMaterial = textureBaker.FindProperty("resultMaterial"); resultMaterials = textureBaker.FindProperty("resultMaterials"); atlasPadding = textureBaker.FindProperty("atlasPadding"); resizePowerOfTwoTextures = textureBaker.FindProperty("resizePowerOfTwoTextures"); customShaderPropNames = textureBaker.FindProperty("customShaderPropNames"); objsToMesh = textureBaker.FindProperty("objsToMesh"); maxTilingBakeSize = textureBaker.FindProperty("maxTilingBakeSize"); textureBakeResults = textureBaker.FindProperty("textureBakeResults"); texturePackingAlgorithm = textureBaker.FindProperty("texturePackingAlgorithm"); }
MB_AtlasesAndRects[] _bakeTexturesOnly(MB2_TextureBaker target) { MB_AtlasesAndRects[] mAndAs = null; if (!MB_Utility.doCombinedValidate((MB2_MeshBakerRoot)target, MB_ObjsToCombineTypes.dontCare)) { return(null); } MB2_TextureBaker mbd = (MB2_TextureBaker)target; mAndAs = mbd.CreateAtlases(updateProgressBar); if (mAndAs != null) { _saveBakeTextureAssets(target, mAndAs); } return(mAndAs); }
void bakeAllBakersInScene() { MB2_MeshBakerRoot[] bakers = (MB2_MeshBakerRoot[])FindObjectsOfType(typeof(MB2_MeshBakerRoot)); for (int i = 0; i < bakers.Length; i++) { if (bakers[i] is MB2_TextureBaker) { MB2_TextureBaker tb = (MB2_TextureBaker)bakers[i]; tb.CreateAndSaveAtlases(updateProgressBar, System.IO.File.WriteAllBytes); } } EditorUtility.ClearProgressBar(); // for (int i = 0; i < bakers.Length; i++){ // if (bakers[i] is MB2_MeshBaker){ // MB2_MeshBaker mb = (MB2_MeshBaker) bakers[i]; // } // if (bakers[i] is MB2_MultiMeshBaker){ // MB2_MultiMeshBaker mb = (MB2_MultiMeshBaker) bakers[i]; // } // } }
void bakeAllBakersInScene() { MB2_MeshBakerRoot[] bakers = (MB2_MeshBakerRoot[])FindObjectsOfType(typeof(MB2_MeshBakerRoot)); for (int i = 0; i < bakers.Length; i++) { if (bakers[i] is MB2_TextureBaker) { MB2_TextureBaker tb = (MB2_TextureBaker)bakers[i]; tb.CreateAtlases(updateProgressBar, true, new MB2_EditorMethods()); } } EditorUtility.ClearProgressBar(); // for (int i = 0; i < bakers.Length; i++){ // if (bakers[i] is MB2_MeshBaker){ // MB2_MeshBaker mb = (MB2_MeshBaker) bakers[i]; // } // if (bakers[i] is MB2_MultiMeshBaker){ // MB2_MultiMeshBaker mb = (MB2_MultiMeshBaker) bakers[i]; // } // } }
void _saveBakeTextureAssets(MB2_TextureBaker target, MB_AtlasesAndRects[] mAndAs) { MB2_TextureBaker mbd = (MB2_TextureBaker)target; for (int i = 0; i < mAndAs.Length; i++) { MB_AtlasesAndRects mAndA = mAndAs[i]; Material resMat = mbd.resultMaterial; if (mbd.doMultiMaterial) { resMat = mbd.resultMaterials[i].combinedMaterial; } _saveAtlasesToAssetDatabase(mAndA, resMat); } MB2_MeshBaker mb = mbd.GetComponent <MB2_MeshBaker>(); if (mb != null) { mb.textureBakeResults = mbd.textureBakeResults; } EditorUtility.SetDirty(mbd.textureBakeResults); }
public static void MigrateTestureBakerToVersion3Component(GameObject go) { MB2_TextureBaker tb2 = go.GetComponent <MB2_TextureBaker>(); if (tb2 == null) { return; } Debug.Log("Migrating Texture Baker"); MB3_TextureBaker tb3 = go.AddComponent <MB3_TextureBaker>(); tb3.atlasPadding = tb2.atlasPadding; tb3.doMultiMaterial = tb2.doMultiMaterial; tb3.fixOutOfBoundsUVs = tb2.fixOutOfBoundsUVs; tb3.maxTilingBakeSize = tb2.maxTilingBakeSize; tb3.objsToMesh = tb2.objsToMesh; tb3.packingAlgorithm = tb2.texturePackingAlgorithm; tb3.resizePowerOfTwoTextures = tb2.resizePowerOfTwoTextures; tb3.resultMaterial = tb2.resultMaterial; tb3.resultMaterials = tb2.resultMaterials; tb3.textureBakeResults = tb2.textureBakeResults; DestroyImmediate(tb2); }
public void ConfigureMutiMaterialsFromObjsToCombine(MB2_TextureBaker mom){ if (mom.objsToMesh.Count == 0){ Debug.LogError("You need to add some objects to combine before building the multi material list."); return; } if (resultMaterials.arraySize > 0){ Debug.LogError("You already have some source to combined material mappings configured. You must remove these before doing this operation."); return; } if (mom.textureBakeResults == null){ Debug.LogError("Material Bake Result asset must be set before using this operation."); return; } Dictionary<Shader,List<Material>> shader2Material_map = new Dictionary<Shader, List<Material>>(); Dictionary<Material,Mesh> obUVobject2material_map = new Dictionary<Material,Mesh>(); for (int i = 0; i < mom.objsToMesh.Count; i++){ GameObject go = mom.objsToMesh[i]; if (go == null) { Debug.LogError("Null object in list of objects to combine at position " + i); return; } Renderer r = go.GetComponent<Renderer>(); if (r == null || (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer))){ Debug.LogError("GameObject at position " + i + " in list of objects to combine did not have a renderer"); return; } if (r.sharedMaterial == null){ Debug.LogError("GameObject at position " + i + " in list of objects to combine has a null material"); return; } Mesh m = MB_Utility.GetMesh(go); Rect dummy = new Rect(); for (int j = 0; j < r.sharedMaterials.Length; j++){ if (MB_Utility.hasOutOfBoundsUVs(m, ref dummy, j)){ if (!obUVobject2material_map.ContainsKey(r.sharedMaterials[j])){ Debug.LogWarning("Object " + go + " submesh " + j + " uses UVs outside the range 0,0..1,1 to generate tiling. This object has been mapped to its own submesh in the combined mesh. It can share a submesh with other objects that use different materials if you use the fix out of bounds UVs feature which will bake the tiling"); obUVobject2material_map.Add(r.sharedMaterials[j],m); } } else if (!obUVobject2material_map.ContainsKey(r.sharedMaterials[j])) { if (r.sharedMaterials[j] == null) continue; List<Material> matsThatUseShader = null;; if (!shader2Material_map.TryGetValue(r.sharedMaterials[j].shader, out matsThatUseShader)){ matsThatUseShader = new List<Material>(); shader2Material_map.Add(r.sharedMaterials[j].shader, matsThatUseShader); } if (!matsThatUseShader.Contains(r.sharedMaterials[j])) matsThatUseShader.Add(r.sharedMaterials[j]); } } } if (shader2Material_map.Count == 0 && obUVobject2material_map.Count == 0) Debug.LogError("Found no materials in list of objects to combine"); mom.resultMaterials = new MB_MultiMaterial[shader2Material_map.Count + obUVobject2material_map.Count]; string pth = AssetDatabase.GetAssetPath(mom.textureBakeResults); string baseName = Path.GetFileNameWithoutExtension(pth); string folderPath = pth.Substring(0,pth.Length - baseName.Length - 6); int k = 0; foreach(Shader sh in shader2Material_map.Keys){ List<Material> matsThatUse = shader2Material_map[sh]; MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = matsThatUse; string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(Shader.Find("Diffuse")); if (matsThatUse.Count > 0 && matsThatUse[0] != null){ MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, matsThatUse[0]); } AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material) AssetDatabase.LoadAssetAtPath(matName,typeof(Material)); k++; } foreach(Material m in obUVobject2material_map.Keys){ MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = new List<Material>(); mm.sourceMaterials.Add(m); string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(Shader.Find("Diffuse")); MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat,m); AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material) AssetDatabase.LoadAssetAtPath(matName,typeof(Material)); k++; } textureBaker.UpdateIfDirtyOrScript(); }
public static bool doCombinedValidate(MB2_MeshBakerRoot mom, MB_ObjsToCombineTypes objToCombineType, MB2_EditorMethodsInterface editorMethods) { if (mom.textureBakeResults == null) { Debug.LogError("Need to set Material Bake Result on " + mom); return(false); } if (!(mom is MB2_TextureBaker)) { MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (tb != null && tb.textureBakeResults != mom.textureBakeResults) { Debug.LogWarning("Material Bake Result on this component is not the same as the Material Bake Result on the MB2_TextureBaker."); } } List <GameObject> objsToMesh = mom.GetObjectsToCombine(); for (int i = 0; i < objsToMesh.Count; i++) { GameObject go = objsToMesh[i]; if (go == null) { Debug.LogError("The list of objects to combine contains a null at position." + i + " Select and use [shift] delete to remove"); return(false); } for (int j = i + 1; j < objsToMesh.Count; j++) { if (objsToMesh[i] == objsToMesh[j]) { Debug.LogError("The list of objects to combine contains duplicates."); return(false); } } if (MB_Utility.GetGOMaterials(go) == null) { Debug.LogError("Object " + go + " in the list of objects to be combined does not have a material"); return(false); } if (MB_Utility.GetMesh(go) == null) { Debug.LogError("Object " + go + " in the list of objects to be combined does not have a mesh"); return(false); } } if (mom.textureBakeResults.doMultiMaterial) { if (!validateSubmeshOverlap(mom)) //only warns currently { return(false); } } List <GameObject> objs = objsToMesh; if (mom is MB2_MeshBaker) { MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (((MB2_MeshBaker)mom).useObjsToMeshFromTexBaker && tb != null) { objs = tb.objsToMesh; } if (objs == null || objs.Count == 0) { Debug.LogError("No meshes to combine. Please assign some meshes to combine."); return(false); } if (mom is MB2_MeshBaker && ((MB2_MeshBaker)mom).renderType == MB_RenderType.skinnedMeshRenderer) { if (!editorMethods.ValidateSkinnedMeshes(objs)) { return(false); } } } if (editorMethods != null) { editorMethods.CheckPrefabTypes(objToCombineType, objsToMesh); } return(true); }
void _bakeIntoCombined(MB2_MeshBakerCommon mom, MB_OutputOptions prefabOrSceneObject) { if (prefabOrSceneObject != MB_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB_OutputOptions.bakeIntoSceneObject) { Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return; } //MB2_MeshBakerCommon mom = (MB2_MeshBakerCommon) target; MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (mom.textureBakeResults == null && tb != null) { Debug.Log("setting results"); mom.textureBakeResults = tb.textureBakeResults; } if (mom.useObjsToMeshFromTexBaker) { if (tb != null) { mom.objsToMesh.Clear(); mom.objsToMesh.AddRange(tb.objsToMesh); } } Mesh mesh; if (!MB_Utility.doCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly)) { return; } if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab && mom.resultPrefab == null) { Debug.LogError("Need to set the Combined Mesh Prefab field."); return; } mom.ClearMesh(); mesh = mom.AddDeleteGameObjects(mom.objsToMesh.ToArray(), null, false, true); if (mesh != null) { mom.Apply(); updateProgressBar("Created mesh saving assets", .6f); if (prefabOrSceneObject == MB_OutputOptions.bakeIntoSceneObject) { // mom.BuildSceneMeshObject(); } else if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab) { string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab); if (prefabPth == null || prefabPth.Length == 0) { Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset."); return; } string baseName = System.IO.Path.GetFileNameWithoutExtension(prefabPth); string folderPath = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7); string newFilename = folderPath + baseName + "-mesh"; mom.SaveMeshsToAssetDatabase(folderPath, newFilename); mom.RebuildPrefab(); // saveMeshToAssetDatabase(mom, mesh); // if (mom.renderType == MB_RenderType.skinnedMeshRenderer){ // Debug.LogWarning("Prefab will not be updated for skinned mesh. This is because all bones need to be included in the prefab for it to be usefull."); // } else { // rebuildPrefab(mom, mesh); // } } else { Debug.LogError("Unknown parameter"); } } }
public void DrawGUI(MB2_TextureBaker mom, System.Type editorWindow) { if (textureBaker == null) { _init(mom); } textureBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Add scene objects or prefabs to combine. For best results these should use the same shader as result material.\n\n" + "2. Create Empty Assets For Combined Material(s)\n\n" + "3. Check that shader on result material(s) are correct.\n\n" + "4. Bake materials into combined material(s).\n\n" + "5. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "6. You are now ready to build combined meshs or adjust meshes to use the combined material(s).", UnityEditor.MessageType.None); } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (GUILayout.Button(openToolsWindowLabelContent)) { MB2_MeshBakerEditorWindowInterface mmWin = (MB2_MeshBakerEditorWindowInterface)EditorWindow.GetWindow(editorWindow); mmWin.target = (MB2_MeshBakerRoot)mom; } EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); if (GUILayout.Button(createPrefabAndMaterialLabelContent)) { string newPrefabPath = EditorUtility.SaveFilePanelInProject("Asset name", "", "asset", "Enter a name for the baked texture results"); if (newPrefabPath != null) { CreateCombinedMaterialAssets(mom, newPrefabPath); } } EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent); if (textureBakeResults.objectReferenceValue != null) { showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport) { EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } EditorGUILayout.PropertyField(doMultiMaterial, new GUIContent("Multiple Combined Materials")); if (mom.doMultiMaterial) { EditorGUILayout.LabelField("Source Material To Combined Mapping", EditorStyles.boldLabel); if (GUILayout.Button(configMultiMatFromObjsContent)) { ConfigureMutiMaterialsFromObjsToCombine(mom); } EditorGUILayout.BeginHorizontal(); resultMaterialsFoldout = EditorGUILayout.Foldout(resultMaterialsFoldout, combinedMaterialsGUIContent); if (GUILayout.Button(insertContent, EditorStyles.miniButtonLeft, buttonWidth)) { if (resultMaterials.arraySize == 0) { mom.resultMaterials = new MB_MultiMaterial[1]; } else { resultMaterials.InsertArrayElementAtIndex(resultMaterials.arraySize - 1); } } if (GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)) { resultMaterials.DeleteArrayElementAtIndex(resultMaterials.arraySize - 1); } EditorGUILayout.EndHorizontal(); if (resultMaterialsFoldout) { for (int i = 0; i < resultMaterials.arraySize; i++) { EditorGUILayout.Separator(); string s = ""; if (i < mom.resultMaterials.Length && mom.resultMaterials[i] != null && mom.resultMaterials[i].combinedMaterial != null) { s = mom.resultMaterials[i].combinedMaterial.shader.ToString(); } EditorGUILayout.LabelField("---------- submesh:" + i + " " + s, EditorStyles.boldLabel); EditorGUILayout.Separator(); SerializedProperty resMat = resultMaterials.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(resMat.FindPropertyRelative("combinedMaterial")); SerializedProperty sourceMats = resMat.FindPropertyRelative("sourceMaterials"); EditorGUILayout.PropertyField(sourceMats, true); } } } else { EditorGUILayout.PropertyField(resultMaterial, new GUIContent("Combined Mesh Material")); } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material Bake Options", EditorStyles.boldLabel); EditorGUILayout.PropertyField(atlasPadding, new GUIContent("Atlas Padding")); EditorGUILayout.PropertyField(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent); EditorGUILayout.PropertyField(customShaderPropNames, customShaderPropertyNamesGUIContent, true); EditorGUILayout.PropertyField(maxTilingBakeSize, maxTilingBakeSizeGUIContent); EditorGUILayout.PropertyField(fixOutOfBoundsUVs, fixOutOfBoundsGUIContent); if (texturePackingAlgorithm.intValue == (int)MB2_PackingAlgorithmEnum.UnitysPackTextures) { EditorGUILayout.HelpBox("Unity's texture packer has memory problems and frequently crashes the editor.", MessageType.Warning); } EditorGUILayout.PropertyField(texturePackingAlgorithm, texturePackingAgorithmGUIContent); EditorGUILayout.Separator(); if (GUILayout.Button("Bake Materials Into Combined Material")) { mom.CreateAtlases(updateProgressBar, true, new MB2_EditorMethods()); EditorUtility.ClearProgressBar(); if (mom.textureBakeResults != null) { EditorUtility.SetDirty(mom.textureBakeResults); } } textureBaker.ApplyModifiedProperties(); textureBaker.SetIsDifferentCacheDirty(); }
void OnGUI() { scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height)); EditorGUILayout.LabelField("Generate Report",EditorStyles.boldLabel); EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None); if (GUILayout.Button("List Shaders In Scene")){ listMaterialsInScene(false); } EditorGUILayout.Separator(); MB_EditorUtil.DrawSeparator(); EditorGUILayout.HelpBox("This feature is experimental. It should be safe to use as all it does is generate game objects with Mesh and Material bakers "+ "on them and assets for the combined materials.\n\n" + "Creates bakers and combined material assets in your scene based on the groupings in 'Generate Report'."+ "Some configuration may still be required after bakers are generated. Groups are created for objects that " + "use the same material(s), shader(s) and lightmap. These groups should produce good results when baked.\n\n" + "This feature groups objects conservatively so bakes almost always work. This is not the only way to group objects. Objects with different shaders can also be grouped but results are" + " less preditable. Meshes with submeshes are only" + "grouped if all meshes use the same set of shaders.", UnityEditor.MessageType.None); EditorGUILayout.LabelField(autoGenerateGUIContent, EditorStyles.boldLabel); autoGenerateMeshBakers = EditorGUILayout.Foldout(autoGenerateMeshBakers,"Show Tools"); if ( autoGenerateMeshBakers ){ EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Folder For Combined Material Assets") ){ generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", ""); generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(Application.dataPath, "") + "/"; } EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Included Objects Must Be Static", GUILayout.Width(200)); generate_IncludeStaticObjects = EditorGUILayout.Toggle(GUIContent.none, generate_IncludeStaticObjects); EditorGUILayout.EndHorizontal(); generate_LightmapOption = (LightMapOption) EditorGUILayout.EnumPopup("Lightmapping", generate_LightmapOption); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Generate Mesh Bakers")){ listMaterialsInScene(true); } if (GUILayout.Button("Bake Every MeshBaker In Scene")){ try{ MB2_TextureBaker[] texBakers = (MB2_TextureBaker[]) FindObjectsOfType(typeof(MB2_TextureBaker)); for (int i = 0; i < texBakers.Length; i++){ texBakers[i].CreateAtlases(updateProgressBar, true, new MB2_EditorMethods()); } MB2_MeshBaker[] mBakers = (MB2_MeshBaker[]) FindObjectsOfType(typeof(MB2_MeshBaker)); for (int i = 0; i < mBakers.Length; i++){ if (mBakers[i].textureBakeResults != null){ MB2_MeshBakerEditorFunctions._bakeIntoCombined(mBakers[i], MB_OutputOptions.bakeIntoSceneObject); } } } catch (Exception e) { Debug.LogError(e); }finally{ EditorUtility.ClearProgressBar(); } } EditorGUILayout.EndHorizontal(); } MB_EditorUtil.DrawSeparator(); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Add Selected Meshes To Bakers",EditorStyles.boldLabel); EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None); target = (MB2_MeshBakerRoot) EditorGUILayout.ObjectField("Target to add objects to",target,typeof(MB2_MeshBakerRoot),true); if (target != null){ targetGO = target.gameObject; } else { targetGO = null; } if (targetGO != oldTargetGO){ textureBaker = targetGO.GetComponent<MB2_TextureBaker>(); meshBaker = targetGO.GetComponent<MB2_MeshBaker>(); tbe = new MB2_TextureBakerEditorInternal(); mbe = new MB2_MeshBakerEditorInternal(); oldTargetGO = targetGO; } onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects); onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects); excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs); mat = (Material) EditorGUILayout.ObjectField("Using Material",mat,typeof(Material),true); shaderMat = (Material) EditorGUILayout.ObjectField("Using Shader",shaderMat,typeof(Material),true); string[] lightmapDisplayValues = new string[257]; int[] lightmapValues = new int[257]; lightmapValues[0] = -2; lightmapValues[1] = -1; lightmapDisplayValues[0] = "don't filter on lightmapping"; lightmapDisplayValues[1] = "not lightmapped"; for (int i = 2; i < lightmapDisplayValues.Length; i++){ lightmapDisplayValues[i] = "" + i; lightmapValues[i] = i; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Using Lightmap Index "); lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex, lightmapDisplayValues, lightmapValues); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Add Selected Meshes")){ addSelectedObjects(); } /* if (GUILayout.Button("Add LOD To Selected")){ addLODToSelected(); } if (GUILayout.Button("Remove LOD From All")){ LODInternal[] lods = (LODInternal[]) FindObjectsOfType(typeof(LODInternal)); for (int i = 0; i < lods.Length; i++){ DestroyImmediate(lods[i]); } } */ if (textureBaker != null){ MB_EditorUtil.DrawSeparator(); tbFoldout = EditorGUILayout.Foldout(tbFoldout,"Texture Baker"); if (tbFoldout){ tbe.DrawGUI((MB2_TextureBaker) textureBaker, typeof(MB_MeshBakerEditorWindow)); } } if (meshBaker != null){ MB_EditorUtil.DrawSeparator(); mbFoldout = EditorGUILayout.Foldout(mbFoldout,"Mesh Baker"); if (mbFoldout){ mbe.DrawGUI((MB2_MeshBaker) meshBaker, typeof(MB_MeshBakerEditorWindow)); } } EditorGUILayout.EndScrollView(); }
public static void _bakeIntoCombined(MB2_MeshBakerCommon mom, MB_OutputOptions prefabOrSceneObject) { if (MB2_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab) { Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return; } if (prefabOrSceneObject != MB_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB_OutputOptions.bakeIntoSceneObject) { Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return; } //MB2_MeshBakerCommon mom = (MB2_MeshBakerCommon) target; MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (mom.textureBakeResults == null && tb != null) { Debug.Log("setting results"); mom.textureBakeResults = tb.textureBakeResults; } if (mom.useObjsToMeshFromTexBaker) { if (tb != null) { mom.GetObjectsToCombine().Clear(); mom.GetObjectsToCombine().AddRange(tb.GetObjectsToCombine()); } } Mesh mesh; if (!MB2_MeshBakerRoot.doCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB2_EditorMethods())) { return; } if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab && mom.resultPrefab == null) { Debug.LogError("Need to set the Combined Mesh Prefab field. Create a prefab asset, drag an empty game object into it, and drag it to the 'Combined Mesh Prefab' field."); return; } mom.ClearMesh(); mesh = mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(), null, false, true); if (mesh != null) { mom.Apply(Unwrapping.GenerateSecondaryUVSet); Debug.Log(String.Format("Successfully baked {0} meshes into a combined mesh", mom.GetObjectsToCombine().Count)); if (prefabOrSceneObject == MB_OutputOptions.bakeIntoSceneObject) { PrefabType pt = PrefabUtility.GetPrefabType(mom.resultSceneObject); if (pt == PrefabType.Prefab || pt == PrefabType.ModelPrefab) { Debug.LogError("Combined Mesh Object is a prefab asset. If output option bakeIntoSceneObject then this must be an instance in the scene."); return; } } else if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab) { string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab); if (prefabPth == null || prefabPth.Length == 0) { Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset."); return; } string baseName = Path.GetFileNameWithoutExtension(prefabPth); string folderPath = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7); string newFilename = folderPath + baseName + "-mesh"; SaveMeshsToAssetDatabase(mom, folderPath, newFilename); if (mom.renderType == MB_RenderType.skinnedMeshRenderer) { Debug.LogWarning("Render type is skinned mesh renderer. " + "Can't create prefab until all bones have been added to the combined mesh object " + mom.resultPrefab + " Add the bones then drag the combined mesh object to the prefab."); } else { RebuildPrefab(mom); } } else { Debug.LogError("Unknown parameter"); } } }
public void DrawGUI(MB2_TextureBaker mom) { if (meshBaker == null) { _init(mom); } meshBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Create Empty Assets For Combined Material(s)\n\n" + "2. Select shader on result material(s).\n\n" + "3. Add scene objects or prefabs to combine. For best results these should use the same shader as result material.\n\n" + "4. Bake materials into combined material(s).\n\n" + "5. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "6. You are now ready to build combined meshs or adjust meshes to use the combined material(s).", UnityEditor.MessageType.None); } //MB2_TextureBaker mom = (MB2_TextureBaker) target; EditorGUILayout.Separator(); EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); if (GUILayout.Button(createPrefabAndMaterialLabelContent)) { string newPrefabPath = EditorUtility.SaveFilePanelInProject("Asset name", "", "asset", "Enter a name for the baked texture results"); if (newPrefabPath != null) { createCombinedMaterialAssets(mom, newPrefabPath); } } EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent); EditorGUILayout.PropertyField(doMultiMaterial, new GUIContent("Multiple Combined Materials")); if (mom.doMultiMaterial) { EditorGUILayout.LabelField("Source Material To Combined Mapping", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); resultMaterialsFoldout = EditorGUILayout.Foldout(resultMaterialsFoldout, combinedMaterialsGUIContent); if (GUILayout.Button(insertContent, EditorStyles.miniButtonLeft, buttonWidth)) { if (resultMaterials.arraySize == 0) { mom.resultMaterials = new MB_MultiMaterial[1]; } else { resultMaterials.InsertArrayElementAtIndex(resultMaterials.arraySize - 1); } } if (GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)) { resultMaterials.DeleteArrayElementAtIndex(resultMaterials.arraySize - 1); } EditorGUILayout.EndHorizontal(); if (resultMaterialsFoldout) { for (int i = 0; i < resultMaterials.arraySize; i++) { EditorGUILayout.Separator(); EditorGUILayout.LabelField("---------- submesh:" + i, EditorStyles.boldLabel); EditorGUILayout.Separator(); SerializedProperty resMat = resultMaterials.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(resMat.FindPropertyRelative("combinedMaterial")); SerializedProperty sourceMats = resMat.FindPropertyRelative("sourceMaterials"); EditorGUILayout.PropertyField(sourceMats, true); } } } else { EditorGUILayout.PropertyField(resultMaterial, new GUIContent("Combined Mesh Material")); } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (GUILayout.Button(openToolsWindowLabelContent)) { MB_MeshBakerEditorWindow mmWin = (MB_MeshBakerEditorWindow)EditorWindow.GetWindow(typeof(MB_MeshBakerEditorWindow)); mmWin.target = (MB2_MeshBakerRoot)mom; } EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material Bake Options", EditorStyles.boldLabel); EditorGUILayout.PropertyField(atlasPadding, new GUIContent("Atlas Padding")); EditorGUILayout.PropertyField(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent); EditorGUILayout.PropertyField(customShaderPropNames, customShaderPropertyNamesGUIContent, true); EditorGUILayout.PropertyField(maxTilingBakeSize, maxTilingBakeSizeGUIContent); EditorGUILayout.PropertyField(fixOutOfBoundsUVs, fixOutOfBoundsGUIContent); EditorGUILayout.Separator(); if (GUILayout.Button("Bake Materials Into Combined Material")) { bake(mom); } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }
public void ConfigureMutiMaterialsFromObjsToCombine(MB2_TextureBaker mom) { if (mom.objsToMesh.Count == 0) { Debug.LogError("You need to add some objects to combine before building the multi material list."); return; } if (resultMaterials.arraySize > 0) { Debug.LogError("You already have some source to combined material mappings configured. You must remove these before doing this operation."); return; } if (mom.textureBakeResults == null) { Debug.LogError("Material Bake Result asset must be set before using this operation."); return; } Dictionary <Shader, List <Material> > shader2Material_map = new Dictionary <Shader, List <Material> >(); Dictionary <Material, Mesh> obUVobject2material_map = new Dictionary <Material, Mesh>(); for (int i = 0; i < mom.objsToMesh.Count; i++) { GameObject go = mom.objsToMesh[i]; if (go == null) { Debug.LogError("Null object in list of objects to combine at position " + i); return; } Renderer r = go.GetComponent <Renderer>(); if (r == null || (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer))) { Debug.LogError("GameObject at position " + i + " in list of objects to combine did not have a renderer"); return; } if (r.sharedMaterial == null) { Debug.LogError("GameObject at position " + i + " in list of objects to combine has a null material"); return; } Mesh m = MB_Utility.GetMesh(go); Rect dummy = new Rect(); for (int j = 0; j < r.sharedMaterials.Length; j++) { if (MB_Utility.hasOutOfBoundsUVs(m, ref dummy, j)) { if (!obUVobject2material_map.ContainsKey(r.sharedMaterials[j])) { Debug.LogWarning("Object " + go + " submesh " + j + " uses UVs outside the range 0,0..1,1 to generate tiling. This object has been mapped to its own submesh in the combined mesh. It can share a submesh with other objects that use different materials if you use the fix out of bounds UVs feature which will bake the tiling"); obUVobject2material_map.Add(r.sharedMaterials[j], m); } } else if (!obUVobject2material_map.ContainsKey(r.sharedMaterials[j])) { if (r.sharedMaterials[j] == null) { continue; } List <Material> matsThatUseShader = null;; if (!shader2Material_map.TryGetValue(r.sharedMaterials[j].shader, out matsThatUseShader)) { matsThatUseShader = new List <Material>(); shader2Material_map.Add(r.sharedMaterials[j].shader, matsThatUseShader); } if (!matsThatUseShader.Contains(r.sharedMaterials[j])) { matsThatUseShader.Add(r.sharedMaterials[j]); } } } } if (shader2Material_map.Count == 0 && obUVobject2material_map.Count == 0) { Debug.LogError("Found no materials in list of objects to combine"); } mom.resultMaterials = new MB_MultiMaterial[shader2Material_map.Count + obUVobject2material_map.Count]; string pth = AssetDatabase.GetAssetPath(mom.textureBakeResults); string baseName = Path.GetFileNameWithoutExtension(pth); string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6); int k = 0; foreach (Shader sh in shader2Material_map.Keys) { List <Material> matsThatUse = shader2Material_map[sh]; MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = matsThatUse; string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(Shader.Find("Diffuse")); if (matsThatUse.Count > 0 && matsThatUse[0] != null) { MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, matsThatUse[0]); } AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material)); k++; } foreach (Material m in obUVobject2material_map.Keys) { MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = new List <Material>(); mm.sourceMaterials.Add(m); string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(Shader.Find("Diffuse")); MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, m); AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material)); k++; } textureBaker.UpdateIfDirtyOrScript(); }
void OnGUI() { scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height)); EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for grouping objects to be combined. SkinnedMeshRenderers are ignored.", UnityEditor.MessageType.None); if (GUILayout.Button("List Shaders In Scene")) { listMaterialsInScene(); } EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None); target = (MB2_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB2_MeshBakerRoot), true); if (target != null) { targetGO = target.gameObject; } else { targetGO = null; } if (targetGO != oldTargetGO) { textureBaker = targetGO.GetComponent <MB2_TextureBaker>(); meshBaker = targetGO.GetComponent <MB2_MeshBaker>(); tbe = new MB2_TextureBakerEditorInternal(); mbe = new MB2_MeshBakerEditorInternal(); oldTargetGO = targetGO; } onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects); mat = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true); shaderMat = (Material)EditorGUILayout.ObjectField("Using Shader", shaderMat, typeof(Material), true); if (GUILayout.Button("Add Selected Meshes")) { addSelectedObjects(); } if (textureBaker != null) { MB_EditorUtil.DrawSeparator(); tbFoldout = EditorGUILayout.Foldout(tbFoldout, "Texture Baker"); if (tbFoldout) { tbe.DrawGUI((MB2_TextureBaker)textureBaker); } } if (meshBaker != null) { MB_EditorUtil.DrawSeparator(); mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker"); if (mbFoldout) { mbe.DrawGUI((MB2_MeshBaker)meshBaker); } } EditorGUILayout.EndScrollView(); }
public static void _bakeIntoCombined(MB2_MeshBakerCommon mom, MB_OutputOptions prefabOrSceneObject) { if (MB2_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab) { Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return; } if (prefabOrSceneObject != MB_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB_OutputOptions.bakeIntoSceneObject) { Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return; } //MB2_MeshBakerCommon mom = (MB2_MeshBakerCommon) target; MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (mom.textureBakeResults == null && tb != null) { Debug.Log("setting results"); mom.textureBakeResults = tb.textureBakeResults; } if (mom.useObjsToMeshFromTexBaker) { if (tb != null) { mom.objsToMesh.Clear(); mom.objsToMesh.AddRange(tb.objsToMesh); } } Mesh mesh; if (!MB2_MeshBakerRoot.doCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly)) { return; } if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab && mom.resultPrefab == null) { Debug.LogError("Need to set the Combined Mesh Prefab field."); return; } mom.ClearMesh(); mesh = mom.AddDeleteGameObjects(mom.objsToMesh.ToArray(), null, false, true); if (mesh != null) { mom.Apply(); // updateProgressBar("Created mesh saving assets",.6f); if (prefabOrSceneObject == MB_OutputOptions.bakeIntoSceneObject) { // mom.BuildSceneMeshObject(); } else if (prefabOrSceneObject == MB_OutputOptions.bakeIntoPrefab) { string prefabPth = AssetDatabase.GetAssetPath(mom.resultPrefab); if (prefabPth == null || prefabPth.Length == 0) { Debug.LogError("Could not save result to prefab. Result Prefab value is not an Asset."); return; } string baseName = Path.GetFileNameWithoutExtension(prefabPth); string folderPath = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7); string newFilename = folderPath + baseName + "-mesh"; mom.SaveMeshsToAssetDatabase(folderPath, newFilename); if (mom.renderType == MB_RenderType.skinnedMeshRenderer) { Debug.LogWarning("Render type is skinned mesh renderer. " + "Can't create prefab until all bones have been added to the combined mesh object " + mom.resultPrefab + " Add the bones then drag the combined mesh object to the prefab."); } else { mom.RebuildPrefab(); } } else { Debug.LogError("Unknown parameter"); } } }
public static void CreateCombinedMaterialAssets(MB2_TextureBaker target, string pth){ MB2_TextureBaker mom = (MB2_TextureBaker) target; string baseName = Path.GetFileNameWithoutExtension(pth); if (baseName == null || baseName.Length == 0) return; string folderPath = pth.Substring(0,pth.Length - baseName.Length - 6); List<string> matNames = new List<string>(); if (mom.doMultiMaterial){ for (int i = 0; i < mom.resultMaterials.Length; i++){ matNames.Add( folderPath + baseName + "-mat" + i + ".mat" ); AssetDatabase.CreateAsset(new Material(Shader.Find("Diffuse")), matNames[i]); mom.resultMaterials[i].combinedMaterial = (Material) AssetDatabase.LoadAssetAtPath(matNames[i],typeof(Material)); } }else{ matNames.Add( folderPath + baseName + "-mat.mat" ); Material newMat = new Material(Shader.Find("Diffuse")); if (mom.objsToMesh.Count > 0 && mom.objsToMesh[0] != null){ Renderer r = mom.objsToMesh[0].GetComponent<Renderer>(); if (r == null){ Debug.LogWarning("Object " + mom.objsToMesh[0] + " does not have a Renderer on it."); } else { if (r.sharedMaterial != null){ newMat.shader = r.sharedMaterial.shader; MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat,r.sharedMaterial); } } } else { Debug.Log("If you add objects to be combined before creating the Combined Material Assets. Then Mesh Baker will create a result material that is a duplicate of the material on the first object to be combined. This saves time configuring the shader."); } AssetDatabase.CreateAsset(newMat, matNames[0]); mom.resultMaterial = (Material) AssetDatabase.LoadAssetAtPath(matNames[0],typeof(Material)); } //create the MB2_TextureBakeResults AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<MB2_TextureBakeResults>(),pth); mom.textureBakeResults = (MB2_TextureBakeResults) AssetDatabase.LoadAssetAtPath(pth, typeof(MB2_TextureBakeResults)); AssetDatabase.Refresh(); }
public void DrawGUI(MB2_TextureBaker mom, System.Type editorWindow){ if (textureBaker == null){ _init(mom); } textureBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions,"Instructions:"); if (showInstructions){ EditorGUILayout.HelpBox("1. Add scene objects or prefabs to combine. For best results these should use the same shader as result material.\n\n" + "2. Create Empty Assets For Combined Material(s)\n\n" + "3. Check that shader on result material(s) are correct.\n\n" + "4. Bake materials into combined material(s).\n\n" + "5. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "6. You are now ready to build combined meshs or adjust meshes to use the combined material(s).", UnityEditor.MessageType.None); } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Objects To Be Combined",EditorStyles.boldLabel); if (GUILayout.Button(openToolsWindowLabelContent)){ MB2_MeshBakerEditorWindowInterface mmWin = (MB2_MeshBakerEditorWindowInterface) EditorWindow.GetWindow(editorWindow); mmWin.target = (MB2_MeshBakerRoot) mom; } EditorGUILayout.PropertyField(objsToMesh,objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Output",EditorStyles.boldLabel); if (GUILayout.Button(createPrefabAndMaterialLabelContent)){ string newPrefabPath = EditorUtility.SaveFilePanelInProject("Asset name", "", "asset", "Enter a name for the baked texture results"); if (newPrefabPath != null){ CreateCombinedMaterialAssets(mom, newPrefabPath); } } EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent); if (textureBakeResults.objectReferenceValue != null){ showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport){ EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } EditorGUILayout.PropertyField(doMultiMaterial,new GUIContent("Multiple Combined Materials")); if (mom.doMultiMaterial){ EditorGUILayout.LabelField("Source Material To Combined Mapping",EditorStyles.boldLabel); if (GUILayout.Button(configMultiMatFromObjsContent)){ ConfigureMutiMaterialsFromObjsToCombine(mom); } EditorGUILayout.BeginHorizontal(); resultMaterialsFoldout = EditorGUILayout.Foldout(resultMaterialsFoldout, combinedMaterialsGUIContent); if(GUILayout.Button(insertContent, EditorStyles.miniButtonLeft, buttonWidth)){ if (resultMaterials.arraySize == 0){ mom.resultMaterials = new MB_MultiMaterial[1]; } else { resultMaterials.InsertArrayElementAtIndex(resultMaterials.arraySize-1); } } if(GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)){ resultMaterials.DeleteArrayElementAtIndex(resultMaterials.arraySize-1); } EditorGUILayout.EndHorizontal(); if (resultMaterialsFoldout){ for(int i = 0; i < resultMaterials.arraySize; i++){ EditorGUILayout.Separator(); string s = ""; if (i < mom.resultMaterials.Length && mom.resultMaterials[i] != null && mom.resultMaterials[i].combinedMaterial != null) s = mom.resultMaterials[i].combinedMaterial.shader.ToString(); EditorGUILayout.LabelField("---------- submesh:" + i + " " + s,EditorStyles.boldLabel); EditorGUILayout.Separator(); SerializedProperty resMat = resultMaterials.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(resMat.FindPropertyRelative("combinedMaterial")); SerializedProperty sourceMats = resMat.FindPropertyRelative("sourceMaterials"); EditorGUILayout.PropertyField(sourceMats,true); } } } else { EditorGUILayout.PropertyField(resultMaterial,new GUIContent("Combined Mesh Material")); } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Material Bake Options",EditorStyles.boldLabel); EditorGUILayout.PropertyField(atlasPadding,new GUIContent("Atlas Padding")); EditorGUILayout.PropertyField(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent); EditorGUILayout.PropertyField(customShaderPropNames,customShaderPropertyNamesGUIContent,true); EditorGUILayout.PropertyField(maxTilingBakeSize, maxTilingBakeSizeGUIContent); EditorGUILayout.PropertyField(fixOutOfBoundsUVs,fixOutOfBoundsGUIContent); if (texturePackingAlgorithm.intValue == (int) MB2_PackingAlgorithmEnum.UnitysPackTextures){ EditorGUILayout.HelpBox("Unity's texture packer has memory problems and frequently crashes the editor.",MessageType.Warning); } EditorGUILayout.PropertyField(texturePackingAlgorithm, texturePackingAgorithmGUIContent); EditorGUILayout.Separator(); if (GUILayout.Button("Bake Materials Into Combined Material")){ mom.CreateAtlases(updateProgressBar, true, new MB2_EditorMethods()); EditorUtility.ClearProgressBar(); if (mom.textureBakeResults != null) EditorUtility.SetDirty(mom.textureBakeResults); } textureBaker.ApplyModifiedProperties(); textureBaker.SetIsDifferentCacheDirty(); }
void OnGUI() { scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height)); EditorGUILayout.LabelField("Generate Report", EditorStyles.boldLabel); EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None); if (GUILayout.Button("List Shaders In Scene")) { listMaterialsInScene(false); } EditorGUILayout.Separator(); MB_EditorUtil.DrawSeparator(); EditorGUILayout.HelpBox("Creates bakers and combined material assets in your scene based on the groupings in 'Generate Report'." + "Some configuration may still be required after bakers are generated. Groups are created for objects that " + "use the same material(s), shader(s) and lightmap. These groups should produce good results when baked.\n\n" + "This feature groups objects conservatively so bakes almost always work. This is not the only way to group objects. Objects with different shaders can also be grouped but results are" + " less preditable. Meshes with submeshes are only" + "grouped if all meshes use the same set of shaders.", UnityEditor.MessageType.None); EditorGUILayout.LabelField(autoGenerateGUIContent, EditorStyles.boldLabel); autoGenerateMeshBakers = EditorGUILayout.Foldout(autoGenerateMeshBakers, "Show Tools"); if (autoGenerateMeshBakers) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Folder For Combined Material Assets")) { generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", ""); generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(UnityEngine.Application.dataPath, "") + "/"; } EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Included Objects Must Be Static", GUILayout.Width(200)); generate_IncludeStaticObjects = EditorGUILayout.Toggle(GUIContent.none, generate_IncludeStaticObjects); EditorGUILayout.EndHorizontal(); generate_LightmapOption = (LightMapOption)EditorGUILayout.EnumPopup("Lightmapping", generate_LightmapOption); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Generate Mesh Bakers")) { listMaterialsInScene(true); } if (GUILayout.Button("Bake Every MeshBaker In Scene")) { try{ MB2_TextureBaker[] texBakers = (MB2_TextureBaker[])FindObjectsOfType(typeof(MB2_TextureBaker)); for (int i = 0; i < texBakers.Length; i++) { texBakers[i].CreateAndSaveAtlases(updateProgressBar, System.IO.File.WriteAllBytes); } MB2_MeshBaker[] mBakers = (MB2_MeshBaker[])FindObjectsOfType(typeof(MB2_MeshBaker)); for (int i = 0; i < mBakers.Length; i++) { if (mBakers[i].textureBakeResults != null) { MB2_MeshBakerEditorInternal._bakeIntoCombined(mBakers[i], MB_OutputOptions.bakeIntoSceneObject); } } } catch (Exception e) { Debug.LogError(e); }finally{ EditorUtility.ClearProgressBar(); } } EditorGUILayout.EndHorizontal(); } MB_EditorUtil.DrawSeparator(); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Add Selected Meshes To Bakers", EditorStyles.boldLabel); EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None); target = (MB2_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB2_MeshBakerRoot), true); if (target != null) { targetGO = target.gameObject; } else { targetGO = null; } if (targetGO != oldTargetGO) { textureBaker = targetGO.GetComponent <MB2_TextureBaker>(); meshBaker = targetGO.GetComponent <MB2_MeshBaker>(); tbe = new MB2_TextureBakerEditorInternal(); mbe = new MB2_MeshBakerEditorInternal(); oldTargetGO = targetGO; } onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects); onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects); excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs); mat = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true); shaderMat = (Material)EditorGUILayout.ObjectField("Using UnityEngine.Shader", shaderMat, typeof(Material), true); string[] lightmapDisplayValues = new string[257]; int[] lightmapValues = new int[257]; lightmapValues[0] = -2; lightmapValues[1] = -1; lightmapDisplayValues[0] = "don't filter on lightmapping"; lightmapDisplayValues[1] = "not lightmapped"; for (int i = 2; i < lightmapDisplayValues.Length; i++) { lightmapDisplayValues[i] = "" + i; lightmapValues[i] = i; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Using Lightmap Index "); lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex, lightmapDisplayValues, lightmapValues); EditorGUILayout.EndHorizontal(); if (GUILayout.Button("Add Selected Meshes")) { addSelectedObjects(); } /* * if (GUILayout.Button("Add LOD To Selected")){ * addLODToSelected(); * } * * if (GUILayout.Button("Remove LOD From All")){ * MB2_LOD[] lods = (MB2_LOD[]) FindObjectsOfType(typeof(MB2_LOD)); * for (int i = 0; i < lods.Length; i++){ * DestroyImmediate(lods[i]); * } * } */ if (textureBaker != null) { MB_EditorUtil.DrawSeparator(); tbFoldout = EditorGUILayout.Foldout(tbFoldout, "UnityEngine.Texture Baker"); if (tbFoldout) { tbe.DrawGUI((MB2_TextureBaker)textureBaker); } } if (meshBaker != null) { MB_EditorUtil.DrawSeparator(); mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker"); if (mbFoldout) { mbe.DrawGUI((MB2_MeshBaker)meshBaker); } } EditorGUILayout.EndScrollView(); }
void createAndSetupBaker(List <_GameObjectAndWarning> gaws, string pthRoot) { if (gaws.Count < 1) { return; } int numVerts = 0; for (int i = 0; i < gaws.Count; i++) { numVerts = gaws[i].numVerts; } UnityEngine.GameObject newMeshBaker = null; if (numVerts >= 65535) { newMeshBaker = MB2_MultiMeshBakerEditor.CreateNewMeshBaker(); } else { newMeshBaker = MB2_MeshBakerEditor.CreateNewMeshBaker(); } newMeshBaker.name = ("MeshBaker-" + gaws[0].shader.name + "-LM" + gaws[0].lightmapIndex).ToString().Replace("/", "-"); MB2_TextureBaker tb = newMeshBaker.GetComponent <MB2_TextureBaker>(); //string pth = AssetDatabase.GenerateUniqueAssetPath(pthRoot); //create result material string pthMat = AssetDatabase.GenerateUniqueAssetPath(pthRoot + newMeshBaker.name + ".mat"); AssetDatabase.CreateAsset(new Material(UnityEngine.Shader.Find("Diffuse")), pthMat); tb.resultMaterial = (Material)AssetDatabase.LoadAssetAtPath(pthMat, typeof(Material)); //create the MB2_TextureBakeResults string pthAsset = AssetDatabase.GenerateUniqueAssetPath(pthRoot + newMeshBaker.name + ".asset"); AssetDatabase.CreateAsset(ScriptableObject.CreateInstance <MB2_TextureBakeResults>(), pthAsset); tb.textureBakeResults = (MB2_TextureBakeResults)AssetDatabase.LoadAssetAtPath(pthAsset, typeof(MB2_TextureBakeResults)); AssetDatabase.Refresh(); tb.resultMaterial.shader = gaws[0].shader; tb.objsToMesh = new List <UnityEngine.GameObject>(); for (int i = 0; i < gaws.Count; i++) { tb.objsToMesh.Add(gaws[i].go); } MB2_MeshBakerCommon mb = newMeshBaker.GetComponent <MB2_MeshBakerCommon>(); if (generate_LightmapOption == LightMapOption.ignore) { mb.lightmapOption = MB2_LightmapOptions.ignore_UV2; } else { if (gaws[0].lightmapIndex == -1 || gaws[0].lightmapIndex == -2) { mb.lightmapOption = MB2_LightmapOptions.ignore_UV2; } else { mb.lightmapOption = MB2_LightmapOptions.preserve_current_lightmapping; } } }
public static bool doCombinedValidate(MB2_MeshBakerRoot mom, MB_ObjsToCombineTypes objToCombineType) { // MB2_MeshBaker mom = (MB2_MeshBaker) target; if (mom.textureBakeResults == null) { Debug.LogError("Need to set textureBakeResults"); return(false); } if (!(mom is MB2_TextureBaker)) { MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (tb != null && tb.textureBakeResults != mom.textureBakeResults) { Debug.LogWarning("textureBakeResults on this component is not the same as the textureBakeResults on the MB2_TextureBaker."); } } List <GameObject> objsToMesh = mom.GetObjectsToCombine(); for (int i = 0; i < objsToMesh.Count; i++) { GameObject go = objsToMesh[i]; if (go == null) { Debug.LogError("The list of objects to combine contains nulls."); return(false); } for (int j = i + 1; j < objsToMesh.Count; j++) { if (objsToMesh[i] == objsToMesh[j]) { Debug.LogError("The list of objects to combine contains duplicates."); return(false); } } if (MB_Utility.GetGOMaterials(go) == null) { Debug.LogError("Object " + go + " in the list of objects to be combined does not have a material"); return(false); } if (MB_Utility.GetMesh(go) == null) { Debug.LogError("Object " + go + " in the list of objects to be combined does not have a mesh"); return(false); } } if (mom.textureBakeResults.doMultiMaterial) { if (!validateSubmeshOverlap(mom)) //only warns currently { return(false); } } List <GameObject> objs = objsToMesh; if (mom is MB2_MeshBaker) { MB2_TextureBaker tb = mom.GetComponent <MB2_TextureBaker>(); if (((MB2_MeshBaker)mom).useObjsToMeshFromTexBaker && tb != null) { objs = tb.objsToMesh; } if (objs == null || objs.Count == 0) { Debug.LogError("No meshes to combine. Please assign some meshes to combine."); return(false); } } #if UNITY_EDITOR for (int i = 0; i < objsToMesh.Count; i++) { UnityEditor.PrefabType pt = UnityEditor.PrefabUtility.GetPrefabType(objsToMesh[i]); if (pt == UnityEditor.PrefabType.None || pt == UnityEditor.PrefabType.PrefabInstance || pt == UnityEditor.PrefabType.ModelPrefabInstance || pt == UnityEditor.PrefabType.DisconnectedPrefabInstance || pt == UnityEditor.PrefabType.DisconnectedModelPrefabInstance) { // these are scene objects if (objToCombineType == MB_ObjsToCombineTypes.prefabOnly) { Debug.LogWarning("The list of objects to combine contains scene objects. You probably want prefabs." + objsToMesh[i] + " is a scene object"); } } else if (objToCombineType == MB_ObjsToCombineTypes.sceneObjOnly) { //these are prefabs Debug.LogWarning("The list of objects to combine contains prefab objects. You probably want scene objects." + objsToMesh[i] + " is a prefab object"); } } #endif return(true); }
public void ConfigureMutiMaterialsFromObjsToCombine(MB2_TextureBaker mom) { if (mom.objsToMesh.Count == 0) { Debug.LogError("You need to add some objects to combine before building the multi material list."); return; } if (resultMaterials.arraySize > 0) { Debug.LogError("You already have some source to combined material mappings configured. You must remove these before doing this operation."); return; } if (mom.textureBakeResults == null) { Debug.LogError("Material Bake Result asset must be set before using this operation."); return; } Dictionary <UnityEngine.Shader, List <Material> > shader2Material_map = new Dictionary <UnityEngine.Shader, List <Material> >(); bool hasOutOfBoundsUVs = false; for (int i = 0; i < mom.objsToMesh.Count; i++) { UnityEngine.GameObject go = mom.objsToMesh[i]; if (go == null) { Debug.LogError("Null object in list of objects to combine at position " + i); return; } UnityEngine.Renderer r = go.GetComponent <UnityEngine.Renderer>(); if (r == null || (!(r is MeshRenderer) && !(r is SkinnedMeshRenderer))) { Debug.LogError("UnityEngine.GameObject at position " + i + " in list of objects to combine did not have a renderer"); return; } Mesh m = MB_Utility.GetMesh(go); Rect dummy = new Rect(); if (MB_Utility.hasOutOfBoundsUVs(m, ref dummy, -1)) { hasOutOfBoundsUVs = true; } for (int j = 0; j < r.sharedMaterials.Length; j++) { if (r.sharedMaterials[j] == null) { continue; } List <Material> matsThatUseShader = null;; if (!shader2Material_map.TryGetValue(r.sharedMaterials[j].shader, out matsThatUseShader)) { matsThatUseShader = new List <Material>(); shader2Material_map.Add(r.sharedMaterials[j].shader, matsThatUseShader); } if (!matsThatUseShader.Contains(r.sharedMaterials[j])) { matsThatUseShader.Add(r.sharedMaterials[j]); } } } if (hasOutOfBoundsUVs) { mom.fixOutOfBoundsUVs = true; Debug.LogWarning("Some game objects have out-of-bounds UVs. Setting the fix-out-of-bounds UVs flag"); } if (shader2Material_map.Count == 0) { Debug.LogError("Found no materials in list of objects to combine"); } mom.resultMaterials = new MB_MultiMaterial[shader2Material_map.Count]; string pth = AssetDatabase.GetAssetPath(mom.textureBakeResults); string baseName = Path.GetFileNameWithoutExtension(pth); string folderPath = pth.Substring(0, pth.Length - baseName.Length - 6); int k = 0; foreach (UnityEngine.Shader sh in shader2Material_map.Keys) { List <Material> matsThatUse = shader2Material_map[sh]; MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = matsThatUse; string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(UnityEngine.Shader.Find("Diffuse")); if (matsThatUse.Count > 0 && matsThatUse[0] != null) { MB2_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, matsThatUse[0]); } AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material)); k++; } textureBaker.UpdateIfDirtyOrScript(); }