public void DrawGUI(SerializedObject textureBaker, MB3_TextureBaker momm, UnityEngine.Object[] targets, System.Type editorWindow) { if (textureBaker == null) { return; } 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.PropertyField(logLevel, logLevelContent); EditorGUILayout.Separator(); // Selected objects EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("Objects To Be Combined", EditorStyles.boldLabel); if (GUILayout.Button(openToolsWindowLabelContent)) { MB3_MeshBakerEditorWindow mmWin = (MB3_MeshBakerEditorWindow)EditorWindow.GetWindow(editorWindow); mmWin.SetTarget((MB3_MeshBakerRoot)momm); } 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, objectsToCombineGUIContent, true); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Objects In Scene")) { List <MB3_TextureBaker> selectedBakers = _getBakersFromTargets(targets); List <GameObject> obsToCombine = new List <GameObject>(); foreach (MB3_TextureBaker 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(); EditorGUILayout.EndVertical(); // output EditorGUILayout.Separator(); EditorGUILayout.LabelField("Output", EditorStyles.boldLabel); EditorGUILayout.PropertyField(resultType); if (GUILayout.Button(createPrefabAndMaterialLabelContent)) { List <MB3_TextureBaker> selectedBakers = _getBakersFromTargets(targets); string newPrefabPath = EditorUtility.SaveFilePanelInProject("Asset name", "", "asset", "Enter a name for the baked texture results"); if (newPrefabPath != null) { for (int i = 0; i < selectedBakers.Count; i++) { CreateCombinedMaterialAssets(selectedBakers[i], newPrefabPath, i == 0 ? true : false); } } } 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); } } if (resultType.enumValueIndex == (int)MB2_TextureBakeResults.ResultType.textureArray) { MB_TextureBakerConfigureTextureArrays.DrawTextureArrayConfiguration(momm, textureBaker, this); } else { EditorGUILayout.PropertyField(doMultiMaterial, new GUIContent("Multiple Combined Materials")); if (momm.doMultiMaterial) { MB_TextureBakerEditorConfigureMultiMaterials.DrawMultipleMaterialsMappings(momm, textureBaker, this); } else { EditorGUILayout.PropertyField(resultMaterial, new GUIContent("Combined Mesh Material")); } } // settings int labelWidth = 200; EditorGUILayout.Separator(); EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("Material Bake Options", EditorStyles.boldLabel); DrawPropertyFieldWithLabelWidth(atlasPadding, gc_atlasPadding, labelWidth); DrawPropertyFieldWithLabelWidth(maxAtlasSize, maxAtlasSizeGUIContent, labelWidth); DrawPropertyFieldWithLabelWidth(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent, labelWidth); DrawPropertyFieldWithLabelWidth(maxTilingBakeSize, maxTilingBakeSizeGUIContent, labelWidth); EditorGUI.BeginDisabledGroup(momm.doMultiMaterial); DrawPropertyFieldWithLabelWidth(considerMeshUVs, fixOutOfBoundsGUIContent, labelWidth); EditorGUI.EndDisabledGroup(); if (texturePackingAlgorithm.intValue == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePacker || texturePackingAlgorithm.intValue == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePacker_Fast || texturePackingAlgorithm.intValue == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePaker_Fast_V2_Beta) { DrawPropertyFieldWithLabelWidth(forcePowerOfTwoAtlas, forcePowerOfTwoAtlasContent, labelWidth); } DrawPropertyFieldWithLabelWidth(considerNonTextureProperties, considerNonTexturePropertiesContent, labelWidth); 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); if (MB3_TextureCombinerPipeline.USE_EXPERIMENTAL_HOIZONTALVERTICAL) { if (texturePackingAlgorithm.enumValueIndex == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePacker_Horizontal) { EditorGUILayout.PropertyField(useMaxAtlasWidthOverride, gc_useMaxAtlasWidthOverride); if (!useMaxAtlasWidthOverride.boolValue) { EditorGUI.BeginDisabledGroup(true); } EditorGUILayout.PropertyField(maxAtlasWidthOverride, gc_overrideMaxAtlasWidth); if (!useMaxAtlasWidthOverride.boolValue) { EditorGUI.EndDisabledGroup(); } } else if (texturePackingAlgorithm.enumValueIndex == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePacker_Vertical) { EditorGUILayout.PropertyField(useMaxAtlasHeightOverride, gc_useMaxAtlasHeightOverride); if (!useMaxAtlasHeightOverride.boolValue) { EditorGUI.BeginDisabledGroup(true); } EditorGUILayout.PropertyField(maxAtlasHeightOverride, gc_overrideMaxAtlasHeight); if (!useMaxAtlasHeightOverride.boolValue) { EditorGUI.EndDisabledGroup(); } } } if (texturePackingAlgorithm.intValue == (int)MB2_PackingAlgorithmEnum.MeshBakerTexturePaker_Fast_V2_Beta) { // layer field int newValueLayerTexturePackerFastMesh = EditorGUILayout.LayerField(layerTexturePackerFastMeshGUIContent, layerTexturePackerFastMesh.intValue); bool isNewValue = newValueLayerTexturePackerFastMesh == layerTexturePackerFastMesh.intValue; layerTexturePackerFastMesh.intValue = newValueLayerTexturePackerFastMesh; if (isNewValue) { Renderer[] rs = GameObject.FindObjectsOfType <Renderer>(); int numRenderersOnLayer = 0; for (int i = 0; i < rs.Length; i++) { if (rs[i].gameObject.layer == newValueLayerTexturePackerFastMesh) { numRenderersOnLayer++; } } string layerName = LayerMask.LayerToName(layerTexturePackerFastMesh.intValue); if (layerName != null && layerName.Length > 0 && numRenderersOnLayer == 0) { layerTexturePackerFastMeshMessage = null; } else { layerTexturePackerFastMeshMessage = layerTexturePackerFastMeshGUIContent.tooltip; } } string scriptDefinesErrMessage = ValidatePlayerSettingsDefineSymbols(); if (layerTexturePackerFastMesh.intValue == -1 || (layerTexturePackerFastMeshMessage != null && layerTexturePackerFastMeshMessage.Length > 0) || (scriptDefinesErrMessage != null)) { EditorGUILayout.HelpBox(layerTexturePackerFastMeshMessage + "\n\n" + scriptDefinesErrMessage, MessageType.Error); } } EditorGUILayout.PropertyField(customShaderProperties, customShaderPropertyNamesGUIContent, true); EditorGUILayout.EndVertical(); EditorGUILayout.Separator(); Color oldColor = GUI.backgroundColor; GUI.color = buttonColor; if (GUILayout.Button("Bake Materials Into Combined Material")) { List <MB3_TextureBaker> selectedBakers = _getBakersFromTargets(targets); foreach (MB3_TextureBaker tb in selectedBakers) { tb.CreateAtlases(updateProgressBar, true, new MB3_EditorMethods()); EditorUtility.ClearProgressBar(); if (tb.textureBakeResults != null) { EditorUtility.SetDirty(momm.textureBakeResults); } } } GUI.backgroundColor = oldColor; textureBaker.ApplyModifiedProperties(); if (GUI.changed) { textureBaker.SetIsDifferentCacheDirty(); } }
static void Init() { MB3_MeshBakerEditorWindow me = (MB3_MeshBakerEditorWindow)EditorWindow.GetWindow(typeof(MB3_MeshBakerEditorWindow)); }
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(); }
/* tried to see if the MultiMaterialConfig could be done using the GroupBy filters. Saddly it didn't work */ public static void ConfigureMutiMaterialsFromObjsToCombine2(MB3_TextureBaker mom, SerializedProperty resultMaterials, SerializedObject textureBaker) { if (mom.GetObjectsToCombine().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("Texture Bake Result asset must be set before using this operation."); return; } //validate that the objects to be combined are valid for (int i = 0; i < mom.GetObjectsToCombine().Count; i++) { GameObject go = mom.GetObjectsToCombine()[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; } } IGroupByFilter[] filters = new IGroupByFilter[3]; filters[0] = new GroupByOutOfBoundsUVs(); filters[1] = new GroupByShader(); filters[2] = new MB3_GroupByStandardShaderType(); List <GameObjectFilterInfo> gameObjects = new List <GameObjectFilterInfo>(); HashSet <GameObject> objectsAlreadyIncludedInBakers = new HashSet <GameObject>(); for (int i = 0; i < mom.GetObjectsToCombine().Count; i++) { GameObjectFilterInfo goaw = new GameObjectFilterInfo(mom.GetObjectsToCombine()[i], objectsAlreadyIncludedInBakers, filters); if (goaw.materials.Length > 0) //don't consider renderers with no materials { gameObjects.Add(goaw); } } //analyse meshes Dictionary <int, MB_Utility.MeshAnalysisResult> meshAnalysisResultCache = new Dictionary <int, MB_Utility.MeshAnalysisResult>(); int totalVerts = 0; for (int i = 0; i < gameObjects.Count; i++) { //string rpt = String.Format("Processing {0} [{1} of {2}]", gameObjects[i].go.name, i, gameObjects.Count); //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " A", .6f); Mesh mm = MB_Utility.GetMesh(gameObjects[i].go); int nVerts = 0; if (mm != null) { nVerts += mm.vertexCount; MB_Utility.MeshAnalysisResult mar; if (!meshAnalysisResultCache.TryGetValue(mm.GetInstanceID(), out mar)) { //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " Check Out Of Bounds UVs", .6f); MB_Utility.hasOutOfBoundsUVs(mm, ref mar); //Rect dummy = mar.uvRect; MB_Utility.doSubmeshesShareVertsOrTris(mm, ref mar); meshAnalysisResultCache.Add(mm.GetInstanceID(), mar); } if (mar.hasOutOfBoundsUVs) { int w = (int)mar.uvRect.width; int h = (int)mar.uvRect.height; gameObjects[i].outOfBoundsUVs = true; gameObjects[i].warning += " [WARNING: has uvs outside the range (0,1) tex is tiled " + w + "x" + h + " times]"; } if (mar.hasOverlappingSubmeshVerts) { gameObjects[i].submeshesOverlap = true; gameObjects[i].warning += " [WARNING: Submeshes share verts or triangles. 'Multiple Combined Materials' feature may not work.]"; } } totalVerts += nVerts; //EditorUtility.DisplayProgressBar("Analysing Scene", rpt + " Validate OBuvs Multi Material", .6f); Renderer mr = gameObjects[i].go.GetComponent <Renderer>(); if (!MB_Utility.AreAllSharedMaterialsDistinct(mr.sharedMaterials)) { gameObjects[i].warning += " [WARNING: Object uses same material on multiple submeshes. This may produce poor results when used with multiple materials or fix out of bounds uvs.]"; } } List <GameObjectFilterInfo> objsNotAddedToBaker = new List <GameObjectFilterInfo>(); Dictionary <GameObjectFilterInfo, List <List <GameObjectFilterInfo> > > gs2bakeGroupMap = MB3_MeshBakerEditorWindow.sortIntoBakeGroups3(gameObjects, objsNotAddedToBaker, filters, false, mom.maxAtlasSize); mom.resultMaterials = new MB_MultiMaterial[gs2bakeGroupMap.Keys.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 (GameObjectFilterInfo m in gs2bakeGroupMap.Keys) { MB_MultiMaterial mm = mom.resultMaterials[k] = new MB_MultiMaterial(); mm.sourceMaterials = new List <Material>(); mm.sourceMaterials.Add(m.materials[0]); string matName = folderPath + baseName + "-mat" + k + ".mat"; Material newMat = new Material(Shader.Find("Diffuse")); MB3_TextureBaker.ConfigureNewMaterialToMatchOld(newMat, m.materials[0]); AssetDatabase.CreateAsset(newMat, matName); mm.combinedMaterial = (Material)AssetDatabase.LoadAssetAtPath(matName, typeof(Material)); k++; } MBVersionEditor.UpdateIfDirtyOrScript(textureBaker); }