Unity custom EditorWindow not working

Here is my code:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class LevelEdit : EditorWindow {
	public string[] options = new string[] {"Dirt","Stone","GrassNormal","GrassBeach"};
	Sprite[] tilesprites;
	List<GUIContent> _ticons = new List<GUIContent> ();
	GUIContent[] tileicons;
	public int index = 0;
	int tindex = 0;
	bool loaded = false;
	bool creating;
	// Add menu item named "My Window" to the Window menu
	[MenuItem("Window/Level Editor")]
	public static void ShowWindow()
	{
		//Show existing window instance. If one doesn't exist, make one.
		EditorWindow window = GetWindow(typeof(LevelEdit));
		window.Show ();
	}
	public static Texture2D textureFromSprite(Sprite sprite)
	{
		if(sprite.rect.width != sprite.texture.width){
			Texture2D newText = new Texture2D((int)sprite.rect.width,(int)sprite.rect.height);
			Color[] newColors = sprite.texture.GetPixels((int)sprite.textureRect.x, 
				(int)sprite.textureRect.y, 
				(int)sprite.textureRect.width, 
				(int)sprite.textureRect.height );
			newText.SetPixels(newColors);
			newText.Apply();
			return newText;
		} else
			return sprite.texture;
	}

	void OnGUI()
	{
		GUILayout.Label ("Base Settings", EditorStyles.boldLabel);
		index = EditorGUILayout.Popup(index, options);
		creating = EditorGUILayout.Toggle ("Place Blocks", creating);
		if (loaded) {
			tindex = EditorGUILayout.Popup(tindex, tileicons);
		}
		if (GUILayout.Button ("Load")) {
			loaded = true;
			string tileprefix = "Tiles_" + index;
			tilesprites = Resources.LoadAll<Sprite>("Tiles/" + tileprefix);

			foreach (Sprite tile in tilesprites) {
				_ticons.Add (new GUIContent (textureFromSprite(tile), tile.name));
			}
			tileicons = _ticons.ToArray ();
		}

		EditorGUILayout.EndToggleGroup ();
	}
}

I am trying to write a level editor for a game I am working on. There is supposed to be a popup box where you can select a type of tile, then hit “Load”, then select a specific tile sprite from another popup that should appear after you hit “Load”, however, when I run it, all I get is this window:

84650-screen-shot-2016-12-23-at-102048-pm.png

which is completely unresponsive. (I can’t drag or close it)

This doesn’t seem to be a problem with Unity itself as the documentary code works just fine, but whenever I add anything else to it, it breaks.

If it is related at all, I also get this error in the console,

InvalidOperationException: Operation is not valid due to the current state of the object
System.Collections.Generic.Stack`1[System.Boolean].Pop ()

I’m running Unity 5.3 on a Mac OS X 10.9

Thanks in advance

Hi @CheesePlusPlus,

I do not know what your end result with this window will be but the script below should help (no errors/popups work/sprites load to popups)

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq; 

public class LevelEdit : EditorWindow
{
    public string[] options = new string[] {"Dirt","Stone","GrassNormal","GrassBeach"};
    List<Sprite> tileSprites = new List<Sprite>();
    List<GUIContent> tileIcons = new List<GUIContent>();
    public int index = 0;
    int tIndex = -1;
    bool creating = false;
    static EditorWindow window;
    
    // Add menu item named "My Window" to the Window menu
    [MenuItem("Window/Level Editor")]
    public static void ShowWindow()
    {
        //Show existing window instance. If one doesn't exist, make one.
        window = GetWindow(typeof(LevelEdit));
        window.minSize = new Vector2(window.position.width, 140);
        window.Show ();
    }

    void OnGUI()
    {
        GUILayout.Label ("Base Settings", EditorStyles.boldLabel);
        index = EditorGUILayout.Popup("Options", index, options);

        // either do this
        creating = EditorGUILayout.Toggle ("Place Blocks", creating);

        // or this - but you do not need both
//        creating = EditorGUILayout.BeginToggleGroup("Place Blocks", creating);
//        EditorGUILayout.EndToggleGroup ();


        if (GUILayout.Button ("Load"))
        {
            tileIcons.Clear();
            tileSprites.Clear();
            tIndex = 0;

            string tilePrefix = "Tiles_" + index;
            tileSprites = Resources.LoadAll<Sprite>("Tiles/" + tilePrefix).ToList();

            foreach (Sprite tile in tileSprites)
            {
                tileIcons.Add (new GUIContent (tile.name, tile.texture));
            }
        }

	    if (tileIcons.Count > 0)
        {
	        tIndex = EditorGUILayout.Popup(tIndex, tileIcons.ToArray());
	        if (GUI.Button (new Rect(window.position.width - 70, window.position.height - 30, 60, 20), "Use"))
	        {
                // place your code here before closing the window
                window.Close();
	        }
	    }
    }
}

Note: The script above most go in the Editor folder (If you do not have one you need to create one). You can also accomplish the same thing using a ScriptableWizard like so

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Linq; 
 
public class LevelEdit : ScriptableWizard
{
 
    private static string[] options = new string[] {"Dirt","Stone","GrassNormal","GrassBeach"};

    public int index = 0;

    List<Sprite> tileSprites = new List<Sprite>();
    List<GUIContent> tileIcons = new List<GUIContent>();

    int tIndex = -1;
    bool loaded = false;
    bool creating = false;

    static Camera cam;
    static Camera lastUsedCam;
 
    static EditorWindow window;
 
    // Add menu item named "My Window" to the Window menu
    [MenuItem("Window/Level Editor")]
    static void CreateWizard()
    {
        cam = Camera.current;
        // Hack because camera.current doesn't return editor camera if scene view doesn't have focus
        if (!cam)
            cam = lastUsedCam;
        else
            lastUsedCam = cam;
        ScriptableWizard.DisplayWizard("Level Edit", typeof(LevelEdit));
        window = GetWindow(typeof(LevelEdit));
        // make sure the window is large enough to contain everything (modify as needed)
        window.minSize = new Vector2(window.position.width, 140);
    }
 
 
    void OnWizardUpdate()
    {
    }
 
 
    void OnWizardCreate()
    {
    }

	void OnGUI()
	{
	    GUILayout.Label ("Base Settings", EditorStyles.boldLabel);

	    index = EditorGUILayout.Popup("Options", index, options);
        creating = EditorGUILayout.Toggle ("Place Blocks", creating);

	    if (GUILayout.Button ("Load"))
	    {
	        tileIcons.Clear();
	        tileSprites.Clear();
	        tIndex = 0;

	        string tilePrefix = "Tiles_" + index;
	        tileSprites = Resources.LoadAll<Sprite>("Tiles/" + tilePrefix).ToList();

	        foreach (Sprite tile in tileSprites)
	        {
	            tileIcons.Add (new GUIContent (tile.name, tile.texture));
	        }
	    }

	    if (tileIcons.Count > 0)
	    {
	        tIndex = EditorGUILayout.Popup(tIndex, tileIcons.ToArray());
	        if (GUI.Button (new Rect(window.position.width - 70, window.position.height - 30, 60, 20), "Use"))
	        {
	            // place your code here before closing the window
	            window.Close();
	        }
	    }
	}
}

Note: The script above is not placed in the editor folder. I also added an extra button called Use which shows up at the bottom right corner of the window after the Load button is pressed.

The code from both scripts does no more that what you asked, you will need to place the extra code needed to handle the image that you selected. This can be don right before window.Close();.