public void DrawGUI(SerializedObject textureBaker, TextureCombineEntrance momm, Type editorWindow) { if (textureBaker == null) { return; } textureBaker.Update(); showInstructions = EditorGUILayout.Foldout(showInstructions, "说明:"); if (showInstructions) { EditorGUILayout.HelpBox("1. Add scene objects or prefabs to combine. For best results these should use the same shader as result material.\n\n" + "2. Create Empty Assets For Combined Material(s)\n\n" + "3. Check that shader on result material(s) are correct.\n\n" + "4. Bake materials into combined material(s).\n\n" + "5. Look at warnings/errors in console. Decide if action needs to be taken.\n\n" + "6. You are now ready to build combined meshs or adjust meshes to use the combined material(s).", UnityEditor.MessageType.None); } EditorGUILayout.Separator(); // Selected objects EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("加入合并物体 ", EditorStyles.boldLabel); if (GUILayout.Button(openToolsWindowLabelContent)) { IMeshCombinerEditorWindow mmWin = (IMeshCombinerEditorWindow)EditorWindow.GetWindow(editorWindow); mmWin.target = (MeshBakerRoot)momm; } object[] objs = EditorMethods.DropZone("将包含 Renderer 组件的游戏物体或父物体托至此处加入合并列表中", 300, 50); EditorMethods.AddDroppedObjects(objs, momm); //合并列表属性 EditorGUILayout.PropertyField(objsToMesh, objectsToCombineGUIContent, true); EditorGUILayout.Separator(); //合并列表属性下方按钮 EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("选中合并列表中的游戏物体")) { Selection.objects = momm.GetObjectsToCombine().ToArray(); if (momm.GetObjectsToCombine().Count > 0) { SceneView.lastActiveSceneView.pivot = momm.GetObjectsToCombine()[0].transform.position; } } //排序按钮 if (GUILayout.Button(gc_SortAlongAxis)) { MeshBakerRoot.ZSortObjects sorter = new MeshBakerRoot.ZSortObjects(); sorter.sortAxis = sortOrderAxis.vector3Value; sorter.SortByDistanceAlongAxis(momm.GetObjectsToCombine()); } EditorGUILayout.PropertyField(sortOrderAxis, GUIContent.none); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); // output EditorGUILayout.Separator(); EditorGUILayout.LabelField("输出", EditorStyles.boldLabel); if (GUILayout.Button(createPrefabAndMaterialLabelContent)) { string newPrefabPath = EditorUtility.SaveFilePanelInProject("新建合并材质资源名称", "", "asset", "Enter a name for the baked texture results"); if (newPrefabPath != null) { CreateCombinedMaterialAssets(momm, newPrefabPath); } } EditorGUILayout.PropertyField(textureBakeResults, textureBakeResultsGUIContent); if (textureBakeResults.objectReferenceValue != null) { showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport) { EditorGUILayout.HelpBox(((TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } //多材质合并 EditorGUILayout.PropertyField(doMultiMaterial, new GUIContent("是否多材质合并")); if (momm.doMultiMaterial) { EditorGUILayout.BeginVertical(editorStyles.multipleMaterialBackgroundStyle); EditorGUILayout.LabelField("原始材质合并映射信息", EditorStyles.boldLabel); float oldLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 300; EditorGUILayout.PropertyField(doMultiMaterialIfOBUVs, gc_DoMultiMaterialSplitAtlasesIfOBUVs); EditorGUILayout.PropertyField(doMultiMaterialSplitAtlasesIfTooBig, gc_DoMultiMaterialSplitAtlasesIfTooBig); EditorGUIUtility.labelWidth = oldLabelWidth; if (GUILayout.Button(configMultiMatFromObjsContent)) { ConfigureMutiMaterialsFromObjsToCombine(momm, resultMaterials, textureBaker); } EditorGUILayout.BeginHorizontal(); resultMaterialsFoldout = EditorGUILayout.Foldout(resultMaterialsFoldout, combinedMaterialsGUIContent); //添加按钮 if (GUILayout.Button(insertContent, EditorStyles.miniButtonLeft, buttonWidth)) { if (resultMaterials.arraySize == 0) { momm.resultMaterials = new MultiMaterial[1]; momm.resultMaterials[0].considerMeshUVs = momm.fixOutOfBoundsUVs; } else { int idx = resultMaterials.arraySize - 1; resultMaterials.InsertArrayElementAtIndex(idx); resultMaterials.GetArrayElementAtIndex(idx + 1).FindPropertyRelative("considerMeshUVs").boolValue = momm.fixOutOfBoundsUVs; } } //删除按钮 if (GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)) { resultMaterials.DeleteArrayElementAtIndex(resultMaterials.arraySize - 1); } EditorGUILayout.EndHorizontal(); //合并材质列表 if (resultMaterialsFoldout) { for (int i = 0; i < resultMaterials.arraySize; i++) { EditorGUILayout.Separator(); if (i % 2 == 1) { EditorGUILayout.BeginVertical(editorStyles.multipleMaterialBackgroundStyle); } else { EditorGUILayout.BeginVertical(editorStyles.multipleMaterialBackgroundStyleDarker); } string s = ""; if (i < momm.resultMaterials.Length && momm.resultMaterials[i] != null && momm.resultMaterials[i].combinedMaterial != null) { s = momm.resultMaterials[i].combinedMaterial.shader.ToString(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("--- " + i + ":" + s, EditorStyles.boldLabel); //删除按钮 if (GUILayout.Button(deleteContent, EditorStyles.miniButtonRight, buttonWidth)) { resultMaterials.DeleteArrayElementAtIndex(i); } EditorGUILayout.EndHorizontal(); if (i < resultMaterials.arraySize) { EditorGUILayout.Separator(); SerializedProperty resMat = resultMaterials.GetArrayElementAtIndex(i); EditorGUILayout.PropertyField(resMat.FindPropertyRelative("combinedMaterial")); EditorGUILayout.PropertyField(resMat.FindPropertyRelative("considerMeshUVs")); SerializedProperty sourceMats = resMat.FindPropertyRelative("sourceMaterials"); EditorGUILayout.PropertyField(sourceMats, true); } EditorGUILayout.EndVertical(); } } EditorGUILayout.EndVertical(); } else { EditorGUILayout.PropertyField(resultMaterial, new GUIContent("已合并材质")); } // settings 材质合并选项 int labelWidth = 200; EditorGUILayout.Separator(); EditorGUILayout.Separator(); EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); EditorGUILayout.LabelField("材质合并选项", EditorStyles.boldLabel); // Atlas 间隙 DrawPropertyFieldWithLabelWidth(atlasPadding, gc_atlasPadding, labelWidth); // Atlas 最大尺寸 DrawPropertyFieldWithLabelWidth(maxAtlasSize, maxAtlasSizeGUIContent, labelWidth); // POT DrawPropertyFieldWithLabelWidth(resizePowerOfTwoTextures, resizePowerOfTwoGUIContent, labelWidth); // DrawPropertyFieldWithLabelWidth(maxTilingBakeSize, maxTilingBakeSizeGUIContent, labelWidth); EditorGUI.BeginDisabledGroup(momm.doMultiMaterial); //是否计算网格 UV DrawPropertyFieldWithLabelWidth(considerMeshUVs, fixOutOfBoundsGUIContent, labelWidth); EditorGUI.EndDisabledGroup(); if (texturePackingAlgorithm.intValue == (int)PackingAlgorithmEnum.MeshBakerTexturePacker || texturePackingAlgorithm.intValue == (int)PackingAlgorithmEnum.MeshBakerTexturePacker_Fast) { //强制 POT DrawPropertyFieldWithLabelWidth(forcePowerOfTwoAtlas, forcePowerOfTwoAtlasContent, labelWidth); } //非 Texture 属性 DrawPropertyFieldWithLabelWidth(considerNonTextureProperties, considerNonTexturePropertiesContent, labelWidth); if (texturePackingAlgorithm.intValue == (int)PackingAlgorithmEnum.UnitysPackTextures) { EditorGUILayout.HelpBox("Unity's texture packer has memory problems and frequently crashes the editor.", MessageType.Warning); } //合并算法选项 EditorGUILayout.PropertyField(texturePackingAlgorithm, texturePackingAgorithmGUIContent); if (TextureCombinerPipeline.USE_EXPERIMENTAL_HOIZONTALVERTICAL) { if (texturePackingAlgorithm.enumValueIndex == (int)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)PackingAlgorithmEnum.MeshBakerTexturePacker_Vertical) { EditorGUILayout.PropertyField(useMaxAtlasHeightOverride, gc_useMaxAtlasHeightOverride); if (!useMaxAtlasHeightOverride.boolValue) { EditorGUI.BeginDisabledGroup(true); } EditorGUILayout.PropertyField(maxAtlasHeightOverride, gc_overrideMaxAtlasHeight); if (!useMaxAtlasHeightOverride.boolValue) { EditorGUI.EndDisabledGroup(); } } } EditorGUILayout.PropertyField(customShaderProperties, customShaderPropertyNamesGUIContent, true); EditorGUILayout.EndVertical(); EditorGUILayout.Separator(); Color oldColor = GUI.backgroundColor; GUI.color = buttonColor; if (GUILayout.Button("合并")) { momm.CreateAtlases(updateProgressBar, true, new EditorMethods()); EditorUtility.ClearProgressBar(); if (momm.textureBakeResults != null) { EditorUtility.SetDirty(momm.textureBakeResults); } } GUI.backgroundColor = oldColor; textureBaker.ApplyModifiedProperties(); if (GUI.changed) { textureBaker.SetIsDifferentCacheDirty(); } }
private void DrawGUI(SerializedObject meshBaker, MeshBakerCommon target, System.Type editorWindowType) { if (meshBaker == null) { return; } meshBaker.Update(); //说明窗口 showInstructions = EditorGUILayout.Foldout(showInstructions, "说明:"); 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(); } MeshBakerCommon momm = (MeshBakerCommon)target; //已合并材质资源 EditorGUILayout.PropertyField(textureBakeResults, gc_textureBakeResultsGUIContent); if (textureBakeResults.objectReferenceValue != null) { showContainsReport = EditorGUILayout.Foldout(showContainsReport, "Shaders & Materials Contained"); if (showContainsReport) { EditorGUILayout.HelpBox(((TextureBakeResults)textureBakeResults.objectReferenceValue).GetDescription(), MessageType.Info); } } EditorGUILayout.BeginVertical(editorStyles.editorBoxBackgroundStyle); //参与网格合并物体列表 EditorGUILayout.LabelField("合并物体列表", EditorStyles.whiteBoldLabel); 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)) { IMeshCombinerEditorWindow mmWin = (IMeshCombinerEditorWindow)EditorWindow.GetWindow(editorWindowType); mmWin.target = (MeshBakerRoot)target; } object[] objs = EditorMethods.DropZone("Drag & Drop Renderers Or Parents Here To Add Objects To Be Combined", 300, 50); 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)) { MeshBakerRoot.ZSortObjects sorter = new 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("输出:", EditorStyles.boldLabel); EditorGUILayout.PropertyField(outputOptions, gc_outputOptoinsGUIContent); //输出方式设置 if (momm.meshCombiner.outputOption == OutputOptions.bakeIntoSceneObject) { momm.meshCombiner.resultSceneObject = (GameObject)EditorGUILayout.ObjectField("合并后游戏物体", momm.meshCombiner.resultSceneObject, typeof(GameObject), true); if (momm is MeshCombinerEntrance) { 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"); ((MeshCombineHandler)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } //合并为预制体 else if (momm.meshCombiner.outputOption == OutputOptions.bakeIntoPrefab) { momm.resultPrefab = (GameObject)EditorGUILayout.ObjectField( gc_combinedMeshPrefabGUIContent, momm.resultPrefab, typeof(GameObject), true); if (momm is MeshCombinerEntrance) { 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"); ((MeshCombineHandler)momm.meshCombiner).SetMesh(nm); mesh.objectReferenceValue = nm; } } } //合并磁盘中文件 else if (momm.meshCombiner.outputOption == 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."); } 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("网格合并设置:", EditorStyles.boldLabel); bool settingsEnabled = true; //------------- Mesh Baker Settings is a bit tricky because it is an interface. 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 IMeshCombinerSettingHolder itf = (IMeshCombinerSettingHolder)((GameObject)obj).GetComponent(typeof(IMeshCombinerSettingHolder)); if (itf != null) { settingsEnabled = false; Component settingsHolderComponent = (Component)itf; if (settingsHolder.objectReferenceValue != settingsHolderComponent) { settingsHolder.objectReferenceValue = settingsHolderComponent; meshBakerSettingsExternal = new MeshCombineSettingEditor(); meshBakerSettingsExternal.OnEnable(itf.GetMeshBakerSettingsAsSerializedProperty()); } } else { settingsEnabled = true; settingsHolder = null; if (meshBakerSettingsExternal != null) { meshBakerSettingsExternal.OnDisable(); meshBakerSettingsExternal = null; } } } else if (obj is IMeshCombinerSettingHolder) { settingsEnabled = false; if (settingsHolder.objectReferenceValue != obj) { settingsHolder.objectReferenceValue = obj; meshBakerSettingsExternal = new MeshCombineSettingEditor(); meshBakerSettingsExternal.OnEnable(((IMeshCombinerSettingHolder)obj).GetMeshBakerSettingsAsSerializedProperty()); } } 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); } else { if (meshBakerSettingsExternal == null) { meshBakerSettingsExternal = new MeshCombineSettingEditor(); meshBakerSettingsExternal.OnEnable(((IMeshCombinerSettingHolder)obj).GetMeshBakerSettingsAsSerializedProperty()); } var set = settingsHolder.objectReferenceValue; var settings = (IMeshCombinerSettingHolder)settingsHolder.objectReferenceValue; meshBakerSettingsExternal.DrawGUI(settings.GetMeshBakerSettings(), settingsEnabled); } Color oldColor = GUI.backgroundColor; GUI.backgroundColor = buttonColor; if (GUILayout.Button("合并")) { bake(momm, ref meshBaker); } GUI.backgroundColor = oldColor; string enableRenderersLabel; bool disableRendererInSource = false; if (momm.GetObjectsToCombine().Count > 0) { Renderer r = MeshBakerUtility.GetRenderer(momm.GetObjectsToCombine()[0]); if (r != null && r.enabled) { disableRendererInSource = true; } } if (disableRendererInSource) { enableRenderersLabel = "隐藏源游戏物体"; } else { enableRenderersLabel = "显示源游戏物体"; } if (GUILayout.Button(enableRenderersLabel)) { momm.EnableDisableSourceObjectRenderers(!disableRendererInSource); } meshBaker.ApplyModifiedProperties(); meshBaker.SetIsDifferentCacheDirty(); }