void OnGUI()
    {
        GUILayout.Label("Time to bake textures: " + elapsedTime);
        if (GUILayout.Button("Combine textures & build combined mesh"))
        {
            MB2_MeshBaker    meshbaker    = target.GetComponent <MB2_MeshBaker>();
            MB2_TextureBaker textureBaker = target.GetComponent <MB2_TextureBaker>();

            //These can be assets configured at runtime or you can create them
            // on the fly like this
            textureBaker.textureBakeResults = ScriptableObject.CreateInstance <MB2_TextureBakeResults>();
            textureBaker.resultMaterial     = new Material(Shader.Find("Diffuse"));

            float t1 = Time.realtimeSinceStartup;
            textureBaker.CreateAtlases();
            elapsedTime = Time.realtimeSinceStartup - t1;

            meshbaker.ClearMesh();             //only necessary if your not sure whats in the combined mesh
            meshbaker.textureBakeResults = textureBaker.textureBakeResults;
            //Add the objects to the combined mesh
            meshbaker.AddDeleteGameObjects(textureBaker.GetObjectsToCombine().ToArray(), null, true, false);

            meshbaker.Apply();
        }
    }
Пример #2
0
 public static void RebuildPrefab(MB2_MeshBakerCommon mom)
 {
     if (MB2_MeshCombiner.EVAL_VERSION)
     {
         return;
     }
     if (mom is MB2_MeshBaker)
     {
         MB2_MeshBaker mb         = (MB2_MeshBaker)mom;
         GameObject    prefabRoot = mom.resultPrefab;
         GameObject    rootGO     = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot);
         mb.meshCombiner.buildSceneMeshObject(rootGO, mb.meshCombiner.GetMesh(), true);
         string prefabPth = AssetDatabase.GetAssetPath(prefabRoot);
         PrefabUtility.ReplacePrefab(rootGO, AssetDatabase.LoadAssetAtPath(prefabPth, typeof(GameObject)), ReplacePrefabOptions.ConnectToPrefab);
         Editor.DestroyImmediate(rootGO);
     }
     else if (mom is MB2_MultiMeshBaker)
     {
         MB2_MultiMeshBaker mmb        = (MB2_MultiMeshBaker)mom;
         GameObject         prefabRoot = mom.resultPrefab;
         GameObject         rootGO     = (GameObject)PrefabUtility.InstantiatePrefab(prefabRoot);
         for (int i = 0; i < mmb.meshCombiner.meshCombiners.Count; i++)
         {
             mmb.meshCombiner.meshCombiners[i].combinedMesh.buildSceneMeshObject(rootGO, mmb.meshCombiner.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 MB2_MeshBaker or an MB2_MultiMeshBaker.");
     }
 }
	void Start(){
		mbd = GetComponent<MB2_MeshBaker>(); 
		
		// instantiate 10k game objects
		int dim = 25;
		GameObject[] gos = new GameObject[dim * dim];
		for (int i = 0; i < dim; i++){
			for (int j = 0; j < dim; j++){
				GameObject go = (GameObject) Instantiate(prefab);
				gos[i*dim + j] = go.GetComponentInChildren<MeshRenderer>().gameObject;
				go.transform.position = (new Vector3(9f*i,0,9f * j));
				//put every third object in a list so we can add and delete it later
				if ((i*dim + j) % 3 == 0){
					objsInCombined.Add(gos[i*dim + j]);
				}
			}
		}
		//add objects to combined mesh
		mbd.AddDeleteGameObjects(gos, null);
		mbd.Apply();
		
		objs = objsInCombined.ToArray();
		//start routine which will periodically add and delete objects
		StartCoroutine(largeNumber());
	}
Пример #4
0
    public static void MigrateMeshBakerToVersion3Component(GameObject go)
    {
        MB2_MeshBaker tb2 = go.GetComponent <MB2_MeshBaker>();

        if (tb2 == null)
        {
            return;
        }
        Debug.Log("Migrating Mesh Baker");
        MB3_MeshBaker tb3 = go.AddComponent <MB3_MeshBaker>();

        tb3.textureBakeResults          = tb2.textureBakeResults;
        tb3.bakeAssetsInPlaceFolderPath = tb2.bakeAssetsInPlaceFolderPath;
        tb3.objsToMesh   = tb2.objsToMesh;
        tb3.resultPrefab = tb2.resultPrefab;
        tb3.useObjsToMeshFromTexBaker      = tb2.useObjsToMeshFromTexBaker;
        tb3.meshCombiner.doCol             = tb2.doCol;
        tb3.meshCombiner.doNorm            = tb2.doNorm;
        tb3.meshCombiner.doTan             = tb2.doTan;
        tb3.meshCombiner.doUV              = tb2.doUV;
        tb3.meshCombiner.doUV1             = tb2.doUV1;
        tb3.meshCombiner.lightmapOption    = tb2.lightmapOption;
        tb3.meshCombiner.outputOption      = tb2.outputOption;
        tb3.meshCombiner.resultSceneObject = tb2.resultSceneObject;
        tb3.meshCombiner.renderType        = tb2.renderType;
        tb3.meshCombiner.targetRenderer    = tb2.meshCombiner.targetRenderer;

        DestroyImmediate(tb2);
    }
Пример #5
0
    void Start()
    {
        mbd = GetComponent <MB2_MeshBaker>();

        // instantiate 10k game objects
        int dim = 25;

        GameObject[] gos = new GameObject[dim * dim];
        for (int i = 0; i < dim; i++)
        {
            for (int j = 0; j < dim; j++)
            {
                GameObject go = (GameObject)Instantiate(prefab);
                gos[i * dim + j]      = go.GetComponentInChildren <MeshRenderer>().gameObject;
                go.transform.position = (new Vector3(9f * i, 0, 9f * j));
                //put every third object in a list so we can add and delete it later
                if ((i * dim + j) % 3 == 0)
                {
                    objsInCombined.Add(gos[i * dim + j]);
                }
            }
        }
        //add objects to combined mesh
        mbd.AddDeleteGameObjects(gos, null);
        mbd.Apply();

        objs = objsInCombined.ToArray();
        //start routine which will periodically add and delete objects
        StartCoroutine(largeNumber());
    }
Пример #6
0
    public override void OnInspectorGUI()
    {
        MB2_MeshBaker tb = (MB2_MeshBaker)target;

        if (GUILayout.Button(" MIGRATE COMPONENTS TO VERSION 3 "))
        {
            GameObject go = tb.gameObject;
            MB2_TextureBakerEditor.MigrateTestureBakerToVersion3Component(go);
            MB2_MultiMeshBakerEditor.MigrateMultiMeshBakerToVersion3Component(go);
            MigrateMeshBakerToVersion3Component(go);
        }
        mbe.OnInspectorGUI((MB2_MeshBakerCommon)target, typeof(MB_MeshBakerEditorWindow));
    }
Пример #7
0
 public static void SaveMeshsToAssetDatabase(MB2_MeshBakerCommon mom, string folderPath, string newFileNameBase)
 {
     if (MB2_MeshCombiner.EVAL_VERSION)
     {
         return;
     }
     if (mom is MB2_MeshBaker)
     {
         MB2_MeshBaker mb          = (MB2_MeshBaker)mom;
         string        newFilename = newFileNameBase + ".asset";
         string        ap          = AssetDatabase.GetAssetPath(mb.meshCombiner.GetMesh());
         if (ap == null || ap.Equals(""))
         {
             Debug.Log("Saving mesh asset to " + newFilename);
             AssetDatabase.CreateAsset(mb.meshCombiner.GetMesh(), newFilename);
         }
         else
         {
             Debug.Log("Mesh is an asset at " + ap);
         }
     }
     else if (mom is MB2_MultiMeshBaker)
     {
         MB2_MultiMeshBaker mmb = (MB2_MultiMeshBaker)mom;
         for (int i = 0; i < mmb.meshCombiner.meshCombiners.Count; i++)
         {
             string newFilename = newFileNameBase + i + ".asset";
             Mesh   mesh        = mmb.meshCombiner.meshCombiners[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 MB2_MeshBaker or an MB2_MultiMeshBaker.");
     }
 }
Пример #8
0
    void _saveBakeTextureAssets(MB2_TextureBaker target, MB_AtlasesAndRects[] mAndAs)
    {
        MB2_TextureBaker mbd = (MB2_TextureBaker)target;

        for (int i = 0; i < mAndAs.Length; i++)
        {
            MB_AtlasesAndRects mAndA  = mAndAs[i];
            Material           resMat = mbd.resultMaterial;
            if (mbd.doMultiMaterial)
            {
                resMat = mbd.resultMaterials[i].combinedMaterial;
            }
            _saveAtlasesToAssetDatabase(mAndA, resMat);
        }

        MB2_MeshBaker mb = mbd.GetComponent <MB2_MeshBaker>();

        if (mb != null)
        {
            mb.textureBakeResults = mbd.textureBakeResults;
        }
        EditorUtility.SetDirty(mbd.textureBakeResults);
    }
	void OnGUI()
	{
		scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height));

		EditorGUILayout.LabelField("Generate Report",EditorStyles.boldLabel);		
		EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None);
		
		if (GUILayout.Button("List Shaders In Scene")){
			listMaterialsInScene(false);
		}
		
		EditorGUILayout.Separator();
		MB_EditorUtil.DrawSeparator();

		EditorGUILayout.HelpBox("This feature is experimental. It should be safe to use as all it does is generate game objects with Mesh and Material bakers "+
								"on them and assets for the combined materials.\n\n" +
								"Creates bakers and combined material assets in your scene based on the groupings in 'Generate Report'."+
								"Some configuration may still be required after bakers are generated. Groups are created for objects that " +
								"use the same material(s), shader(s) and lightmap. These groups should produce good results when baked.\n\n" +
							    "This feature groups objects conservatively so bakes almost always work.   This is not the only way to group objects. Objects with different shaders can also be grouped but results are" +
							    " less preditable. Meshes with submeshes are only" +
								"grouped if all meshes use the same set of shaders.", UnityEditor.MessageType.None);
				
		EditorGUILayout.LabelField(autoGenerateGUIContent, EditorStyles.boldLabel);		
		autoGenerateMeshBakers = EditorGUILayout.Foldout(autoGenerateMeshBakers,"Show Tools");
		if ( autoGenerateMeshBakers ){

			EditorGUILayout.BeginHorizontal();
			if (GUILayout.Button("Select Folder For Combined Material Assets") ){
				generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", "");	
				generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(Application.dataPath, "") + "/";
			}
			EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder);
			EditorGUILayout.EndHorizontal();
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.LabelField("Included Objects Must Be Static", GUILayout.Width(200));
			generate_IncludeStaticObjects = EditorGUILayout.Toggle(GUIContent.none, generate_IncludeStaticObjects);
			EditorGUILayout.EndHorizontal();
			generate_LightmapOption = (LightMapOption) EditorGUILayout.EnumPopup("Lightmapping", generate_LightmapOption);
			EditorGUILayout.BeginHorizontal();
			if (GUILayout.Button("Generate Mesh Bakers")){
				listMaterialsInScene(true);
			}
			if (GUILayout.Button("Bake Every MeshBaker In Scene")){
				try{
					MB2_TextureBaker[] texBakers = (MB2_TextureBaker[]) FindObjectsOfType(typeof(MB2_TextureBaker));
					for (int i = 0; i < texBakers.Length; i++){
						texBakers[i].CreateAtlases(updateProgressBar, true, new MB2_EditorMethods());	
					}
					MB2_MeshBaker[] mBakers = (MB2_MeshBaker[]) FindObjectsOfType(typeof(MB2_MeshBaker));
					for (int i = 0; i < mBakers.Length; i++){
						if (mBakers[i].textureBakeResults != null){
					    	MB2_MeshBakerEditorFunctions._bakeIntoCombined(mBakers[i], MB_OutputOptions.bakeIntoSceneObject);	
						}
					}					
				} catch (Exception e) {
					Debug.LogError(e);
				}finally{
					EditorUtility.ClearProgressBar();
				}
			}
			EditorGUILayout.EndHorizontal();
		}
		MB_EditorUtil.DrawSeparator();
		EditorGUILayout.Separator();		
		
		EditorGUILayout.LabelField("Add Selected Meshes To Bakers",EditorStyles.boldLabel);
		EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None);
		target = (MB2_MeshBakerRoot) EditorGUILayout.ObjectField("Target to add objects to",target,typeof(MB2_MeshBakerRoot),true);
		
		if (target != null){
			targetGO = target.gameObject;
		} else {
			targetGO = null;	
		}
			
		if (targetGO != oldTargetGO){
			textureBaker = targetGO.GetComponent<MB2_TextureBaker>();
			meshBaker = targetGO.GetComponent<MB2_MeshBaker>();
			tbe = new MB2_TextureBakerEditorInternal();
			mbe = new MB2_MeshBakerEditorInternal();
			oldTargetGO = targetGO;
		}		
		
		onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);
		
		onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects);
		
		excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs);
			
		mat = (Material) EditorGUILayout.ObjectField("Using Material",mat,typeof(Material),true);
		shaderMat = (Material) EditorGUILayout.ObjectField("Using Shader",shaderMat,typeof(Material),true);
		
		string[] lightmapDisplayValues = new string[257];
		int[] lightmapValues = new int[257];
		lightmapValues[0] = -2;
		lightmapValues[1] = -1;
		lightmapDisplayValues[0] = "don't filter on lightmapping";
		lightmapDisplayValues[1] = "not lightmapped";
		for (int i = 2; i < lightmapDisplayValues.Length; i++){
			lightmapDisplayValues[i] = "" + i;
			lightmapValues[i] = i;
		}
		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Using Lightmap Index ");
		lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex,
												 lightmapDisplayValues,
												 lightmapValues);
		EditorGUILayout.EndHorizontal();
		
		if (GUILayout.Button("Add Selected Meshes")){
			addSelectedObjects();
		}
		
		/*
		if (GUILayout.Button("Add LOD To Selected")){
			addLODToSelected();
		}
		
		if (GUILayout.Button("Remove LOD From All")){
			LODInternal[] lods = (LODInternal[]) FindObjectsOfType(typeof(LODInternal));
			for (int i = 0; i < lods.Length; i++){
				DestroyImmediate(lods[i]);
			}
		}
		*/		
		
		if (textureBaker != null){
			MB_EditorUtil.DrawSeparator();
			tbFoldout = EditorGUILayout.Foldout(tbFoldout,"Texture Baker");
			if (tbFoldout){
				tbe.DrawGUI((MB2_TextureBaker) textureBaker, typeof(MB_MeshBakerEditorWindow));
			}
			
		}
		if (meshBaker != null){
			MB_EditorUtil.DrawSeparator();
			mbFoldout = EditorGUILayout.Foldout(mbFoldout,"Mesh Baker");
			if (mbFoldout){
				mbe.DrawGUI((MB2_MeshBaker) meshBaker, typeof(MB_MeshBakerEditorWindow));
			}
		}
		EditorGUILayout.EndScrollView();
	}
Пример #10
0
    void OnGUI()
    {
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height));

        EditorGUILayout.LabelField("Generate Report", EditorStyles.boldLabel);
        EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for planning which objects to combine.", UnityEditor.MessageType.None);

        if (GUILayout.Button("List Shaders In Scene"))
        {
            listMaterialsInScene(false);
        }

        EditorGUILayout.Separator();
        MB_EditorUtil.DrawSeparator();

        EditorGUILayout.HelpBox("Creates bakers and combined material assets in your scene based on the groupings in 'Generate Report'." +
                                "Some configuration may still be required after bakers are generated. Groups are created for objects that " +
                                "use the same material(s), shader(s) and lightmap. These groups should produce good results when baked.\n\n" +
                                "This feature groups objects conservatively so bakes almost always work.   This is not the only way to group objects. Objects with different shaders can also be grouped but results are" +
                                " less preditable. Meshes with submeshes are only" +
                                "grouped if all meshes use the same set of shaders.", UnityEditor.MessageType.None);

        EditorGUILayout.LabelField(autoGenerateGUIContent, EditorStyles.boldLabel);
        autoGenerateMeshBakers = EditorGUILayout.Foldout(autoGenerateMeshBakers, "Show Tools");
        if (autoGenerateMeshBakers)
        {
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Select Folder For Combined Material Assets"))
            {
                generate_AssetsFolder = EditorUtility.SaveFolderPanel("Create Combined Material Assets In Folder", "", "");
                generate_AssetsFolder = "Assets" + generate_AssetsFolder.Replace(UnityEngine.Application.dataPath, "") + "/";
            }
            EditorGUILayout.LabelField("Folder: " + generate_AssetsFolder);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Included Objects Must Be Static", GUILayout.Width(200));
            generate_IncludeStaticObjects = EditorGUILayout.Toggle(GUIContent.none, generate_IncludeStaticObjects);
            EditorGUILayout.EndHorizontal();
            generate_LightmapOption = (LightMapOption)EditorGUILayout.EnumPopup("Lightmapping", generate_LightmapOption);
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Generate Mesh Bakers"))
            {
                listMaterialsInScene(true);
            }
            if (GUILayout.Button("Bake Every MeshBaker In Scene"))
            {
                try{
                    MB2_TextureBaker[] texBakers = (MB2_TextureBaker[])FindObjectsOfType(typeof(MB2_TextureBaker));
                    for (int i = 0; i < texBakers.Length; i++)
                    {
                        texBakers[i].CreateAndSaveAtlases(updateProgressBar, System.IO.File.WriteAllBytes);
                    }
                    MB2_MeshBaker[] mBakers = (MB2_MeshBaker[])FindObjectsOfType(typeof(MB2_MeshBaker));
                    for (int i = 0; i < mBakers.Length; i++)
                    {
                        if (mBakers[i].textureBakeResults != null)
                        {
                            MB2_MeshBakerEditorInternal._bakeIntoCombined(mBakers[i], MB_OutputOptions.bakeIntoSceneObject);
                        }
                    }
                } catch (Exception e) {
                    Debug.LogError(e);
                }finally{
                    EditorUtility.ClearProgressBar();
                }
            }
            EditorGUILayout.EndHorizontal();
        }
        MB_EditorUtil.DrawSeparator();
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Add Selected Meshes To Bakers", EditorStyles.boldLabel);
        EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None);
        target = (MB2_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB2_MeshBakerRoot), true);

        if (target != null)
        {
            targetGO = target.gameObject;
        }
        else
        {
            targetGO = null;
        }

        if (targetGO != oldTargetGO)
        {
            textureBaker = targetGO.GetComponent <MB2_TextureBaker>();
            meshBaker    = targetGO.GetComponent <MB2_MeshBaker>();
            tbe          = new MB2_TextureBakerEditorInternal();
            mbe          = new MB2_MeshBakerEditorInternal();
            oldTargetGO  = targetGO;
        }

        onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);

        onlyEnabledObjects = EditorGUILayout.Toggle("Only Enabled Objects", onlyEnabledObjects);

        excludeMeshesWithOBuvs = EditorGUILayout.Toggle("Exclude meshes with out-of-bounds UVs", excludeMeshesWithOBuvs);

        mat       = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true);
        shaderMat = (Material)EditorGUILayout.ObjectField("Using UnityEngine.Shader", shaderMat, typeof(Material), true);

        string[] lightmapDisplayValues = new string[257];
        int[]    lightmapValues        = new int[257];
        lightmapValues[0]        = -2;
        lightmapValues[1]        = -1;
        lightmapDisplayValues[0] = "don't filter on lightmapping";
        lightmapDisplayValues[1] = "not lightmapped";
        for (int i = 2; i < lightmapDisplayValues.Length; i++)
        {
            lightmapDisplayValues[i] = "" + i;
            lightmapValues[i]        = i;
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Using Lightmap Index ");
        lightmapIndex = EditorGUILayout.IntPopup(lightmapIndex,
                                                 lightmapDisplayValues,
                                                 lightmapValues);
        EditorGUILayout.EndHorizontal();

        if (GUILayout.Button("Add Selected Meshes"))
        {
            addSelectedObjects();
        }

        /*
         * if (GUILayout.Button("Add LOD To Selected")){
         *      addLODToSelected();
         * }
         *
         * if (GUILayout.Button("Remove LOD From All")){
         *      MB2_LOD[] lods = (MB2_LOD[]) FindObjectsOfType(typeof(MB2_LOD));
         *      for (int i = 0; i < lods.Length; i++){
         *              DestroyImmediate(lods[i]);
         *      }
         * }
         */

        if (textureBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            tbFoldout = EditorGUILayout.Foldout(tbFoldout, "UnityEngine.Texture Baker");
            if (tbFoldout)
            {
                tbe.DrawGUI((MB2_TextureBaker)textureBaker);
            }
        }
        if (meshBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker");
            if (mbFoldout)
            {
                mbe.DrawGUI((MB2_MeshBaker)meshBaker);
            }
        }
        EditorGUILayout.EndScrollView();
    }
Пример #11
0
    void OnGUI()
    {
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height));

        EditorGUILayout.HelpBox("List shaders in scene prints a report to the console of shaders and which objects use them. This is useful for grouping objects to be combined. SkinnedMeshRenderers are ignored.", UnityEditor.MessageType.None);
        if (GUILayout.Button("List Shaders In Scene"))
        {
            listMaterialsInScene();
        }

        EditorGUILayout.Separator();
        EditorGUILayout.Separator();
        EditorGUILayout.HelpBox("Select one or more objects in the hierarchy view. Child Game Objects with MeshRender will be added. Use the fields below to filter what is added.", UnityEditor.MessageType.None);
        target = (MB2_MeshBakerRoot)EditorGUILayout.ObjectField("Target to add objects to", target, typeof(MB2_MeshBakerRoot), true);

        if (target != null)
        {
            targetGO = target.gameObject;
        }
        else
        {
            targetGO = null;
        }

        if (targetGO != oldTargetGO)
        {
            textureBaker = targetGO.GetComponent <MB2_TextureBaker>();
            meshBaker    = targetGO.GetComponent <MB2_MeshBaker>();
            tbe          = new MB2_TextureBakerEditorInternal();
            mbe          = new MB2_MeshBakerEditorInternal();
            oldTargetGO  = targetGO;
        }

        onlyStaticObjects = EditorGUILayout.Toggle("Only Static Objects", onlyStaticObjects);

        mat       = (Material)EditorGUILayout.ObjectField("Using Material", mat, typeof(Material), true);
        shaderMat = (Material)EditorGUILayout.ObjectField("Using Shader", shaderMat, typeof(Material), true);

        if (GUILayout.Button("Add Selected Meshes"))
        {
            addSelectedObjects();
        }

        if (textureBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            tbFoldout = EditorGUILayout.Foldout(tbFoldout, "Texture Baker");
            if (tbFoldout)
            {
                tbe.DrawGUI((MB2_TextureBaker)textureBaker);
            }
        }
        if (meshBaker != null)
        {
            MB_EditorUtil.DrawSeparator();
            mbFoldout = EditorGUILayout.Foldout(mbFoldout, "Mesh Baker");
            if (mbFoldout)
            {
                mbe.DrawGUI((MB2_MeshBaker)meshBaker);
            }
        }
        EditorGUILayout.EndScrollView();
    }