public static bool _OkToCreateDummyTextureBakeResult(MB3_MeshBakerCommon mom) { List<GameObject> objsToMesh = mom.GetObjectsToCombine(); if (objsToMesh.Count == 0) return false; return true; }
public static void RebuildPrefab(MB3_MeshBakerCommon mom){ if (MB3_MeshCombiner.EVAL_VERSION) return; if (mom is MB3_MeshBaker){ MB3_MeshBaker mb = (MB3_MeshBaker) mom; MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle) mb.meshCombiner; GameObject prefabRoot = mom.resultPrefab; GameObject rootGO = (GameObject) PrefabUtility.InstantiatePrefab(prefabRoot); MB3_MeshCombinerSingle.BuildSceneHierarch(mbs, rootGO, mbs.GetMesh()); string prefabPth = AssetDatabase.GetAssetPath(prefabRoot); PrefabUtility.ReplacePrefab(rootGO,AssetDatabase.LoadAssetAtPath(prefabPth,typeof(GameObject)),ReplacePrefabOptions.ConnectToPrefab); Editor.DestroyImmediate(rootGO); } else if (mom is MB3_MultiMeshBaker){ MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker) mom; MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner) mmb.meshCombiner; GameObject prefabRoot = mom.resultPrefab; GameObject rootGO = (GameObject) PrefabUtility.InstantiatePrefab(prefabRoot); for (int i = 0; i < mbs.meshCombiners.Count; i++){ MB3_MeshCombinerSingle.BuildSceneHierarch(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(),true); } string prefabPth = AssetDatabase.GetAssetPath(prefabRoot); PrefabUtility.ReplacePrefab(rootGO,AssetDatabase.LoadAssetAtPath(prefabPth,typeof(GameObject)),ReplacePrefabOptions.ConnectToPrefab); Editor.DestroyImmediate(rootGO); } else { Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker."); } }
private static bool _BakeIntoCombinedSceneObject(MB3_MeshBakerCommon mom, bool createdDummyTextureBakeResults, ref SerializedObject so) { bool success; mom.ClearMesh(); if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(), null, false)) { success = true; mom.Apply(UnwrapUV2); if (createdDummyTextureBakeResults) { Debug.Log(String.Format("Successfully baked {0} meshes each material is mapped to its own submesh.", mom.GetObjectsToCombine().Count)); } else { Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count)); } } else { success = false; } return(success); }
public static void SaveMeshsToAssetDatabase(MB3_MeshBakerCommon mom, string folderPath, string newFileNameBase){ if (MB3_MeshCombiner.EVAL_VERSION) return; if (mom is MB3_MeshBaker){ MB3_MeshBaker mb = (MB3_MeshBaker) mom; string newFilename = newFileNameBase + ".asset"; string ap = AssetDatabase.GetAssetPath(((MB3_MeshCombinerSingle) mb.meshCombiner).GetMesh()); if (ap == null || ap.Equals("")){ Debug.Log("Saving mesh asset to " + newFilename); AssetDatabase.CreateAsset(((MB3_MeshCombinerSingle) mb.meshCombiner).GetMesh(), newFilename); } else { Debug.Log("Mesh is an asset at " + ap); } } else if (mom is MB3_MultiMeshBaker){ MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker) mom; List<MB3_MultiMeshCombiner.CombinedMesh> combiners = ((MB3_MultiMeshCombiner) mmb.meshCombiner).meshCombiners; for (int i = 0; i < combiners.Count; i++){ string newFilename = newFileNameBase + i + ".asset"; Mesh mesh = combiners[i].combinedMesh.GetMesh(); string ap = AssetDatabase.GetAssetPath(mesh); if (ap == null || ap.Equals("")){ Debug.Log("Saving mesh asset to " + newFilename); AssetDatabase.CreateAsset(mesh, newFilename); } else { Debug.Log("Mesh is an asset at " + ap); } } } else { Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker."); } }
public static bool bake(MB3_MeshBakerCommon mom) { bool createdDummyTextureBakeResults = false; bool success = false; try{ if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject || mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { success = MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom, out createdDummyTextureBakeResults); } else { //bake meshes in place if (mom is MB3_MeshBaker) { if (MB3_MeshCombiner.EVAL_VERSION) { Debug.LogError("Bake Meshes In Place is disabled in the evaluation version."); } else { MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.prefabOnly, new MB3_EditorMethods(), vl)) { return(false); } List <GameObject> objsToMesh = mom.GetObjectsToCombine(); Mesh m = MB3_BakeInPlace.BakeMeshesInPlace((MB3_MeshCombinerSingle)((MB3_MeshBaker)mom).meshCombiner, objsToMesh, mom.bakeAssetsInPlaceFolderPath, updateProgressBar); if (m != null) { success = true; } } } else { Debug.LogError("Multi-mesh Baker components cannot be used for Bake In Place. Use an ordinary Mesh Baker object instead."); } } if (mom.clearBuffersAfterBake) { mom.meshCombiner.ClearBuffers(); } mom.meshCombiner.CheckIntegrity(); } catch (Exception e) { Debug.LogError(e); } finally { if (createdDummyTextureBakeResults) { GameObject.DestroyImmediate(mom.textureBakeResults); mom.textureBakeResults = null; } EditorUtility.ClearProgressBar(); } return(success); }
public void DeleteAllChildMeshBakers() { MB3_MeshBakerCommon[] mBakers = GetComponentsInChildren <MB3_MeshBakerCommon>(); for (int i = 0; i < mBakers.Length; i++) { MB3_MeshBakerCommon mb = mBakers[i]; GameObject resultGameObject = mb.meshCombiner.resultSceneObject; MB_Utility.Destroy(resultGameObject); MB_Utility.Destroy(mb.gameObject); } }
// The serialized object reference is necessary to work around a nasty unity bug. public static void RebuildPrefab(MB3_MeshBakerCommon mom, ref SerializedObject so) { if (MB3_MeshCombiner.EVAL_VERSION) { return; } if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Rebuilding Prefab: " + mom.resultPrefab); } GameObject prefabRoot = mom.resultPrefab; GameObject rootGO = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot); //remove all renderer childeren of rootGO MBVersionEditor.UnpackPrefabInstance(rootGO, ref so); Renderer[] rs = rootGO.GetComponentsInChildren <Renderer>(); for (int i = 0; i < rs.Length; i++) { if (rs[i] != null && rs[i].transform.parent == rootGO.transform) { MB_Utility.Destroy(rs[i].gameObject); } } if (mom is MB3_MeshBaker) { MB3_MeshBaker mb = (MB3_MeshBaker)mom; MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle)mb.meshCombiner; MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs, rootGO, mbs.GetMesh()); } else if (mom is MB3_MultiMeshBaker) { MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker)mom; MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner)mmb.meshCombiner; for (int i = 0; i < mbs.meshCombiners.Count; i++) { MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(), true); } } else { Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker."); } string prefabPth = AssetDatabase.GetAssetPath(prefabRoot); MBVersionEditor.ReplacePrefab(rootGO, prefabPth, MB_ReplacePrefabOption.connectToPrefab); if (mom.meshCombiner.renderType != MB_RenderType.skinnedMeshRenderer) { // For Skinned meshes, leave the prefab instance in the scene so source game objects can moved into the prefab. Editor.DestroyImmediate(rootGO); } }
private static void DoGeneratePrefabsIfNecessary(MB3_MeshBakerGrouper grouper, List <MB3_MeshBakerCommon> newBakers) { if (!grouper.prefabOptions_autoGeneratePrefabs && !grouper.prefabOptions_mergeOutputIntoSinglePrefab) { return; } if (!MB_BatchPrefabBakerEditorFunctions.ValidateFolderIsInProject("Output Folder", grouper.prefabOptions_outputFolder)) { return; } if (grouper.prefabOptions_autoGeneratePrefabs) { for (int i = 0; i < newBakers.Count; i++) { MB3_MeshBakerCommon baker = newBakers[i]; string path = grouper.prefabOptions_outputFolder; // To handle paths with a different root //path = MB_BatchPrefabBakerEditorFunctions.ConvertAnyPathToProjectRelativePath(path); // Generate a new prefab name string prefabName = baker.name.Replace("MeshBaker", "CombinedMesh"); prefabName = prefabName.Replace(" ", "_"); prefabName = prefabName.Replace(",", "_"); prefabName = prefabName.Trim(Path.GetInvalidFileNameChars()); prefabName = prefabName.Trim(Path.GetInvalidPathChars()); string pathName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + prefabName + ".prefab"); if (pathName == null || pathName.Length == 0) { Debug.LogError("Could not generate prefab " + prefabName + " in folder " + path + ". There is something wrong with the path or prefab name."); continue; } // Generate a new prefab GameObject go = new GameObject(baker.name); GameObject pf = MBVersionEditor.PrefabUtility_CreatePrefab(pathName, go); // Configure the baker to bake into the prefab baker.resultPrefab = pf; baker.resultPrefabLeaveInstanceInSceneAfterBake = true; baker.meshCombiner.outputOption = MB2_OutputOptions.bakeIntoPrefab; if (grouper.parentSceneObject != null) { baker.parentSceneObject = grouper.parentSceneObject; } MB_Utility.Destroy(go); } } }
private static void createEmptyPrefab(MB3_MeshBakerCommon mom, string folder, string prefabNameNoExtension, int idx) { if (prefabNameNoExtension != null && prefabNameNoExtension.Length > 0) { string prefabName = prefabNameNoExtension + idx; GameObject go = new GameObject(prefabName); string fullName = folder + "/" + prefabName + ".prefab"; fullName = AssetDatabase.GenerateUniqueAssetPath(fullName); Debug.Log(fullName); MBVersionEditor.PrefabUtility_CreatePrefab(fullName, go); GameObject.DestroyImmediate(go); SerializedObject so = new SerializedObject(mom); so.FindProperty("resultPrefab").objectReferenceValue = (GameObject)AssetDatabase.LoadAssetAtPath(fullName, typeof(GameObject)); so.ApplyModifiedProperties(); } }
public static bool bake(MB3_MeshBakerCommon mom) { bool createdDummyTextureBakeResults = false; bool success = false; try{ if (mom.textureBakeResults == null){ if (_OkToCreateDummyTextureBakeResult(mom)){ createdDummyTextureBakeResults = true; List<GameObject> gos = mom.GetObjectsToCombine(); mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(MB_Utility.GetRenderer(gos[0])); } } if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject){ success = MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab){ success = MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else { if (mom is MB3_MeshBaker){ if (MB3_MeshCombiner.EVAL_VERSION){ Debug.LogError("Bake Meshes In Place is disabled in the evaluation version."); } else { MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.prefabOnly, new MB3_EditorMethods(), vl)) return false; List<GameObject> objsToMesh = mom.GetObjectsToCombine(); Mesh m = MB3_BakeInPlace.BakeMeshesInPlace((MB3_MeshCombinerSingle)((MB3_MeshBaker)mom).meshCombiner, objsToMesh, mom.bakeAssetsInPlaceFolderPath, updateProgressBar); if (m != null) success = true; } } else { Debug.LogError("Multi-mesh Baker components cannot be used for Bake In Place. Use an ordinary Mesh Baker object instead."); } } if (mom.clearBuffersAfterBake){ mom.meshCombiner.ClearBuffers (); } } catch(Exception e){ Debug.LogError(e); } finally { if (createdDummyTextureBakeResults){ GameObject.DestroyImmediate(mom.textureBakeResults); mom.textureBakeResults = null; } EditorUtility.ClearProgressBar(); } return success; }
void _init(MB3_MeshBakerCommon target) { meshBaker = new SerializedObject(target); objsToMesh = meshBaker.FindProperty("objsToMesh"); combiner = meshBaker.FindProperty("_meshCombiner"); outputOptions = combiner.FindPropertyRelative("_outputOption"); renderType = combiner.FindPropertyRelative("_renderType"); useObjsToMeshFromTexBaker = meshBaker.FindProperty("useObjsToMeshFromTexBaker"); textureBakeResults = combiner.FindPropertyRelative("_textureBakeResults"); lightmappingOption = combiner.FindPropertyRelative("_lightmapOption"); doNorm = combiner.FindPropertyRelative("_doNorm"); doTan = combiner.FindPropertyRelative("_doTan"); doUV = combiner.FindPropertyRelative("_doUV"); doUV1 = combiner.FindPropertyRelative("_doUV1"); doCol = combiner.FindPropertyRelative("_doCol"); mesh = combiner.FindPropertyRelative("_mesh"); }
public static void RebuildPrefab(MB3_MeshBakerCommon mom) { if (MB3_MeshCombiner.EVAL_VERSION) { return; } GameObject prefabRoot = mom.resultPrefab; GameObject rootGO = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot); //remove all renderer childeren of rootGO Renderer[] rs = rootGO.GetComponentsInChildren <Renderer>(); for (int i = 0; i < rs.Length; i++) { if (rs[i] != null && rs[i].transform.parent == rootGO.transform) { MB_Utility.Destroy(rs[i].gameObject); } } if (mom is MB3_MeshBaker) { MB3_MeshBaker mb = (MB3_MeshBaker)mom; MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle)mb.meshCombiner; MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs, rootGO, mbs.GetMesh()); } else if (mom is MB3_MultiMeshBaker) { MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker)mom; MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner)mmb.meshCombiner; for (int i = 0; i < mbs.meshCombiners.Count; i++) { MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs.meshCombiners[i].combinedMesh, rootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(), true); } } else { Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker."); } string prefabPth = AssetDatabase.GetAssetPath(prefabRoot); PrefabUtility.ReplacePrefab(rootGO, AssetDatabase.LoadAssetAtPath(prefabPth, typeof(GameObject)), ReplacePrefabOptions.ConnectToPrefab); if (mom.meshCombiner.renderType != MB_RenderType.skinnedMeshRenderer) { Editor.DestroyImmediate(rootGO); } }
void bake(MB3_MeshBakerCommon mom) { try{ if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject) { MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else { if (mom is MB3_MeshBaker) { if (MB3_MeshCombiner.EVAL_VERSION) { Debug.LogError("Bake Meshes In Place is disabled in the evaluation version."); } else { if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.prefabOnly, new MB3_EditorMethods())) { return; } List <GameObject> objsToMesh = mom.objsToMesh; if (mom.useObjsToMeshFromTexBaker && mom.GetComponent <MB3_TextureBaker>() != null) { objsToMesh = mom.GetComponent <MB3_TextureBaker>().objsToMesh; } MB3_BakeInPlace.BakeMeshesInPlace((MB3_MeshCombinerSingle)((MB3_MeshBaker)mom).meshCombiner, objsToMesh, mom.bakeAssetsInPlaceFolderPath, updateProgressBar); } } else { Debug.LogError("Multi-mesh Baker components cannot be used for Bake In Place. Use an ordinary Mesh Baker object instead."); } } } catch (Exception e) { Debug.LogError(e); } finally { EditorUtility.ClearProgressBar(); } }
void _init (MB3_MeshBakerCommon target) { meshBaker = new SerializedObject(target); objsToMesh = meshBaker.FindProperty("objsToMesh"); combiner = meshBaker.FindProperty("_meshCombiner"); outputOptions = combiner.FindPropertyRelative("_outputOption"); renderType = combiner.FindPropertyRelative("_renderType"); useObjsToMeshFromTexBaker = meshBaker.FindProperty("useObjsToMeshFromTexBaker"); textureBakeResults = combiner.FindPropertyRelative("_textureBakeResults"); lightmappingOption = combiner.FindPropertyRelative("_lightmapOption"); doNorm = combiner.FindPropertyRelative("_doNorm"); doTan = combiner.FindPropertyRelative("_doTan"); doUV = combiner.FindPropertyRelative("_doUV"); doUV3 = combiner.FindPropertyRelative("_doUV3"); doUV4 = combiner.FindPropertyRelative("_doUV4"); doCol = combiner.FindPropertyRelative("_doCol"); clearBuffersAfterBake = meshBaker.FindProperty("clearBuffersAfterBake"); mesh = combiner.FindPropertyRelative("_mesh"); }
void _init(MB3_MeshBakerCommon target) { meshBaker = new SerializedObject(target); objsToMesh = meshBaker.FindProperty("objsToMesh"); combiner = meshBaker.FindProperty("_meshCombiner"); outputOptions = combiner.FindPropertyRelative("_outputOption"); renderType = combiner.FindPropertyRelative("_renderType"); useObjsToMeshFromTexBaker = meshBaker.FindProperty("useObjsToMeshFromTexBaker"); textureBakeResults = combiner.FindPropertyRelative("_textureBakeResults"); lightmappingOption = combiner.FindPropertyRelative("_lightmapOption"); doNorm = combiner.FindPropertyRelative("_doNorm"); doTan = combiner.FindPropertyRelative("_doTan"); doUV = combiner.FindPropertyRelative("_doUV"); doUV3 = combiner.FindPropertyRelative("_doUV3"); doUV4 = combiner.FindPropertyRelative("_doUV4"); doCol = combiner.FindPropertyRelative("_doCol"); uv2OutputParamsPackingMargin = combiner.FindPropertyRelative("uv2UnwrappingParamsPackMargin"); uv2OutputParamsHardAngle = combiner.FindPropertyRelative("uv2UnwrappingParamsHardAngle"); clearBuffersAfterBake = meshBaker.FindProperty("clearBuffersAfterBake"); mesh = combiner.FindPropertyRelative("_mesh"); }
public bool _OkToCreateDummyTextureBakeResult(MB3_MeshBakerCommon mom) { List <GameObject> objsToMesh = mom.GetObjectsToCombine(); if (objsToMesh.Count == 0) { return(false); } if (objsToMesh [0] == null) { return(false); } Material[] ms = MB_Utility.GetGOMaterials(objsToMesh[0]); for (int i = 1; i < objsToMesh.Count; i++) { Material[] ms2 = MB_Utility.GetGOMaterials(objsToMesh[i]); if (!MB_Utility.ArrayBIsSubsetOfA(ms, ms2)) { Debug.LogError("Materials on " + objsToMesh[i] + " in the list of objects to combine were not a subset of the materials on the first object in the list."); return(false); } } return(true); }
public void OnInspectorGUI(MB3_MeshBakerCommon target, System.Type editorWindowType) { DrawGUI(target, editorWindowType); }
void bake(MB3_MeshBakerCommon mom) { bool createdDummyTextureBakeResults = false; try{ if (mom.textureBakeResults == null) { if (_OkToCreateDummyTextureBakeResult(mom)) { createdDummyTextureBakeResults = true; List <GameObject> gos = mom.GetObjectsToCombine(); mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(MB_Utility.GetRenderer(gos[0])); } } if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject) { MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { MB3_MeshBakerEditorFunctions.BakeIntoCombined(mom); } else { if (mom is MB3_MeshBaker) { if (MB3_MeshCombiner.EVAL_VERSION) { Debug.LogError("Bake Meshes In Place is disabled in the evaluation version."); } else { MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.prefabOnly, new MB3_EditorMethods(), vl)) { return; } List <GameObject> objsToMesh = mom.GetObjectsToCombine(); //objsToMesh = mom.GetComponent<MB3_TextureBaker>().GetObjectsToCombine(); MB3_BakeInPlace.BakeMeshesInPlace((MB3_MeshCombinerSingle)((MB3_MeshBaker)mom).meshCombiner, objsToMesh, mom.bakeAssetsInPlaceFolderPath, updateProgressBar); } } else { Debug.LogError("Multi-mesh Baker components cannot be used for Bake In Place. Use an ordinary Mesh Baker object instead."); } } if (mom.clearBuffersAfterBake) { mom.meshCombiner.ClearBuffers(); } } catch (Exception e) { Debug.LogError(e); } finally { if (createdDummyTextureBakeResults) { GameObject.DestroyImmediate(mom.textureBakeResults); mom.textureBakeResults = null; } EditorUtility.ClearProgressBar(); } }
public override void OnInspectorGUI() { MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target; MB3_TextureBaker tb = ((MB3_MeshBakerGrouper)target).GetComponent <MB3_TextureBaker>(); grouper.Update(); DrawGrouperInspector(); if (GUILayout.Button("Generate Mesh Bakers")) { if (tb == null) { Debug.LogError("There must be an MB3_TextureBaker attached to this game object."); return; } if (tb.GetObjectsToCombine().Count == 0) { Debug.LogError("The MB3_MeshBakerGrouper creates clusters based on the objects to combine in the MB3_TextureBaker component. There were no objects in this list."); return; } //check if any of the objes that will be added to bakers already exist in child bakers List <GameObject> objsWeAreGrouping = tb.GetObjectsToCombine(); MB3_MeshBakerCommon[] alreadyExistBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>(); bool foundChildBakersWithObjsToCombine = false; for (int i = 0; i < alreadyExistBakers.Length; i++) { List <GameObject> childOjs2Combine = alreadyExistBakers[i].GetObjectsToCombine(); for (int j = 0; j < childOjs2Combine.Count; j++) { if (childOjs2Combine[j] != null && objsWeAreGrouping.Contains(childOjs2Combine[j])) { foundChildBakersWithObjsToCombine = true; break; } } } bool proceed = true; if (foundChildBakersWithObjsToCombine) { proceed = EditorUtility.DisplayDialog("Replace Previous Generated Bakers", "Delete child bakers?\n\n" + "This grouper has child Mesh Baker objects from a previous clustering. Do you want to delete these and create new ones?", "OK", "Cancel"); } if (proceed) { if (foundChildBakersWithObjsToCombine) { tbg.DeleteAllChildMeshBakers(); } ((MB3_MeshBakerGrouper)target).grouper.DoClustering(tb, tbg); } } if (GUILayout.Button("Bake All Child MeshBakers")) { try { MB3_MeshBakerCommon[] mBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>(); for (int i = 0; i < mBakers.Length; i++) { bool createdDummyMaterialBakeResult; MB3_MeshBakerEditorFunctions.BakeIntoCombined(mBakers[i], out createdDummyMaterialBakeResult, ref grouper); } } catch (Exception e) { Debug.LogError(e); } finally { EditorUtility.ClearProgressBar(); } } string buttonTextEnableRenderers = "Disable Renderers On All Child MeshBaker Source Objs"; bool enableRenderers = false; MB3_MeshBakerCommon bc = tbg.GetComponentInChildren <MB3_MeshBakerCommon>(); if (bc != null && bc.GetObjectsToCombine().Count > 0) { GameObject go = bc.GetObjectsToCombine()[0]; if (go != null && go.GetComponent <Renderer>() != null && go.GetComponent <Renderer>().enabled == false) { buttonTextEnableRenderers = "Enable Renderers On All Child MeshBaker Source Objs"; enableRenderers = true; } } if (GUILayout.Button(buttonTextEnableRenderers)) { try { MB3_MeshBakerCommon[] mBakers = tbg.GetComponentsInChildren <MB3_MeshBakerCommon>(); for (int i = 0; i < mBakers.Length; i++) { mBakers[i].EnableDisableSourceObjectRenderers(enableRenderers); } } catch (Exception e) { Debug.LogError(e); } finally { EditorUtility.ClearProgressBar(); } } if (GUILayout.Button("Delete All Child Mesh Bakers & Combined Meshes")) { if (EditorUtility.DisplayDialog("Delete Mesh Bakers", "Delete all child mesh bakers", "OK", "Cancel")) { tbg.DeleteAllChildMeshBakers(); } } if (DateTime.UtcNow.Ticks - lastBoundsCheckRefreshTime > 10000000 && tb != null) { List <GameObject> gos = tb.GetObjectsToCombine(); Bounds b = new Bounds(Vector3.zero, Vector3.one); if (gos.Count > 0 && gos[0] != null && gos[0].GetComponent <Renderer>() != null) { b = gos[0].GetComponent <Renderer>().bounds; } for (int i = 0; i < gos.Count; i++) { if (gos[i] != null && gos[i].GetComponent <Renderer>() != null) { b.Encapsulate(gos[i].GetComponent <Renderer>().bounds); } } tbg.sourceObjectBounds = b; lastBoundsCheckRefreshTime = DateTime.UtcNow.Ticks; } grouper.ApplyModifiedProperties(); }
// The serialized object reference is necessary to work around a nasty unity bug. public static GameObject RebuildPrefab(MB3_MeshBakerCommon mom, ref SerializedObject so, bool leaveInstanceInSceneAfterBake, List <Transform> tempPrefabInstanceRoots, GameObject[] objsToCombine) { if (MB3_MeshCombiner.EVAL_VERSION) { return(null); } if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("Rebuilding Prefab: " + mom.resultPrefab); } GameObject prefabRoot = mom.resultPrefab; GameObject instanceRootGO = mom.meshCombiner.resultSceneObject; /* * GameObject instanceRootGO = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot); * instanceRootGO.transform.position = Vector3.zero; * instanceRootGO.transform.rotation = Quaternion.identity; * instanceRootGO.transform.localScale = Vector3.one; * * //remove everything in the prefab. * * MBVersionEditor.UnpackPrefabInstance(instanceRootGO, ref so); * int numChildren = instanceRootGO.transform.childCount; * for (int i = numChildren - 1; i >= 0; i--) * { * MB_Utility.Destroy(instanceRootGO.transform.GetChild(i).gameObject); * } * * if (mom is MB3_MeshBaker) * { * MB3_MeshBaker mb = (MB3_MeshBaker)mom; * MB3_MeshCombinerSingle mbs = (MB3_MeshCombinerSingle)mb.meshCombiner; * MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs, instanceRootGO, mbs.GetMesh()); * } * else if (mom is MB3_MultiMeshBaker) * { * MB3_MultiMeshBaker mmb = (MB3_MultiMeshBaker)mom; * MB3_MultiMeshCombiner mbs = (MB3_MultiMeshCombiner)mmb.meshCombiner; * for (int i = 0; i < mbs.meshCombiners.Count; i++) * { * MB3_MeshCombinerSingle.BuildPrefabHierarchy(mbs.meshCombiners[i].combinedMesh, instanceRootGO, mbs.meshCombiners[i].combinedMesh.GetMesh(), true); * } * } * else * { * Debug.LogError("Argument was not a MB3_MeshBaker or an MB3_MultiMeshBaker."); * } */ if (mom.meshCombiner.settings.renderType == MB_RenderType.skinnedMeshRenderer) { _MoveBonesToCombinedMeshPrefabAndDeleteRenderers(instanceRootGO.transform, tempPrefabInstanceRoots, objsToCombine); } string prefabPth = AssetDatabase.GetAssetPath(prefabRoot); MBVersionEditor.PrefabUtility_ReplacePrefab(instanceRootGO, prefabPth, MB_ReplacePrefabOption.connectToPrefab); mom.resultPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(prefabPth); if (!leaveInstanceInSceneAfterBake) { Editor.DestroyImmediate(instanceRootGO); } return(instanceRootGO); }
public static bool BakeIntoCombined(MB3_MeshBakerCommon mom, out bool createdDummyTextureBakeResults) { SerializedObject so = null; return(BakeIntoCombined(mom, out createdDummyTextureBakeResults, ref so)); }
public static bool BakeIntoCombined(MB3_MeshBakerCommon mom){ MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption; if (MB3_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab){ Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return false; } if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject){ Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return false; } MB3_TextureBaker tb = mom.GetComponent<MB3_TextureBaker>(); if (mom.textureBakeResults == null && tb != null){ mom.textureBakeResults = tb.textureBakeResults; } MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(),vl)) return false; if (prefabOrSceneObject == MB2_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 false; } if (mom.meshCombiner.resultSceneObject != null && (PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab || PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.Prefab)) { Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field."); mom.meshCombiner.resultSceneObject = null; } mom.ClearMesh(); if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(),null,false)){ mom.Apply( Unwrapping.GenerateSecondaryUVSet ); Debug.Log(String.Format("Successfully baked {0} meshes",mom.GetObjectsToCombine().Count)); if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject){ PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.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 false; } } else if (prefabOrSceneObject == MB2_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 false; } 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.meshCombiner.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"); return false; } } return true; }
public void DrawGUI(SerializedObject meshBaker, MB3_MeshBakerCommon target, UnityEngine.Object[] targets, System.Type editorWindowType) { if (meshBaker == null) { return; } meshBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" + "2. If necessary set the 'Texture Bake Results' field.\n\n" + "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" + "4. Select options and 'Bake'.\n\n" + "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None); EditorGUILayout.Separator(); } MB3_MeshBakerCommon momm = (MB3_MeshBakerCommon)target; EditorGUILayout.PropertyField(logLevel, gc_logLevelContent); EditorGUILayout.PropertyField(textureBakeResults, gc_textureBakeResultsGUIContent); bool doingTextureArray = false; if (textureBakeResults.objectReferenceValue != null) { doingTextureArray = ((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).resultType == MB2_TextureBakeResults.ResultType.textureArray; showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport) { EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (momm.GetTextureBaker() != null) { EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent); } else { useObjsToMeshFromTexBaker.boolValue = false; momm.useObjsToMeshFromTexBaker = false; GUI.enabled = false; EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent); GUI.enabled = true; } if (!momm.useObjsToMeshFromTexBaker) { if (GUILayout.Button(gc_openToolsWindowLabelContent)) { MB3_MeshBakerEditorWindow mmWin = (MB3_MeshBakerEditorWindow)EditorWindow.GetWindow(editorWindowType); mmWin.SetTarget((MB3_MeshBakerRoot)momm); } object[] objs = MB3_EditorMethods.DropZone("Drag & Drop Renderers or Parents\n" + "HERE\n" + "to add objects to be combined", 300, 50); MB3_EditorMethods.AddDroppedObjects(objs, momm); EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Objects In Scene")) { List <MB3_MeshBakerCommon> selectedBakers = _getBakersFromTargets(targets); List <GameObject> obsToCombine = new List <GameObject>(); foreach (MB3_MeshBakerCommon baker in selectedBakers) { obsToCombine.AddRange(baker.GetObjectsToCombine()); } Selection.objects = obsToCombine.ToArray(); if (momm.GetObjectsToCombine().Count > 0) { SceneView.lastActiveSceneView.pivot = momm.GetObjectsToCombine()[0].transform.position; } } if (GUILayout.Button(gc_SortAlongAxis)) { MB3_MeshBakerRoot.ZSortObjects sorter = new MB3_MeshBakerRoot.ZSortObjects(); sorter.sortAxis = sortOrderAxis.vector3Value; sorter.SortByDistanceAlongAxis(momm.GetObjectsToCombine()); } EditorGUILayout.PropertyField(sortOrderAxis, GUIContent.none); EditorGUILayout.EndHorizontal(); } else { GUI.enabled = false; EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true); GUI.enabled = true; } EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); EditorGUILayout.PropertyField(outputOptions, gc_outputOptoinsGUIContent); if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject) { Transform pgo = (Transform)EditorGUILayout.ObjectField(gc_parentSceneObject, parentSceneObject.objectReferenceValue, typeof(Transform), true); if (pgo != null && MB_Utility.IsSceneInstance(pgo.gameObject)) { parentSceneObject.objectReferenceValue = pgo; } else { parentSceneObject.objectReferenceValue = null; } //todo switch to renderer momm.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("Combined Mesh Object", momm.meshCombiner.resultSceneObject, typeof(GameObject), true); if (momm is MB3_MeshBaker) { string l = "Mesh"; Mesh m = (Mesh)mesh.objectReferenceValue; if (m != null) { l += " (" + m.GetInstanceID() + ")"; } Mesh nm = (Mesh)EditorGUILayout.ObjectField(gc_combinedMesh, m, typeof(Mesh), true); if (nm != m) { Undo.RecordObject(momm, "Assign Mesh"); ((MB3_MeshCombinerSingle)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { if (momm.meshCombiner.settings.renderType == MB_RenderType.skinnedMeshRenderer) { EditorGUILayout.HelpBox("The workflow for baking Skinned Meshes into prefabs has changed as of version 29.1. " + "It is no longer necessary to manually copy bones to the target prefab after baking. This should happen automatically.", MessageType.Info); } Transform pgo = (Transform)EditorGUILayout.ObjectField(gc_parentSceneObject, parentSceneObject.objectReferenceValue, typeof(Transform), true); if (pgo != null && MB_Utility.IsSceneInstance(pgo.gameObject)) { parentSceneObject.objectReferenceValue = pgo; } else { parentSceneObject.objectReferenceValue = null; } EditorGUILayout.BeginHorizontal(); momm.resultPrefab = (GameObject)EditorGUILayout.ObjectField(gc_combinedMeshPrefabGUIContent, momm.resultPrefab, typeof(GameObject), true); if (momm.resultPrefab != null) { string assetPath = AssetDatabase.GetAssetPath(momm.resultPrefab); if (assetPath == null || assetPath.Length == 0) { Debug.LogError("The " + gc_combinedMeshPrefabGUIContent.text + " must be a prefab asset, not a scene GameObject"); momm.resultPrefab = null; } else { MB_PrefabType pt = MBVersionEditor.PrefabUtility_GetPrefabType(momm.resultPrefab); if (pt != MB_PrefabType.prefabAsset) { Debug.LogError("The " + gc_combinedMeshPrefabGUIContent.text + " must be a prefab asset, the prefab type was '" + pt + "'"); momm.resultPrefab = null; } } } else { if (GUILayout.Button("Create Empty Prefab")) { if (!Application.isPlaying) { string path = EditorUtility.SaveFilePanelInProject("Create Empty Prefab", "MyPrefab", "prefab", "Create a prefab containing an empty GameObject"); string pathNoFolder = Path.GetDirectoryName(path); string fileNameNoExt = Path.GetFileNameWithoutExtension(path); List <MB3_MeshBakerCommon> selectedBakers = _getBakersFromTargets(targets); if (selectedBakers.Count > 1) { Debug.Log("About to create prefabs for " + selectedBakers.Count); } int idx = 0; foreach (MB3_MeshBakerCommon baker in selectedBakers) { createEmptyPrefab(baker, pathNoFolder, fileNameNoExt, idx); idx++; } } } } EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(resultPrefabLeaveInstanceInSceneAfterBake, gc_resultPrefabLeaveInstanceInSceneAfterBake); if (momm is MB3_MeshBaker) { string l = "Mesh"; Mesh m = (Mesh)mesh.objectReferenceValue; if (m != null) { l += " (" + m.GetInstanceID() + ")"; } Mesh nm = (Mesh)EditorGUILayout.ObjectField(gc_combinedMesh, m, typeof(Mesh), true); if (nm != m) { Undo.RecordObject(momm, "Assign Mesh"); ((MB3_MeshCombinerSingle)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace) { EditorGUILayout.HelpBox("Try the BatchPrefabBaker component! It makes preparing a batch of prefabs for static/ dynamic batching much easier.", MessageType.Info); if (GUILayout.Button("Choose Folder For Bake In Place Meshes")) { string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, ""); if (!newFolder.Contains(Application.dataPath)) { Debug.LogWarning("The chosen folder must be in your assets folder."); } string folder = "Assets" + newFolder.Replace(Application.dataPath, ""); List <MB3_MeshBakerCommon> selectedBakers = _getBakersFromTargets(targets); Undo.RecordObjects(targets, "Undo Set Folder"); foreach (MB3_MeshBakerCommon baker in selectedBakers) { baker.bakeAssetsInPlaceFolderPath = folder; EditorUtility.SetDirty(baker); } } EditorGUILayout.LabelField("Folder For Meshes: " + momm.bakeAssetsInPlaceFolderPath); } if (momm is MB3_MultiMeshBaker) { MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner)momm.meshCombiner; mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh); } //----------------------------------- EditorGUILayout.Space(); EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel); bool settingsEnabled = true; //------------- Mesh Baker Settings is a bit tricky because it is an interface. EditorGUILayout.Space(); UnityEngine.Object obj = settingsHolder.objectReferenceValue; // Don't use a PropertyField because we may not be able to use the assigned object. It may not implement requried interface. obj = EditorGUILayout.ObjectField(gc_Settings, obj, typeof(UnityEngine.Object), true); if (obj == null) { settingsEnabled = true; settingsHolder.objectReferenceValue = null; if (meshBakerSettingsExternal != null) { meshBakerSettingsExternal.OnDisable(); meshBakerSettingsExternal = null; } } else if (obj is GameObject) { // Check to see if there is a component on this game object that implements MB_IMeshBakerSettingsHolder MB_IMeshBakerSettingsHolder itf = (MB_IMeshBakerSettingsHolder)((GameObject)obj).GetComponent(typeof(MB_IMeshBakerSettingsHolder)); if (itf != null) { settingsEnabled = false; Component settingsHolderComponent = (Component)itf; if (settingsHolder.objectReferenceValue != settingsHolderComponent) { settingsHolder.objectReferenceValue = settingsHolderComponent; meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; itf.GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } } else { settingsEnabled = true; settingsHolder = null; if (meshBakerSettingsExternal != null) { meshBakerSettingsExternal.OnDisable(); meshBakerSettingsExternal = null; } } } else if (obj is MB_IMeshBakerSettingsHolder) { settingsEnabled = false; if (settingsHolder.objectReferenceValue != obj) { settingsHolder.objectReferenceValue = obj; meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; ((MB_IMeshBakerSettingsHolder)obj).GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } } else { Debug.LogError("Object was not a Mesh Baker Settings object."); } EditorGUILayout.Space(); if (settingsHolder.objectReferenceValue == null) { // Use the meshCombiner settings meshBakerSettingsThis.DrawGUI(momm.meshCombiner, settingsEnabled, doingTextureArray); } else { if (meshBakerSettingsExternal == null) { meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; ((MB_IMeshBakerSettingsHolder)obj).GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } meshBakerSettingsExternal.DrawGUI(((MB_IMeshBakerSettingsHolder)settingsHolder.objectReferenceValue).GetMeshBakerSettings(), settingsEnabled, doingTextureArray); } Color oldColor = GUI.backgroundColor; GUI.backgroundColor = buttonColor; if (GUILayout.Button("Bake")) { List <MB3_MeshBakerCommon> selectedBakers = _getBakersFromTargets(targets); if (selectedBakers.Count > 1) { Debug.Log("About to bake " + selectedBakers.Count); } foreach (MB3_MeshBakerCommon baker in selectedBakers) { // Why are we caching and recreating the SerializedObject? Because "bakeIntoPrefab" corrupts the serialized object // and the meshBaker SerializedObject throws an NRE the next time it gets used. MB3_MeshBakerCommon mbr = (MB3_MeshBakerCommon)meshBaker.targetObject; bake(baker); meshBaker = new SerializedObject(mbr); } } GUI.backgroundColor = oldColor; string enableRenderersLabel; bool disableRendererInSource = false; if (momm.GetObjectsToCombine().Count > 0) { Renderer r = MB_Utility.GetRenderer(momm.GetObjectsToCombine()[0]); if (r != null && r.enabled) { disableRendererInSource = true; } } if (disableRendererInSource) { enableRenderersLabel = "Disable Renderers On Source Objects"; } else { enableRenderersLabel = "Enable Renderers On Source Objects"; } if (GUILayout.Button(enableRenderersLabel)) { List <MB3_MeshBakerCommon> selectedBakers = _getBakersFromTargets(targets); foreach (MB3_MeshBakerCommon baker in selectedBakers) { baker.EnableDisableSourceObjectRenderers(!disableRendererInSource); } } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }
public void DrawGUI(MB3_MeshBakerCommon target, System.Type editorWindowType){ if (meshBaker == null){ _init(target); } meshBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions,"Instructions:"); if (showInstructions){ EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" + "2. If necessary set the 'Material Bake Results' field.\n\n" + "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" + "4. Select options and 'Bake'.\n\n" + "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None); EditorGUILayout.Separator(); } MB3_MeshBakerCommon mom = (MB3_MeshBakerCommon) target; mom.meshCombiner.LOG_LEVEL = (MB2_LogLevel) EditorGUILayout.EnumPopup("Log Level", mom.meshCombiner.LOG_LEVEL); 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.LabelField("Objects To Be Combined",EditorStyles.boldLabel); if (mom.GetTextureBaker() != null){ EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, useTextureBakerObjsGUIContent); } else { useObjsToMeshFromTexBaker.boolValue = false; mom.useObjsToMeshFromTexBaker = false; GUI.enabled = false; EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, useTextureBakerObjsGUIContent); GUI.enabled = true; } if (!mom.useObjsToMeshFromTexBaker){ if (GUILayout.Button(openToolsWindowLabelContent)){ MB3_MeshBakerEditorWindowInterface mmWin = (MB3_MeshBakerEditorWindowInterface) EditorWindow.GetWindow(editorWindowType); mmWin.target = (MB3_MeshBakerRoot) target; } EditorGUILayout.PropertyField(objsToMesh,objectsToCombineGUIContent, true); } else { GUI.enabled = false; EditorGUILayout.PropertyField(objsToMesh,objectsToCombineGUIContent, true); GUI.enabled = true; } EditorGUILayout.LabelField("Output",EditorStyles.boldLabel); if (mom is MB3_MultiMeshBaker){ MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner) mom.meshCombiner; mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(doNorm,doNormGUIContent); EditorGUILayout.PropertyField(doTan,doTanGUIContent); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(doUV,doUVGUIContent); EditorGUILayout.PropertyField(doUV3,doUV3GUIContent); EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(doUV4, doUV4GUIContent); EditorGUILayout.PropertyField(doCol,doColGUIContent); if (mom.meshCombiner.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping) { if (MBVersion.GetMajorVersion() == 5) { EditorGUILayout.HelpBox("The best choice for Unity 5 is to Ignore_UV2 or Generate_New_UV2 layout. Unity's baked GI will create the UV2 layout it wants. See manual for more information.", MessageType.Warning); } } if (mom.meshCombiner.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout){ EditorGUILayout.HelpBox("Generating new lightmap UVs can split vertices which can push the number of vertices over the 64k limit.",MessageType.Warning); } EditorGUILayout.PropertyField(lightmappingOption,lightmappingOptionGUIContent); EditorGUILayout.PropertyField(outputOptions,outputOptoinsGUIContent); EditorGUILayout.PropertyField(renderType, renderTypeGUIContent); if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject){ //todo switch to renderer mom.meshCombiner.resultSceneObject = (GameObject) EditorGUILayout.ObjectField("Combined Mesh Object", mom.meshCombiner.resultSceneObject, typeof(GameObject), true); if (mom is MB3_MeshBaker){ string l = "Mesh"; if (mesh.objectReferenceValue != null) l += " ("+ mesh.objectReferenceValue.GetInstanceID() +")"; EditorGUILayout.PropertyField(mesh,new GUIContent(l)); } } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab){ mom.resultPrefab = (GameObject) EditorGUILayout.ObjectField(combinedMeshPrefabGUIContent, mom.resultPrefab, typeof(GameObject), true); if (mom is MB3_MeshBaker){ string l = "Mesh"; if (mesh.objectReferenceValue != null) l += " ("+ mesh.objectReferenceValue.GetInstanceID() +")"; EditorGUILayout.PropertyField(mesh,new GUIContent(l)); } } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace){ EditorGUILayout.HelpBox("NEW! Try the BatchPrefabBaker component. It makes preparing a batch of prefabs for static/ dynamic batching much easier.",MessageType.Info); if (GUILayout.Button("Choose Folder For Bake In Place Meshes") ){ string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, ""); if (!newFolder.Contains(Application.dataPath)) Debug.LogWarning("The chosen folder must be in your assets folder."); mom.bakeAssetsInPlaceFolderPath = "Assets" + newFolder.Replace(Application.dataPath, ""); } EditorGUILayout.LabelField("Folder For Meshes: " + mom.bakeAssetsInPlaceFolderPath); } EditorGUILayout.PropertyField(clearBuffersAfterBake, clearBuffersAfterBakeGUIContent); if (GUILayout.Button("Bake")){ bake(mom); } string enableRenderersLabel; bool disableRendererInSource = false; if (mom.GetObjectsToCombine().Count > 0){ Renderer r = MB_Utility.GetRenderer(mom.GetObjectsToCombine()[0]); if (r != null && r.enabled) disableRendererInSource = true; } if (disableRendererInSource){ enableRenderersLabel = "Disable Renderers On Source Objects"; } else { enableRenderersLabel = "Enable Renderers On Source Objects"; } if (GUILayout.Button(enableRenderersLabel)){ mom.EnableDisableSourceObjectRenderers(!disableRendererInSource); } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }
public void OnInspectorGUI(MB3_MeshBakerCommon target, System.Type editorWindowType){ DrawGUI(target, editorWindowType); }
public static bool _OkToCreateDummyTextureBakeResult(MB3_MeshBakerCommon mom){ List<GameObject> objsToMesh = mom.GetObjectsToCombine (); if (objsToMesh.Count == 0) return false; if (objsToMesh [0] == null) return false; Material[] ms = MB_Utility.GetGOMaterials(objsToMesh[0]); for (int i = 1; i < objsToMesh.Count; i++) { Material[] ms2 = MB_Utility.GetGOMaterials(objsToMesh[i]); if (!MB_Utility.ArrayBIsSubsetOfA(ms,ms2)){ Debug.LogError ("Materials on " + objsToMesh[i] + " in the list of objects to combine were not a subset of the materials on the first object in the list."); return false; } } return true; }
public static bool BakeIntoCombined(MB3_MeshBakerCommon mom, out bool createdDummyTextureBakeResults) { MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption; createdDummyTextureBakeResults = false; if (MB3_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab){ Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return false; } if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject){ Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return false; } MB3_TextureBaker tb = mom.GetComponentInParent<MB3_TextureBaker>(); if (mom.textureBakeResults == null && tb != null){ mom.textureBakeResults = tb.textureBakeResults; } if (mom.textureBakeResults == null) { if (_OkToCreateDummyTextureBakeResult(mom)) { createdDummyTextureBakeResults = true; List<GameObject> gos = mom.GetObjectsToCombine(); if (mom.GetNumObjectsInCombined() > 0) { Debug.LogError("'Texture Bake Result' must be set to add more objects to a combined mesh that already contains objects. Try enabling 'clear buffers after bake'"); return false; } mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(gos.ToArray(), mom.meshCombiner.GetMaterialsOnTargetRenderer()); if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("'Texture Bake Result' was not set. Creating a temporary one. Each material will be mapped to a separate submesh."); } } } MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(),vl)) return false; if (prefabOrSceneObject == MB2_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 false; } if (mom.meshCombiner.resultSceneObject != null && (PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab || PrefabUtility.GetPrefabType (mom.meshCombiner.resultSceneObject) == PrefabType.Prefab)) { Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field."); mom.meshCombiner.resultSceneObject = null; } mom.ClearMesh(); if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(),null,false)){ mom.Apply( UnwrapUV2 ); if (createdDummyTextureBakeResults) { Debug.Log(String.Format("Successfully baked {0} meshes each material is mapped to its own submesh.", mom.GetObjectsToCombine().Count)); } else { Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count)); } if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject){ PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.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 false; } } else if (prefabOrSceneObject == MB2_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 false; } 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.meshCombiner.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"); return false; } } return true; }
public void DrawGUI(MB3_MeshBakerCommon target, System.Type editorWindowType) { if (meshBaker == null) { _init(target); } meshBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" + "2. If necessary set the 'Material Bake Results' field.\n\n" + "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" + "4. Select options and 'Bake'.\n\n" + "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None); EditorGUILayout.Separator(); } MB3_MeshBakerCommon mom = (MB3_MeshBakerCommon)target; mom.meshCombiner.LOG_LEVEL = (MB2_LogLevel)EditorGUILayout.EnumPopup("Log Level", mom.meshCombiner.LOG_LEVEL); 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.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (mom.GetTextureBaker() != null) { EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, useTextureBakerObjsGUIContent); } else { useObjsToMeshFromTexBaker.boolValue = false; mom.useObjsToMeshFromTexBaker = false; GUI.enabled = false; EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, useTextureBakerObjsGUIContent); GUI.enabled = true; } if (!mom.useObjsToMeshFromTexBaker) { if (GUILayout.Button(openToolsWindowLabelContent)) { MB3_MeshBakerEditorWindowInterface mmWin = (MB3_MeshBakerEditorWindowInterface)EditorWindow.GetWindow(editorWindowType); mmWin.target = (MB3_MeshBakerRoot)target; } EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true); } else { GUI.enabled = false; EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true); GUI.enabled = true; } EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); if (mom is MB3_MultiMeshBaker) { MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner)mom.meshCombiner; mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(doNorm, doNormGUIContent); EditorGUILayout.PropertyField(doTan, doTanGUIContent); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(doUV, doUVGUIContent); EditorGUILayout.PropertyField(doUV1, doUV1GUIContent); EditorGUILayout.EndHorizontal(); EditorGUILayout.PropertyField(doCol, doColGUIContent); if (mom.meshCombiner.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout) { EditorGUILayout.HelpBox("Generating new lightmap UVs can split vertices which can push the number of vertices over the 64k limit.", MessageType.Warning); } EditorGUILayout.PropertyField(lightmappingOption, lightmappingOptionGUIContent); EditorGUILayout.PropertyField(outputOptions, outputOptoinsGUIContent); EditorGUILayout.PropertyField(renderType, renderTypeGUIContent); if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject) { //todo switch to renderer mom.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("Combined Mesh Object", mom.meshCombiner.resultSceneObject, typeof(GameObject), true); if (mom is MB3_MeshBaker) { string l = "Mesh"; if (mesh.objectReferenceValue != null) { l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")"; } EditorGUILayout.PropertyField(mesh, new GUIContent(l)); } } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { mom.resultPrefab = (GameObject)EditorGUILayout.ObjectField(combinedMeshPrefabGUIContent, mom.resultPrefab, typeof(GameObject), true); if (mom is MB3_MeshBaker) { string l = "Mesh"; if (mesh.objectReferenceValue != null) { l += " (" + mesh.objectReferenceValue.GetInstanceID() + ")"; } EditorGUILayout.PropertyField(mesh, new GUIContent(l)); } } else if (mom.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace) { EditorGUILayout.HelpBox("NEW! Try the BatchPrefabBaker component. It makes preparing a batch of prefabs for static/ dynamic batching much easier.", MessageType.Info); if (GUILayout.Button("Choose Folder For Bake In Place Meshes")) { string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, ""); if (!newFolder.Contains(Application.dataPath)) { Debug.LogWarning("The chosen folder must be in your assets folder."); } mom.bakeAssetsInPlaceFolderPath = "Assets" + newFolder.Replace(Application.dataPath, ""); } EditorGUILayout.LabelField("Folder For Meshes: " + mom.bakeAssetsInPlaceFolderPath); } EditorGUILayout.PropertyField(clearBuffersAfterBake, clearBuffersAfterBakeGUIContent); if (GUILayout.Button("Bake")) { bake(mom); } string enableRenderersLabel; bool disableRendererInSource = false; if (mom.GetObjectsToCombine().Count > 0) { Renderer r = MB_Utility.GetRenderer(mom.GetObjectsToCombine()[0]); if (r != null && r.enabled) { disableRendererInSource = true; } } if (disableRendererInSource) { enableRenderersLabel = "Disable Renderers On Source Objects"; } else { enableRenderersLabel = "Enable Renderers On Source Objects"; } if (GUILayout.Button(enableRenderersLabel)) { mom.EnableDisableSourceObjectRenderers(!disableRendererInSource); } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }
public static bool BakeIntoCombined(MB3_MeshBakerCommon mom) { MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption; if (MB3_MeshCombiner.EVAL_VERSION && prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab) { Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return(false); } if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject) { Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return(false); } MB3_TextureBaker tb = mom.GetComponent <MB3_TextureBaker>(); if (mom.textureBakeResults == null && tb != null) { mom.textureBakeResults = tb.textureBakeResults; } MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(), vl)) { return(false); } if (prefabOrSceneObject == MB2_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(false); } if (mom.meshCombiner.resultSceneObject != null && (PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.ModelPrefab || PrefabUtility.GetPrefabType(mom.meshCombiner.resultSceneObject) == PrefabType.Prefab)) { Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field."); mom.meshCombiner.resultSceneObject = null; } mom.ClearMesh(); if (mom.AddDeleteGameObjects(mom.GetObjectsToCombine().ToArray(), null, false)) { mom.Apply(Unwrapping.GenerateSecondaryUVSet); Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count)); if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject) { PrefabType pt = PrefabUtility.GetPrefabType(mom.meshCombiner.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(false); } } else if (prefabOrSceneObject == MB2_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(false); } 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.meshCombiner.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"); return(false); } } return(true); }
public void OnInspectorGUI(SerializedObject meshBaker, MB3_MeshBakerCommon target, System.Type editorWindowType) { DrawGUI(meshBaker, target, editorWindowType); }
private static bool _BakeIntoCombinedPrefab(MB3_MeshBakerCommon mom, bool createdDummyTextureBakeResults, ref SerializedObject so) { bool success = false; List <Transform> tempPrefabInstanceRoots = null; GameObject[] objsToCombine = mom.GetObjectsToCombine().ToArray(); if (mom.meshCombiner.settings.renderType == MB_RenderType.skinnedMeshRenderer) { tempPrefabInstanceRoots = new List <Transform>(); // We are going to move bones of source objs and transforms into our combined mesh prefab so make some duplicates // so that we don't destroy a setup. _DuplicateSrcObjectInstancesAndUnpack(mom.meshCombiner.settings.renderType, objsToCombine, tempPrefabInstanceRoots); } try { MB3_EditorMethods editorMethods = new MB3_EditorMethods(); mom.ClearMesh(editorMethods); if (mom.AddDeleteGameObjects(objsToCombine, null, false)) { success = true; mom.Apply(UnwrapUV2); if (createdDummyTextureBakeResults) { Debug.Log(String.Format("Successfully baked {0} meshes each material is mapped to its own submesh.", mom.GetObjectsToCombine().Count)); } else { Debug.Log(String.Format("Successfully baked {0} meshes", mom.GetObjectsToCombine().Count)); } 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."); success = false; } else { string baseName = Path.GetFileNameWithoutExtension(prefabPth); string folderPath = prefabPth.Substring(0, prefabPth.Length - baseName.Length - 7); string newFilename = folderPath + baseName + "-mesh"; SaveMeshsToAssetDatabase(mom, folderPath, newFilename); RebuildPrefab(mom, ref so, mom.resultPrefabLeaveInstanceInSceneAfterBake, tempPrefabInstanceRoots, objsToCombine); } } else { success = false; } } catch { throw; } finally { // Clean up temporary created instances. If success was true then they should have been added to a prefab // and cleaned up for us. if (success == false) { if (tempPrefabInstanceRoots != null) { for (int i = 0; i < tempPrefabInstanceRoots.Count; i++) { MB_Utility.Destroy(tempPrefabInstanceRoots[i]); } } } } return(success); }
public void DrawGUI(SerializedObject meshBaker, MB3_MeshBakerCommon target, System.Type editorWindowType) { if (meshBaker == null) { return; } meshBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "Instructions:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Bake combined material(s).\n\n" + "2. If necessary set the 'Texture Bake Results' field.\n\n" + "3. Add scene objects or prefabs to combine or check 'Same As Texture Baker'. For best results these should use the same shader as result material.\n\n" + "4. Select options and 'Bake'.\n\n" + "6. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "7. (optional) Disable renderers in source objects.", UnityEditor.MessageType.None); EditorGUILayout.Separator(); } MB3_MeshBakerCommon momm = (MB3_MeshBakerCommon)target; EditorGUILayout.PropertyField(logLevel, gc_logLevelContent); EditorGUILayout.PropertyField(textureBakeResults, gc_textureBakeResultsGUIContent); bool doingTextureArray = false; if (textureBakeResults.objectReferenceValue != null) { doingTextureArray = ((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).resultType == MB2_TextureBakeResults.ResultType.textureArray; showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport) { EditorGUILayout.HelpBox(((MB2_TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (momm.GetTextureBaker() != null) { EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent); } else { useObjsToMeshFromTexBaker.boolValue = false; momm.useObjsToMeshFromTexBaker = false; GUI.enabled = false; EditorGUILayout.PropertyField(useObjsToMeshFromTexBaker, gc_useTextureBakerObjsGUIContent); GUI.enabled = true; } if (!momm.useObjsToMeshFromTexBaker) { if (GUILayout.Button(gc_openToolsWindowLabelContent)) { MB3_MeshBakerEditorWindowInterface mmWin = (MB3_MeshBakerEditorWindowInterface)EditorWindow.GetWindow(editorWindowType); mmWin.target = (MB3_MeshBakerRoot)target; } object[] objs = MB3_EditorMethods.DropZone("Drag & Drop Renderers Or Parents Here To Add Objects To Be Combined", 300, 50); MB3_EditorMethods.AddDroppedObjects(objs, momm); EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Objects In Scene")) { Selection.objects = momm.GetObjectsToCombine().ToArray(); if (momm.GetObjectsToCombine().Count > 0) { SceneView.lastActiveSceneView.pivot = momm.GetObjectsToCombine()[0].transform.position; } } if (GUILayout.Button(gc_SortAlongAxis)) { MB3_MeshBakerRoot.ZSortObjects sorter = new MB3_MeshBakerRoot.ZSortObjects(); sorter.sortAxis = sortOrderAxis.vector3Value; sorter.SortByDistanceAlongAxis(momm.GetObjectsToCombine()); } EditorGUILayout.PropertyField(sortOrderAxis, GUIContent.none); EditorGUILayout.EndHorizontal(); } else { GUI.enabled = false; EditorGUILayout.PropertyField(objsToMesh, gc_objectsToCombineGUIContent, true); GUI.enabled = true; } EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); EditorGUILayout.PropertyField(outputOptions, gc_outputOptoinsGUIContent); if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoSceneObject) { //todo switch to renderer momm.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("Combined Mesh Object", momm.meshCombiner.resultSceneObject, typeof(GameObject), true); if (momm is MB3_MeshBaker) { string l = "Mesh"; Mesh m = (Mesh)mesh.objectReferenceValue; if (m != null) { l += " (" + m.GetInstanceID() + ")"; } Mesh nm = (Mesh)EditorGUILayout.ObjectField(new GUIContent(l), m, typeof(Mesh), true); if (nm != m) { Undo.RecordObject(momm, "Assign Mesh"); ((MB3_MeshCombinerSingle)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeIntoPrefab) { momm.resultPrefab = (GameObject)EditorGUILayout.ObjectField(gc_combinedMeshPrefabGUIContent, momm.resultPrefab, typeof(GameObject), true); if (momm is MB3_MeshBaker) { string l = "Mesh"; Mesh m = (Mesh)mesh.objectReferenceValue; if (m != null) { l += " (" + m.GetInstanceID() + ")"; } Mesh nm = (Mesh)EditorGUILayout.ObjectField(new GUIContent(l), m, typeof(Mesh), true); if (nm != m) { Undo.RecordObject(momm, "Assign Mesh"); ((MB3_MeshCombinerSingle)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } else if (momm.meshCombiner.outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace) { EditorGUILayout.HelpBox("NEW! Try the BatchPrefabBaker component. It makes preparing a batch of prefabs for static/ dynamic batching much easier.", MessageType.Info); if (GUILayout.Button("Choose Folder For Bake In Place Meshes")) { string newFolder = EditorUtility.SaveFolderPanel("Folder For Bake In Place Meshes", Application.dataPath, ""); if (!newFolder.Contains(Application.dataPath)) { Debug.LogWarning("The chosen folder must be in your assets folder."); } momm.bakeAssetsInPlaceFolderPath = "Assets" + newFolder.Replace(Application.dataPath, ""); } EditorGUILayout.LabelField("Folder For Meshes: " + momm.bakeAssetsInPlaceFolderPath); } if (momm is MB3_MultiMeshBaker) { MB3_MultiMeshCombiner mmc = (MB3_MultiMeshCombiner)momm.meshCombiner; mmc.maxVertsInMesh = EditorGUILayout.IntField("Max Verts In Mesh", mmc.maxVertsInMesh); } //----------------------------------- EditorGUILayout.Space(); EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel); bool settingsEnabled = true; //------------- Mesh Baker Settings is a bit tricky because it is an interface. EditorGUILayout.Space(); UnityEngine.Object obj = settingsHolder.objectReferenceValue; // Don't use a PropertyField because we may not be able to use the assigned object. It may not implement requried interface. obj = EditorGUILayout.ObjectField(gc_Settings, obj, typeof(UnityEngine.Object), true); if (obj == null) { settingsEnabled = true; settingsHolder.objectReferenceValue = null; if (meshBakerSettingsExternal != null) { meshBakerSettingsExternal.OnDisable(); meshBakerSettingsExternal = null; } } else if (obj is GameObject) { // Check to see if there is a component on this game object that implements MB_IMeshBakerSettingsHolder MB_IMeshBakerSettingsHolder itf = (MB_IMeshBakerSettingsHolder)((GameObject)obj).GetComponent(typeof(MB_IMeshBakerSettingsHolder)); if (itf != null) { settingsEnabled = false; Component settingsHolderComponent = (Component)itf; if (settingsHolder.objectReferenceValue != settingsHolderComponent) { settingsHolder.objectReferenceValue = settingsHolderComponent; meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; itf.GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } } else { settingsEnabled = true; settingsHolder = null; if (meshBakerSettingsExternal != null) { meshBakerSettingsExternal.OnDisable(); meshBakerSettingsExternal = null; } } } else if (obj is MB_IMeshBakerSettingsHolder) { settingsEnabled = false; if (settingsHolder.objectReferenceValue != obj) { settingsHolder.objectReferenceValue = obj; meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; ((MB_IMeshBakerSettingsHolder)obj).GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } } else { Debug.LogError("Object was not a Mesh Baker Settings object."); } EditorGUILayout.Space(); if (settingsHolder.objectReferenceValue == null) { // Use the meshCombiner settings meshBakerSettingsThis.DrawGUI(momm.meshCombiner, settingsEnabled, doingTextureArray); } else { if (meshBakerSettingsExternal == null) { meshBakerSettingsExternal = new MB_MeshBakerSettingsEditor(); UnityEngine.Object targetObj; string propertyName; ((MB_IMeshBakerSettingsHolder)obj).GetMeshBakerSettingsAsSerializedProperty(out propertyName, out targetObj); SerializedProperty meshBakerSettings = new SerializedObject(targetObj).FindProperty(propertyName); meshBakerSettingsExternal.OnEnable(meshBakerSettings); } meshBakerSettingsExternal.DrawGUI(((MB_IMeshBakerSettingsHolder)settingsHolder.objectReferenceValue).GetMeshBakerSettings(), settingsEnabled, doingTextureArray); } Color oldColor = GUI.backgroundColor; GUI.backgroundColor = buttonColor; if (GUILayout.Button("Bake")) { bake(momm, ref meshBaker); } GUI.backgroundColor = oldColor; string enableRenderersLabel; bool disableRendererInSource = false; if (momm.GetObjectsToCombine().Count > 0) { Renderer r = MB_Utility.GetRenderer(momm.GetObjectsToCombine()[0]); if (r != null && r.enabled) { disableRendererInSource = true; } } if (disableRendererInSource) { enableRenderersLabel = "Disable Renderers On Source Objects"; } else { enableRenderersLabel = "Enable Renderers On Source Objects"; } if (GUILayout.Button(enableRenderersLabel)) { momm.EnableDisableSourceObjectRenderers(!disableRendererInSource); } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }
/// <summary> /// Bakes a combined mesh. /// </summary> /// <param name="so">If this is being called from Inspector code then pass in the SerializedObject for the component. /// This is necessary for "bake into prefab" which can corrupt the SerializedObject.</param> public static bool BakeIntoCombined(MB3_MeshBakerCommon mom, out bool createdDummyTextureBakeResults, ref SerializedObject so) { MB2_OutputOptions prefabOrSceneObject = mom.meshCombiner.outputOption; createdDummyTextureBakeResults = false; // Initial Validate { if (mom.meshCombiner.resultSceneObject != null && (MBVersionEditor.PrefabUtility_GetPrefabType(mom.meshCombiner.resultSceneObject) == MB_PrefabType.modelPrefabAsset || MBVersionEditor.PrefabUtility_GetPrefabType(mom.meshCombiner.resultSceneObject) == MB_PrefabType.prefabAsset)) { Debug.LogWarning("Result Game Object was a project asset not a scene object instance. Clearing this field."); mom.meshCombiner.resultSceneObject = null; } if (prefabOrSceneObject != MB2_OutputOptions.bakeIntoPrefab && prefabOrSceneObject != MB2_OutputOptions.bakeIntoSceneObject) { Debug.LogError("Paramater prefabOrSceneObject must be bakeIntoPrefab or bakeIntoSceneObject"); return(false); } if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab) { if (MB3_MeshCombiner.EVAL_VERSION) { Debug.LogError("Cannot BakeIntoPrefab with evaluation version."); return(false); } if (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(false); } 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 a project asset. Is it an instance in the scene?"); return(false); } } } { // Find or create texture bake results MB3_TextureBaker tb = mom.GetComponentInParent <MB3_TextureBaker>(); if (mom.textureBakeResults == null && tb != null) { mom.textureBakeResults = tb.textureBakeResults; } if (mom.textureBakeResults == null) { if (_OkToCreateDummyTextureBakeResult(mom)) { createdDummyTextureBakeResults = true; List <GameObject> gos = mom.GetObjectsToCombine(); if (mom.GetNumObjectsInCombined() > 0) { if (mom.clearBuffersAfterBake) { mom.ClearMesh(); } else { Debug.LogError("'Texture Bake Result' must be set to add more objects to a combined mesh that already contains objects. Try enabling 'clear buffers after bake'"); return(false); } } mom.textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(gos.ToArray(), mom.meshCombiner.GetMaterialsOnTargetRenderer()); if (mom.meshCombiner.LOG_LEVEL >= MB2_LogLevel.debug) { Debug.Log("'Texture Bake Result' was not set. Creating a temporary one. Each material will be mapped to a separate submesh."); } } } } // Second level of validation now that TextureBakeResults exists. MB2_ValidationLevel vl = Application.isPlaying ? MB2_ValidationLevel.quick : MB2_ValidationLevel.robust; if (!MB3_MeshBakerRoot.DoCombinedValidate(mom, MB_ObjsToCombineTypes.sceneObjOnly, new MB3_EditorMethods(), vl)) { return(false); } // Add Delete Game Objects bool success; if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoSceneObject) { success = _BakeIntoCombinedSceneObject(mom, createdDummyTextureBakeResults, ref so); } else if (prefabOrSceneObject == MB2_OutputOptions.bakeIntoPrefab) { success = _BakeIntoCombinedPrefab(mom, createdDummyTextureBakeResults, ref so); } else { Debug.LogError("Should be impossible."); success = false; } if (mom.clearBuffersAfterBake) { mom.meshCombiner.ClearBuffers(); } if (createdDummyTextureBakeResults) { MB_Utility.Destroy(mom.textureBakeResults); } return(success); }
public static bool bake(MB3_MeshBakerCommon mom) { SerializedObject so = null; return(bake(mom, ref so)); }
void createAndSetupBaker(List <GameObjectFilterInfo> gaws, string pthRoot) { for (int i = gaws.Count - 1; i >= 0; i--) { if (gaws[i].go == null) { gaws.RemoveAt(i); } } if (gaws.Count < 1) { Debug.LogError("No game objects."); return; } if (pthRoot == null || pthRoot == "") { Debug.LogError("Folder for saving created assets was not set."); return; } int numVerts = 0; for (int i = 0; i < gaws.Count; i++) { if (gaws[i].go != null) { numVerts = gaws[i].numVerts; } } GameObject newMeshBaker = null; if (numVerts >= 65535) { newMeshBaker = MB3_MultiMeshBakerEditor.CreateNewMeshBaker(); } else { newMeshBaker = MB3_MeshBakerEditor.CreateNewMeshBaker(); } newMeshBaker.name = ("MeshBaker-" + gaws[0].shaderName + "-LM" + gaws[0].lightmapIndex).ToString().Replace("/", "-"); MB3_TextureBaker tb = newMeshBaker.GetComponent <MB3_TextureBaker>(); MB3_MeshBakerCommon mb = tb.GetComponentInChildren <MB3_MeshBakerCommon>(); tb.GetObjectsToCombine().Clear(); for (int i = 0; i < gaws.Count; i++) { if (gaws[i].go != null) { tb.GetObjectsToCombine().Add(gaws[i].go); } } if (gaws[0].numMaterials > 1) { string pthMat = AssetDatabase.GenerateUniqueAssetPath(pthRoot + newMeshBaker.name + ".asset"); MB3_TextureBakerEditorInternal.CreateCombinedMaterialAssets(tb, pthMat); tb.doMultiMaterial = true; SerializedObject tbr = new SerializedObject(tb); SerializedProperty resultMaterials = tbr.FindProperty("resultMaterials"); MB3_TextureBakerEditorInternal.ConfigureMutiMaterialsFromObjsToCombine(tb, resultMaterials, tbr); } else { string pthMat = AssetDatabase.GenerateUniqueAssetPath(pthRoot + newMeshBaker.name + ".asset"); MB3_TextureBakerEditorInternal.CreateCombinedMaterialAssets(tb, pthMat); } if (gaws[0].isMeshRenderer) { mb.meshCombiner.renderType = MB_RenderType.meshRenderer; } else { mb.meshCombiner.renderType = MB_RenderType.skinnedMeshRenderer; } }
public override void OnInspectorGUI() { grouper.Update(); DrawGrouperInspector(); if (GUILayout.Button("Generate Mesh Bakers")) { for (int tIdx = 0; tIdx < targets.Length; tIdx++) { _generateMeshBakers(targets[tIdx]); } } if (GUILayout.Button("Bake All Child MeshBakers")) { for (int tIdx = 0; tIdx < targets.Length; tIdx++) { _bakeAllChildMeshBakers(targets[tIdx], ref grouper); } } string buttonTextEnableRenderers = "Disable Renderers On All Child MeshBaker Source Objs"; bool enableRenderers = false; { MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target; MB3_MeshBakerCommon bc = tbg.GetComponentInChildren <MB3_MeshBakerCommon>(); if (bc != null && bc.GetObjectsToCombine().Count > 0) { GameObject go = bc.GetObjectsToCombine()[0]; if (go != null && go.GetComponent <Renderer>() != null && go.GetComponent <Renderer>().enabled == false) { buttonTextEnableRenderers = "Enable Renderers On All Child MeshBaker Source Objs"; enableRenderers = true; } } } if (GUILayout.Button(buttonTextEnableRenderers)) { for (int tIdx = 0; tIdx < targets.Length; tIdx++) { _enableDisableRenderers(targets[tIdx], enableRenderers); } } if (GUILayout.Button("Delete All Child Mesh Bakers & Combined Meshes")) { if (EditorUtility.DisplayDialog("Delete Mesh Bakers", "Delete all child mesh bakers", "OK", "Cancel")) { for (int i = 0; i < targets.Length; i++) { MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)targets[i]; tbg.DeleteAllChildMeshBakers(); } } } if (DateTime.UtcNow.Ticks - lastBoundsCheckRefreshTime > 10000000) { MB3_TextureBaker tb = ((MB3_MeshBakerGrouper)target).GetComponent <MB3_TextureBaker>(); if (tb != null) { MB3_MeshBakerGrouper tbg = (MB3_MeshBakerGrouper)target; List <GameObject> gos = tb.GetObjectsToCombine(); Bounds b = new Bounds(Vector3.zero, Vector3.one); if (gos.Count > 0 && gos[0] != null && gos[0].GetComponent <Renderer>() != null) { b = gos[0].GetComponent <Renderer>().bounds; } for (int i = 0; i < gos.Count; i++) { if (gos[i] != null && gos[i].GetComponent <Renderer>() != null) { b.Encapsulate(gos[i].GetComponent <Renderer>().bounds); } } tbg.sourceObjectBounds = b; lastBoundsCheckRefreshTime = DateTime.UtcNow.Ticks; } } grouper.ApplyModifiedProperties(); }