void LoadTileMapData()
	{
		width = tileMap.width;
		height = tileMap.height;
		partitionSizeX = tileMap.partitionSizeX;
		partitionSizeY = tileMap.partitionSizeY;
	
		GetEditorData();

		if (tileMap.data && editorData && tileMap.Editor__SpriteCollection != null)
		{
			// Rebuild the palette
			editorData.CreateDefaultPalette(tileMap.SpriteCollectionInst, editorData.paletteBrush, editorData.paletteTilesPerRow);
		}
		
		// Rebuild the render utility
		if (sceneGUI != null)
		{
			sceneGUI.Destroy();
		}
		sceneGUI = new tk2dTileMapSceneGUI(this, tileMap, editorData);
		
		// Rebuild the brush renderer
		brushRenderer = null;
	}
    void LoadTileMapData()
    {
        buildKey = tileMap.buildKey;

        string editorDataPath = AssetDatabase.GUIDToAssetPath(tileMap.editorDataGUID);

        editorData = Resources.LoadAssetAtPath(editorDataPath, typeof(tk2dTileMapEditorData)) as tk2dTileMapEditorData;

        width          = tileMap.width;
        height         = tileMap.height;
        partitionSizeX = tileMap.partitionSizeX;
        partitionSizeY = tileMap.partitionSizeY;

        if (tileMap.data && editorData)
        {
            // Rebuild the palette
            editorData.CreateDefaultPalette(tileMap.spriteCollection, editorData.paletteBrush, editorData.paletteTilesPerRow);
        }

        // Rebuild the render utility
        if (sceneGUI != null)
        {
            sceneGUI.Destroy();
        }
        sceneGUI = new tk2dTileMapSceneGUI(this, tileMap, editorData);

        // Rebuild the brush renderer
        if (brushRenderer != null)
        {
            brushRenderer.Destroy();
        }
        brushRenderer = new tk2dEditor.BrushRenderer(tileMap.spriteCollection);
    }
    void DrawSettingsPanel()
    {
        // Tilemap data
        tk2dTileMapData newData = (tk2dTileMapData)EditorGUILayout.ObjectField("Tile Map Data", tileMap.data, typeof(tk2dTileMapData), false);

        if (newData != tileMap.data)
        {
            tileMap.data = newData;
            LoadTileMapData();
        }
        if (tileMap.data == null)
        {
            if (tk2dGuiUtility.InfoBoxWithButtons(
                    "TileMap needs an data object to proceed. " +
                    "Please create one or drag an existing data object into the inspector slot.\n",
                    tk2dGuiUtility.WarningLevel.Info,
                    "Create") != -1)
            {
                string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Data", "tileMapData", "asset", "");
                if (assetPath.Length > 0)
                {
                    tk2dTileMapData tileMapData = ScriptableObject.CreateInstance <tk2dTileMapData>();
                    AssetDatabase.CreateAsset(tileMapData, assetPath);
                    tileMap.data = tileMapData;
                    EditorUtility.SetDirty(tileMap);

                    Init(tileMapData);
                    LoadTileMapData();
                }
            }
        }

        // Editor data
        tk2dTileMapEditorData newEditorData = (tk2dTileMapEditorData)EditorGUILayout.ObjectField("Editor Data", editorData, typeof(tk2dTileMapEditorData), false);

        if (newEditorData != editorData)
        {
            string assetPath = AssetDatabase.GetAssetPath(newEditorData);
            if (assetPath.Length > 0)
            {
                tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
                EditorUtility.SetDirty(tileMap);
                LoadTileMapData();
            }
        }
        if (editorData == null)
        {
            if (tk2dGuiUtility.InfoBoxWithButtons(
                    "TileMap needs an editor data object to proceed. " +
                    "Please create one or drag an existing data object into the inspector slot.\n",
                    tk2dGuiUtility.WarningLevel.Info,
                    "Create") != -1)
            {
                string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Editor Data", "tileMapEditorData", "asset", "");
                if (assetPath.Length > 0)
                {
                    tk2dTileMapEditorData tileMapEditorData = ScriptableObject.CreateInstance <tk2dTileMapEditorData>();
                    AssetDatabase.CreateAsset(tileMapEditorData, assetPath);
                    tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
                    EditorUtility.SetDirty(tileMap);
                    LoadTileMapData();
                }
            }
        }

        // Sprite collection
        Object selectedSpriteCollectionObject = EditorGUILayout.ObjectField("Sprite Collection", tileMap.spriteCollection, typeof(Object), false) as Object;

        if (selectedSpriteCollectionObject != tileMap.spriteCollection)
        {
            string    assetPath = AssetDatabase.GetAssetPath(selectedSpriteCollectionObject);
            string    guid      = AssetDatabase.AssetPathToGUID(assetPath);
            tk2dIndex index     = tk2dEditorUtility.GetOrCreateIndex();

            foreach (var scIndex in index.GetSpriteCollectionIndex())
            {
                if (scIndex.spriteCollectionGUID == guid ||
                    scIndex.spriteCollectionDataGUID == guid)
                {
                    string realDataPath           = AssetDatabase.GUIDToAssetPath(scIndex.spriteCollectionDataGUID);
                    tk2dSpriteCollectionData data = AssetDatabase.LoadAssetAtPath(realDataPath, typeof(tk2dSpriteCollectionData)) as tk2dSpriteCollectionData;

                    if (data.allowMultipleAtlases)
                    {
                        Debug.Log("Atlas spanning not allowed");
                    }
                    else
                    {
                        tileMap.spriteCollection = data;
                        data.InitMaterialIds();
                        LoadTileMapData();

                        EditorUtility.SetDirty(tileMap);

                        if (Ready)
                        {
                            Init(tileMap.data);
                            tileMap.BeginEditMode();
                        }
                        break;
                    }
                }
            }
        }

        // If not set up, don't bother drawing anything else
        if (!Ready)
        {
            return;
        }

        tileMap.renderData = EditorGUILayout.ObjectField("Render Data", tileMap.renderData, typeof(GameObject), false) as GameObject;
        GUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel(" ");
        if (GUILayout.Button("Make Unique"))
        {
            tk2dRuntime.TileMap.BuilderUtil.CleanRenderData(tileMap);
            tileMap.renderData = null;
        }
        GUILayout.EndHorizontal();

        // tile map size
        editorData.showDimensions = EditorGUILayout.Foldout(editorData.showDimensions, "Dimensions");
        if (editorData.showDimensions)
        {
            EditorGUI.indentLevel++;

            width          = Mathf.Clamp(EditorGUILayout.IntField("Width", width), 1, 512);
            height         = Mathf.Clamp(EditorGUILayout.IntField("Height", height), 1, 512);
            partitionSizeX = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeX", partitionSizeX), 4, 32);
            partitionSizeY = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeY", partitionSizeY), 4, 32);

            // Create a default tilemap with given dimensions
            if (!tileMap.AreSpritesInitialized())
            {
                tk2dRuntime.TileMap.BuilderUtil.InitDataStore(tileMap);
                tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, tileMap.partitionSizeX, tileMap.partitionSizeY);
            }

            if (width != tileMap.width || height != tileMap.height || partitionSizeX != tileMap.partitionSizeX || partitionSizeY != tileMap.partitionSizeY)
            {
                if ((width < tileMap.width || height < tileMap.height))
                {
                    tk2dGuiUtility.InfoBox("The new size of the tile map is smaller than the current size." +
                                           "Some clipping will occur.", tk2dGuiUtility.WarningLevel.Warning);
                }

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Apply", EditorStyles.miniButton))
                {
                    tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, partitionSizeX, partitionSizeY);
                }
                GUILayout.EndHorizontal();
            }

            EditorGUI.indentLevel--;
        }

        editorData.showLayers = EditorGUILayout.Foldout(editorData.showLayers, "Layers");
        if (editorData.showLayers)
        {
            EditorGUI.indentLevel++;

            DrawLayersPanel(true);

            EditorGUI.indentLevel--;
        }

        // tilemap info
        editorData.showInfo = EditorGUILayout.Foldout(editorData.showInfo, "Info");
        if (editorData.showInfo)
        {
            EditorGUI.indentLevel++;

            int numActiveChunks = 0;
            if (tileMap.Layers != null)
            {
                foreach (var layer in tileMap.Layers)
                {
                    numActiveChunks += layer.NumActiveChunks;
                }
            }
            EditorGUILayout.LabelField("Active chunks", numActiveChunks.ToString());
            int partitionMemSize = partitionSizeX * partitionSizeY * 4;
            EditorGUILayout.LabelField("Memory", ((numActiveChunks * partitionMemSize) / 1024).ToString() + "kB");

            int numActiveColorChunks = 0;
            if (tileMap.ColorChannel != null)
            {
                numActiveColorChunks += tileMap.ColorChannel.NumActiveChunks;
            }
            EditorGUILayout.LabelField("Active color chunks", numActiveColorChunks.ToString());
            int colorMemSize = (partitionSizeX + 1) * (partitionSizeY + 1) * 4;
            EditorGUILayout.LabelField("Memory", ((numActiveColorChunks * colorMemSize) / 1024).ToString() + "kB");

            EditorGUI.indentLevel--;
        }

        // tile properties
        editorData.showTileProperties = EditorGUILayout.Foldout(editorData.showTileProperties, "Tile Properties");
        if (editorData.showTileProperties)
        {
            EditorGUI.indentLevel++;

            // sort method
            tk2dGuiUtility.BeginChangeCheck();
            tileMap.data.sortMethod = (tk2dTileMapData.SortMethod)EditorGUILayout.EnumPopup("Sort Method", tileMap.data.sortMethod);
            if (tk2dGuiUtility.EndChangeCheck())
            {
                tileMap.BeginEditMode();
            }


            // reset sizes
            GUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Reset sizes");
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Reset", EditorStyles.miniButtonRight))
            {
                Init(tileMap.data);
                Build(true);
            }
            GUILayout.EndHorizontal();

            // convert these to pixel units
            Vector3 texelSize        = SpriteCollection.spriteDefinitions[0].texelSize;
            Vector3 tileOriginPixels = new Vector3(tileMap.data.tileOrigin.x / texelSize.x, tileMap.data.tileOrigin.y / texelSize.y, tileMap.data.tileOrigin.z);
            Vector3 tileSizePixels   = new Vector3(tileMap.data.tileSize.x / texelSize.x, tileMap.data.tileSize.y / texelSize.y, tileMap.data.tileSize.z);

            Vector3 newTileOriginPixels = EditorGUILayout.Vector3Field("Cursor Origin", tileOriginPixels);
            Vector3 newTileSizePixels   = EditorGUILayout.Vector3Field("Tile Size", tileSizePixels);

            if (newTileOriginPixels != tileOriginPixels ||
                newTileSizePixels != tileSizePixels)
            {
                tileMap.data.tileOrigin = new Vector3(newTileOriginPixels.x * texelSize.x, newTileOriginPixels.y * texelSize.y, newTileOriginPixels.z);
                tileMap.data.tileSize   = new Vector3(newTileSizePixels.x * texelSize.x, newTileSizePixels.y * texelSize.y, newTileSizePixels.z);
                Build(true);
            }
            EditorGUI.indentLevel--;
        }

        editorData.showPaletteProperties = EditorGUILayout.Foldout(editorData.showPaletteProperties, "Palette Properties");
        if (editorData.showPaletteProperties)
        {
            EditorGUI.indentLevel++;
            int newTilesPerRow = Mathf.Clamp(EditorGUILayout.IntField("Tiles Per Row", editorData.paletteTilesPerRow),
                                             1, SpriteCollection.Count);
            if (newTilesPerRow != editorData.paletteTilesPerRow)
            {
                guiBrushBuilder.Reset();

                editorData.paletteTilesPerRow = newTilesPerRow;
                editorData.CreateDefaultPalette(tileMap.spriteCollection, editorData.paletteBrush, editorData.paletteTilesPerRow);
            }

            GUILayout.BeginHorizontal();
            editorData.brushDisplayScale = EditorGUILayout.FloatField("Display Scale", editorData.brushDisplayScale);
            editorData.brushDisplayScale = Mathf.Clamp(editorData.brushDisplayScale, 1.0f / 16.0f, 4.0f);
            if (GUILayout.Button("Reset", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false)))
            {
                editorData.brushDisplayScale = 1.0f;
                Repaint();
            }
            GUILayout.EndHorizontal();

            EditorGUILayout.PrefixLabel("Preview");
            brushRenderer.DrawBrush(tileMap, editorData.paletteBrush, editorData.brushDisplayScale, true, editorData.paletteTilesPerRow);
            EditorGUI.indentLevel--;
        }

//		editorData.showAdvancedProperties = EditorGUILayout.Foldout(editorData.showAdvancedProperties, "Advanced");
//		if (editorData.showAdvancedProperties)
//		{
//		}
    }
	void LoadTileMapData()
	{
		buildKey = tileMap.buildKey;
		
		string editorDataPath = AssetDatabase.GUIDToAssetPath(tileMap.editorDataGUID);
		editorData = AssetDatabase.LoadAssetAtPath(editorDataPath, typeof(tk2dTileMapEditorData)) as tk2dTileMapEditorData;
		
		width = tileMap.width;
		height = tileMap.height;
		partitionSizeX = tileMap.partitionSizeX;
		partitionSizeY = tileMap.partitionSizeY;
		
		if (tileMap.data && editorData)
		{
			// Rebuild the palette
			editorData.CreateDefaultPalette(tileMap.SpriteCollectionInst, editorData.paletteBrush, editorData.paletteTilesPerRow);
		}
		
		// Rebuild the render utility
		if (sceneGUI != null)
		{
			sceneGUI.Destroy();
		}
		sceneGUI = new tk2dTileMapSceneGUI(this, tileMap, editorData);
		
		// Rebuild the brush renderer
		brushRenderer = null;
	}
Example #5
0
    void DrawSettingsPanel()
    {
        // Tilemap data
        tk2dTileMapData newData = (tk2dTileMapData)EditorGUILayout.ObjectField("Tile Map Data", tileMap.data, typeof(tk2dTileMapData), false);

        if (newData != tileMap.data)
        {
            tileMap.data = newData;
            LoadTileMapData();
        }
        if (tileMap.data == null)
        {
            if (tk2dGuiUtility.InfoBoxWithButtons(
                    "TileMap needs an data object to proceed. " +
                    "Please create one or drag an existing data object into the inspector slot.\n",
                    tk2dGuiUtility.WarningLevel.Info,
                    "Create") != -1)
            {
                string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Data", "tileMapData", "asset", "");
                if (assetPath.Length > 0)
                {
                    tk2dTileMapData tileMapData = ScriptableObject.CreateInstance <tk2dTileMapData>();
                    AssetDatabase.CreateAsset(tileMapData, assetPath);
                    tileMap.data = tileMapData;
                    EditorUtility.SetDirty(tileMap);

                    Init(tileMapData);
                    LoadTileMapData();
                }
            }
        }

        // Editor data
        tk2dTileMapEditorData newEditorData = (tk2dTileMapEditorData)EditorGUILayout.ObjectField("Editor Data", editorData, typeof(tk2dTileMapEditorData), false);

        if (newEditorData != editorData)
        {
            string assetPath = AssetDatabase.GetAssetPath(newEditorData);
            if (assetPath.Length > 0)
            {
                tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
                EditorUtility.SetDirty(tileMap);
                LoadTileMapData();
            }
        }
        if (editorData == null)
        {
            if (tk2dGuiUtility.InfoBoxWithButtons(
                    "TileMap needs an editor data object to proceed. " +
                    "Please create one or drag an existing data object into the inspector slot.\n",
                    tk2dGuiUtility.WarningLevel.Info,
                    "Create") != -1)
            {
                string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Editor Data", "tileMapEditorData", "asset", "");
                if (assetPath.Length > 0)
                {
                    tk2dTileMapEditorData tileMapEditorData = ScriptableObject.CreateInstance <tk2dTileMapEditorData>();
                    AssetDatabase.CreateAsset(tileMapEditorData, assetPath);
                    tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
                    EditorUtility.SetDirty(tileMap);
                    LoadTileMapData();
                }
            }
        }

        // Sprite collection
        GUILayout.BeginHorizontal();
        Object selectedSpriteCollectionObject = EditorGUILayout.ObjectField("Sprite Collection", tileMap.Editor__SpriteCollection, typeof(Object), false) as Object;

        if (tileMap.Editor__SpriteCollection != null && GUILayout.Button(">", EditorStyles.miniButton, GUILayout.Width(19)))
        {
            tk2dSpriteCollectionEditorPopup v = EditorWindow.GetWindow(typeof(tk2dSpriteCollectionEditorPopup), false, "Sprite Collection Editor") as tk2dSpriteCollectionEditorPopup;
            string assetPath        = AssetDatabase.GUIDToAssetPath(tileMap.Editor__SpriteCollection.spriteCollectionGUID);
            var    spriteCollection = AssetDatabase.LoadAssetAtPath(assetPath, typeof(tk2dSpriteCollection)) as tk2dSpriteCollection;
            v.SetGeneratorAndSelectedSprite(spriteCollection, 0);
        }
        GUILayout.EndHorizontal();
        if (selectedSpriteCollectionObject != tileMap.Editor__SpriteCollection)
        {
            string    assetPath = AssetDatabase.GetAssetPath(selectedSpriteCollectionObject);
            string    guid      = AssetDatabase.AssetPathToGUID(assetPath);
            tk2dIndex index     = tk2dEditorUtility.GetOrCreateIndex();

            foreach (var scIndex in index.GetSpriteCollectionIndex())
            {
                if (scIndex.spriteCollectionGUID == guid ||
                    scIndex.spriteCollectionDataGUID == guid)
                {
                    string realDataPath           = AssetDatabase.GUIDToAssetPath(scIndex.spriteCollectionDataGUID);
                    tk2dSpriteCollectionData data = AssetDatabase.LoadAssetAtPath(realDataPath, typeof(tk2dSpriteCollectionData)) as tk2dSpriteCollectionData;

                    if (data.allowMultipleAtlases)
                    {
                        Debug.Log("Atlas spanning not allowed");
                    }
                    else
                    {
                        tileMap.Editor__SpriteCollection = data;
                        data.InitMaterialIds();
                        LoadTileMapData();

                        EditorUtility.SetDirty(tileMap);

                        if (Ready)
                        {
                            Init(tileMap.data);
                            tileMap.BeginEditMode();
                        }
                        break;
                    }
                }
            }
        }

        // If not set up, don't bother drawing anything else
        if (!Ready)
        {
            return;
        }

        // this is intentionally read only
        EditorGUILayout.ObjectField("Render Data", tileMap.renderData, typeof(GameObject), false);
        GUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel(" ");
        if (GUILayout.Button("Make Unique"))
        {
            tk2dRuntime.TileMap.BuilderUtil.CleanRenderData(tileMap);
            tileMap.renderData = null;
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        EditorGUILayout.PrefixLabel(" ");
        if (!tileMap.serializeRenderData && GUILayout.Button("Make Serializable"))
        {
            if (tileMap.serializeRenderData == true)
            {
                tk2dRuntime.TileMap.BuilderUtil.CleanRenderData(tileMap);                 // clear everything (i.e. all serialized meshes will be back in "serializedMeshes")
                tileMap.serializeRenderData = false;
            }

            string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Render Data", "Tilemap Render Data 1", "asset",
                                                                    "Select an asset file to save the render data to.\n" +
                                                                    "It is best to save this in an empty directory, as the tilemap may contain more than one mesh");
            if (assetPath.Length > 0)
            {
                tileMap.serializeRenderData = true;
                tileMap.serializedMeshPath  = assetPath;
                if (tileMap.renderData)
                {
                    List <Mesh>    existingMeshes = new List <Mesh>();
                    MeshFilter[]   meshFilters    = tileMap.renderData.GetComponentsInChildren <MeshFilter>();
                    MeshCollider[] meshColliders  = tileMap.renderData.GetComponentsInChildren <MeshCollider>();
                    foreach (var j in meshFilters)
                    {
                        existingMeshes.Add(j.sharedMesh);
                    }
                    foreach (var j in meshColliders)
                    {
                        existingMeshes.Add(j.sharedMesh);
                    }

                    existingMeshes.RemoveAll(a => a == null);
                    foreach (var j in existingMeshes)
                    {
                        j.RecalculateNormals();                         // normals are likely to be missing here
                        AssetDatabase.CreateAsset(j, AssetDatabase.GenerateUniqueAssetPath(tileMap.serializedMeshPath));
                    }
                }
            }
        }
        if (tileMap.serializeRenderData)
        {
            if (GUILayout.Toggle(true, "Serialized", "button") == false)
            {
                GameObject.DestroyImmediate(tileMap.renderData);
                tileMap.renderData          = null;
                tileMap.serializeRenderData = false;

                Build(true);
            }
        }
        GUILayout.EndHorizontal();

        // tile map size

        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Dimensions, "Dimensions"))
        {
            EditorGUI.indentLevel++;

            width          = Mathf.Clamp(EditorGUILayout.IntField("Width", width), 1, tk2dEditor.TileMap.TileMapUtility.MaxWidth);
            height         = Mathf.Clamp(EditorGUILayout.IntField("Height", height), 1, tk2dEditor.TileMap.TileMapUtility.MaxHeight);
            partitionSizeX = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeX", partitionSizeX), 4, 32);
            partitionSizeY = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeY", partitionSizeY), 4, 32);

            // Create a default tilemap with given dimensions
            if (!tileMap.AreSpritesInitialized())
            {
                tk2dRuntime.TileMap.BuilderUtil.InitDataStore(tileMap);
                tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, tileMap.partitionSizeX, tileMap.partitionSizeY);
            }

            if (width != tileMap.width || height != tileMap.height || partitionSizeX != tileMap.partitionSizeX || partitionSizeY != tileMap.partitionSizeY)
            {
                if ((width < tileMap.width || height < tileMap.height))
                {
                    tk2dGuiUtility.InfoBox("The new size of the tile map is smaller than the current size." +
                                           "Some clipping will occur.", tk2dGuiUtility.WarningLevel.Warning);
                }

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Apply", EditorStyles.miniButton))
                {
                    tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, partitionSizeX, partitionSizeY);
                }
                GUILayout.EndHorizontal();
            }

            EditorGUI.indentLevel--;
        }

        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Layers, "Layers"))
        {
            EditorGUI.indentLevel++;

            DrawLayersPanel(true);

            EditorGUI.indentLevel--;
        }

        // tilemap info
        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Info, "Info"))
        {
            EditorGUI.indentLevel++;

            int numActiveChunks = 0;
            if (tileMap.Layers != null)
            {
                foreach (var layer in tileMap.Layers)
                {
                    numActiveChunks += layer.NumActiveChunks;
                }
            }
            EditorGUILayout.LabelField("Active chunks", numActiveChunks.ToString());
            int partitionMemSize = partitionSizeX * partitionSizeY * 4;
            EditorGUILayout.LabelField("Memory", ((numActiveChunks * partitionMemSize) / 1024).ToString() + "kB");

            int numActiveColorChunks = 0;
            if (tileMap.ColorChannel != null)
            {
                numActiveColorChunks += tileMap.ColorChannel.NumActiveChunks;
            }
            EditorGUILayout.LabelField("Active color chunks", numActiveColorChunks.ToString());
            int colorMemSize = (partitionSizeX + 1) * (partitionSizeY + 1) * 4;
            EditorGUILayout.LabelField("Memory", ((numActiveColorChunks * colorMemSize) / 1024).ToString() + "kB");

            EditorGUI.indentLevel--;
        }

        // tile properties
        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.TileProperties, "Tile Properties"))
        {
            EditorGUI.indentLevel++;

            // sort method
            tk2dGuiUtility.BeginChangeCheck();
            tileMap.data.tileType   = (tk2dTileMapData.TileType)EditorGUILayout.EnumPopup("Tile Type", tileMap.data.tileType);
            tileMap.data.sortMethod = (tk2dTileMapData.SortMethod)EditorGUILayout.EnumPopup("Sort Method", tileMap.data.sortMethod);
            if (tk2dGuiUtility.EndChangeCheck())
            {
                tileMap.BeginEditMode();
            }


            // reset sizes
            GUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Reset sizes");
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Reset", EditorStyles.miniButtonRight))
            {
                Init(tileMap.data);
                Build(true);
            }
            GUILayout.EndHorizontal();

            // convert these to pixel units
            Vector3 texelSize        = SpriteCollection.spriteDefinitions[0].texelSize;
            Vector3 tileOriginPixels = new Vector3(tileMap.data.tileOrigin.x / texelSize.x, tileMap.data.tileOrigin.y / texelSize.y, tileMap.data.tileOrigin.z);
            Vector3 tileSizePixels   = new Vector3(tileMap.data.tileSize.x / texelSize.x, tileMap.data.tileSize.y / texelSize.y, tileMap.data.tileSize.z);

            Vector3 newTileOriginPixels = EditorGUILayout.Vector3Field("Origin", tileOriginPixels);
            Vector3 newTileSizePixels   = EditorGUILayout.Vector3Field("Size", tileSizePixels);

            if (newTileOriginPixels != tileOriginPixels ||
                newTileSizePixels != tileSizePixels)
            {
                tileMap.data.tileOrigin = new Vector3(newTileOriginPixels.x * texelSize.x, newTileOriginPixels.y * texelSize.y, newTileOriginPixels.z);
                tileMap.data.tileSize   = new Vector3(newTileSizePixels.x * texelSize.x, newTileSizePixels.y * texelSize.y, newTileSizePixels.z);
                Build(true);
            }
            EditorGUI.indentLevel--;
        }

        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.PaletteProperties, "Palette Properties"))
        {
            EditorGUI.indentLevel++;
            int newTilesPerRow = Mathf.Clamp(EditorGUILayout.IntField("Tiles Per Row", editorData.paletteTilesPerRow),
                                             1, SpriteCollection.Count);
            if (newTilesPerRow != editorData.paletteTilesPerRow)
            {
                guiBrushBuilder.Reset();

                editorData.paletteTilesPerRow = newTilesPerRow;
                editorData.CreateDefaultPalette(tileMap.SpriteCollectionInst, editorData.paletteBrush, editorData.paletteTilesPerRow);
            }

            GUILayout.BeginHorizontal();
            editorData.brushDisplayScale = EditorGUILayout.FloatField("Display Scale", editorData.brushDisplayScale);
            editorData.brushDisplayScale = Mathf.Clamp(editorData.brushDisplayScale, 1.0f / 16.0f, 4.0f);
            if (GUILayout.Button("Reset", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false)))
            {
                editorData.brushDisplayScale = 1.0f;
                Repaint();
            }
            GUILayout.EndHorizontal();

            EditorGUILayout.PrefixLabel("Preview");
            brushRenderer.DrawBrush(tileMap, editorData.paletteBrush, editorData.brushDisplayScale, true, editorData.paletteTilesPerRow);
            EditorGUI.indentLevel--;
        }

        if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Import, "Import"))
        {
            EditorGUI.indentLevel++;

            if (GUILayout.Button("Import TMX"))
            {
                if (tk2dEditor.TileMap.Importer.Import(tileMap, tk2dEditor.TileMap.Importer.Format.TMX))
                {
                    Build(true);
                    width          = tileMap.width;
                    height         = tileMap.height;
                    partitionSizeX = tileMap.partitionSizeX;
                    partitionSizeY = tileMap.partitionSizeY;
                }
            }

            EditorGUI.indentLevel--;
        }
    }
	void DrawSettingsPanel()
	{
		// Tilemap data
		tk2dTileMapData newData = (tk2dTileMapData)EditorGUILayout.ObjectField("Tile Map Data", tileMap.data, typeof(tk2dTileMapData), false);
		if (newData != tileMap.data)
		{
			tileMap.data = newData;
			LoadTileMapData();
		}
		if (tileMap.data == null)
		{
			if (tk2dGuiUtility.InfoBoxWithButtons(
				"TileMap needs an data object to proceed. " +
				"Please create one or drag an existing data object into the inspector slot.\n",
				tk2dGuiUtility.WarningLevel.Info, 
				"Create") != -1)
			{
				string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Data", "tileMapData", "asset", "");
				if (assetPath.Length > 0)
				{
					tk2dTileMapData tileMapData = ScriptableObject.CreateInstance<tk2dTileMapData>();
					AssetDatabase.CreateAsset(tileMapData, assetPath);
					tileMap.data = tileMapData;
					EditorUtility.SetDirty(tileMap);
					
					Init(tileMapData);
					LoadTileMapData();
				}
			}
		}
		
		// Editor data
		tk2dTileMapEditorData newEditorData = (tk2dTileMapEditorData)EditorGUILayout.ObjectField("Editor Data", editorData, typeof(tk2dTileMapEditorData), false);
		if (newEditorData != editorData)
		{
			string assetPath = AssetDatabase.GetAssetPath(newEditorData);
			if (assetPath.Length > 0)
			{
				tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
				EditorUtility.SetDirty(tileMap);
				LoadTileMapData();
			}
		}
		if (editorData == null)
		{
			if (tk2dGuiUtility.InfoBoxWithButtons(
				"TileMap needs an editor data object to proceed. " +
				"Please create one or drag an existing data object into the inspector slot.\n",
				tk2dGuiUtility.WarningLevel.Info, 
				"Create") != -1)
			{
				string assetPath = EditorUtility.SaveFilePanelInProject("Save Tile Map Editor Data", "tileMapEditorData", "asset", "");
				if (assetPath.Length > 0)
				{
					tk2dTileMapEditorData tileMapEditorData = ScriptableObject.CreateInstance<tk2dTileMapEditorData>();
					AssetDatabase.CreateAsset(tileMapEditorData, assetPath);
					tileMap.editorDataGUID = AssetDatabase.AssetPathToGUID(assetPath);
					EditorUtility.SetDirty(tileMap);
					LoadTileMapData();
				}
			}
		}
		
		// Sprite collection
		GUILayout.BeginHorizontal();
		Object selectedSpriteCollectionObject = EditorGUILayout.ObjectField("Sprite Collection", tileMap.Editor__SpriteCollection, typeof(Object), false) as Object;
		if (tileMap.Editor__SpriteCollection != null && GUILayout.Button(">", EditorStyles.miniButton, GUILayout.Width(19)))
		{
			tk2dSpriteCollectionEditorPopup v = EditorWindow.GetWindow( typeof(tk2dSpriteCollectionEditorPopup), false, "Sprite Collection Editor" ) as tk2dSpriteCollectionEditorPopup;
			string assetPath = AssetDatabase.GUIDToAssetPath(tileMap.Editor__SpriteCollection.spriteCollectionGUID);
			var spriteCollection = AssetDatabase.LoadAssetAtPath(assetPath, typeof(tk2dSpriteCollection)) as tk2dSpriteCollection;
			v.SetGeneratorAndSelectedSprite(spriteCollection, 0);
		}
		GUILayout.EndHorizontal();
		if (selectedSpriteCollectionObject != tileMap.Editor__SpriteCollection)
		{
			string assetPath = AssetDatabase.GetAssetPath(selectedSpriteCollectionObject);
			string guid = AssetDatabase.AssetPathToGUID(assetPath);
			tk2dIndex index = tk2dEditorUtility.GetOrCreateIndex();
			
			foreach (var scIndex in index.GetSpriteCollectionIndex())
			{
				if (scIndex.spriteCollectionGUID == guid ||
					scIndex.spriteCollectionDataGUID == guid)
				{
					string realDataPath = AssetDatabase.GUIDToAssetPath(scIndex.spriteCollectionDataGUID);
					tk2dSpriteCollectionData data = AssetDatabase.LoadAssetAtPath(realDataPath, typeof(tk2dSpriteCollectionData)) as tk2dSpriteCollectionData;
					
					if (data.allowMultipleAtlases)
					{
						Debug.Log("Atlas spanning not allowed");
					}
					else
					{
						tileMap.Editor__SpriteCollection = data;
						data.InitMaterialIds();
						LoadTileMapData();
						
						EditorUtility.SetDirty(tileMap);
						
						if (Ready)
						{
							Init(tileMap.data);
							tileMap.BeginEditMode();
						}
						break;						
					}
				}
			}
		}
		
		// If not set up, don't bother drawing anything else
		if (!Ready)
			return;
		
		// this is intentionally read only
		EditorGUILayout.ObjectField("Render Data", tileMap.renderData, typeof(GameObject), false);
		GUILayout.BeginHorizontal();
		EditorGUILayout.PrefixLabel(" ");
		if (GUILayout.Button("Make Unique")) {
			tk2dEditor.TileMap.TileMapUtility.MakeUnique(tileMap);
		}
		GUILayout.EndHorizontal();
		
		// tile map size
		
		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Dimensions, "Dimensions"))
		{
			EditorGUI.indentLevel++;
			
			width = Mathf.Clamp(EditorGUILayout.IntField("Width", width), 1, tk2dEditor.TileMap.TileMapUtility.MaxWidth);
			height = Mathf.Clamp(EditorGUILayout.IntField("Height", height), 1, tk2dEditor.TileMap.TileMapUtility.MaxHeight);
			partitionSizeX = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeX", partitionSizeX), 4, 32);
			partitionSizeY = Mathf.Clamp(EditorGUILayout.IntField("PartitionSizeY", partitionSizeY), 4, 32);
			
			// Create a default tilemap with given dimensions
			if (!tileMap.AreSpritesInitialized())
			{
				tk2dRuntime.TileMap.BuilderUtil.InitDataStore(tileMap);
				tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, tileMap.partitionSizeX, tileMap.partitionSizeY);	
			}
			
			if (width != tileMap.width || height != tileMap.height || partitionSizeX != tileMap.partitionSizeX || partitionSizeY != tileMap.partitionSizeY)
			{
				if ((width < tileMap.width || height < tileMap.height))
				{
					tk2dGuiUtility.InfoBox("The new size of the tile map is smaller than the current size." +
						"Some clipping will occur.", tk2dGuiUtility.WarningLevel.Warning);
				}
				
				GUILayout.BeginHorizontal();
				GUILayout.FlexibleSpace();
				if (GUILayout.Button("Apply", EditorStyles.miniButton))
				{
					tk2dEditor.TileMap.TileMapUtility.ResizeTileMap(tileMap, width, height, partitionSizeX, partitionSizeY);
				}
				GUILayout.EndHorizontal();
			}

			EditorGUI.indentLevel--;
		}
		
		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Layers, "Layers"))
		{
			EditorGUI.indentLevel++;
			
			DrawLayersPanel(true);
			
			EditorGUI.indentLevel--;
		}
		
		// tilemap info
		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Info, "Info"))
		{
			EditorGUI.indentLevel++;
			
			int numActiveChunks = 0;
			if (tileMap.Layers != null)
			{
				foreach (var layer in tileMap.Layers)
					numActiveChunks += layer.NumActiveChunks;
			}
			EditorGUILayout.LabelField("Active chunks", numActiveChunks.ToString());
			int partitionMemSize = partitionSizeX * partitionSizeY * 4;
			EditorGUILayout.LabelField("Memory", ((numActiveChunks * partitionMemSize) / 1024).ToString() + "kB" );
			
			int numActiveColorChunks = 0;
			if (tileMap.ColorChannel != null)
				numActiveColorChunks += tileMap.ColorChannel.NumActiveChunks;
			EditorGUILayout.LabelField("Active color chunks", numActiveColorChunks.ToString());
			int colorMemSize = (partitionSizeX + 1) * (partitionSizeY + 1) * 4;
			EditorGUILayout.LabelField("Memory", ((numActiveColorChunks * colorMemSize) / 1024).ToString() + "kB" );
			
			EditorGUI.indentLevel--;
		}
		
		// tile properties
		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.TileProperties, "Tile Properties"))
		{
			EditorGUI.indentLevel++;

			// sort method
			tk2dGuiUtility.BeginChangeCheck();
			tileMap.data.tileType = (tk2dTileMapData.TileType)EditorGUILayout.EnumPopup("Tile Type", tileMap.data.tileType);
			tileMap.data.sortMethod = (tk2dTileMapData.SortMethod)EditorGUILayout.EnumPopup("Sort Method", tileMap.data.sortMethod);
			if (tk2dGuiUtility.EndChangeCheck())
			{
				tileMap.BeginEditMode();
			}
			

			// reset sizes			
			GUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel("Reset sizes");
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Reset", EditorStyles.miniButtonRight))
			{
				Init(tileMap.data);
				Build(true);
			}
			GUILayout.EndHorizontal();

			// convert these to pixel units
			Vector3 texelSize = SpriteCollection.spriteDefinitions[0].texelSize;
			Vector3 tileOriginPixels = new Vector3(tileMap.data.tileOrigin.x / texelSize.x, tileMap.data.tileOrigin.y / texelSize.y, tileMap.data.tileOrigin.z);
			Vector3 tileSizePixels = new Vector3(tileMap.data.tileSize.x / texelSize.x, tileMap.data.tileSize.y / texelSize.y, tileMap.data.tileSize.z);
			
			Vector3 newTileOriginPixels = EditorGUILayout.Vector3Field("Origin", tileOriginPixels);
			Vector3 newTileSizePixels = EditorGUILayout.Vector3Field("Size", tileSizePixels);
			
			if (newTileOriginPixels != tileOriginPixels ||
				newTileSizePixels != tileSizePixels)
			{
				tileMap.data.tileOrigin = new Vector3(newTileOriginPixels.x * texelSize.x, newTileOriginPixels.y * texelSize.y, newTileOriginPixels.z);
				tileMap.data.tileSize = new Vector3(newTileSizePixels.x * texelSize.x, newTileSizePixels.y * texelSize.y, newTileSizePixels.z);
				Build(true);
			}

			// preview tile origin and size setting
			Vector2 spritePixelOrigin = Vector2.zero;
			Vector2 spritePixelSize = Vector2.one;
			tk2dSpriteDefinition[] spriteDefs = tileMap.SpriteCollectionInst.spriteDefinitions;
			tk2dSpriteDefinition spriteDef = (tilePropertiesPreviewIdx < spriteDefs.Length) ? spriteDefs[tilePropertiesPreviewIdx] : null;
			if (!spriteDef.Valid) spriteDef = null;
			if (spriteDef != null) {
				spritePixelOrigin = new Vector2(spriteDef.untrimmedBoundsData[0].x / spriteDef.texelSize.x, spriteDef.untrimmedBoundsData[0].y / spriteDef.texelSize.y);
				spritePixelSize = new Vector2(spriteDef.untrimmedBoundsData[1].x / spriteDef.texelSize.x, spriteDef.untrimmedBoundsData[1].y / spriteDef.texelSize.y);
			}
			float zoomFactor = (Screen.width - 32.0f) / (spritePixelSize.x * 2.0f);
			EditorGUILayout.BeginScrollView(Vector2.zero, GUILayout.Height(spritePixelSize.y * 2.0f * zoomFactor + 32.0f));
			Rect innerRect = new Rect(0, 0, spritePixelSize.x * 2.0f * zoomFactor, spritePixelSize.y * 2.0f * zoomFactor);
			tk2dGrid.Draw(innerRect);
			if (spriteDef != null) {
				// Preview tiles
				tk2dSpriteThumbnailCache.DrawSpriteTexture(new Rect(spritePixelSize.x * 0.5f * zoomFactor, spritePixelSize.y * 0.5f * zoomFactor, spritePixelSize.x * zoomFactor, spritePixelSize.y * zoomFactor), spriteDef);
				// Preview cursor
				Vector2 cursorOffset = (spritePixelSize * 0.5f - spritePixelOrigin) * zoomFactor;
				Vector2 cursorSize = new Vector2(tileSizePixels.x * zoomFactor, tileSizePixels.y * zoomFactor);
				cursorOffset.x += tileOriginPixels.x * zoomFactor;
				cursorOffset.y += tileOriginPixels.y * zoomFactor;
				cursorOffset.x += spritePixelSize.x * 0.5f * zoomFactor;
				cursorOffset.y += spritePixelSize.y * 0.5f * zoomFactor;
				float top = spritePixelSize.y * 2.0f * zoomFactor;
				Vector3[] cursorVerts = new Vector3[] {
					new Vector3(cursorOffset.x, top - cursorOffset.y, 0),
					new Vector3(cursorOffset.x + cursorSize.x, top - cursorOffset.y, 0),
					new Vector3(cursorOffset.x + cursorSize.x, top - (cursorOffset.y + cursorSize.y), 0),
					new Vector3(cursorOffset.x, top - (cursorOffset.y + cursorSize.y), 0)
				};
				Handles.DrawSolidRectangleWithOutline(cursorVerts, new Color(1.0f, 1.0f, 1.0f, 0.2f), Color.white);
			}
			if (GUILayout.Button(new GUIContent("", "Click - preview using different tile"), "label", GUILayout.Width(innerRect.width), GUILayout.Height(innerRect.height))) {
				int n = spriteDefs.Length;
				for (int i = 0; i < n; ++i) {
					if (++tilePropertiesPreviewIdx >= n)
						tilePropertiesPreviewIdx = 0;
					if (spriteDefs[tilePropertiesPreviewIdx].Valid)
						break;
				}
			}
			EditorGUILayout.EndScrollView();

			EditorGUI.indentLevel--;
		}
		
		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.PaletteProperties, "Palette Properties"))
		{
			EditorGUI.indentLevel++;
			int newTilesPerRow = Mathf.Clamp(EditorGUILayout.IntField("Tiles Per Row", editorData.paletteTilesPerRow),
											1, SpriteCollection.Count);
			if (newTilesPerRow != editorData.paletteTilesPerRow)
			{
				guiBrushBuilder.Reset();
				
				editorData.paletteTilesPerRow = newTilesPerRow;
				editorData.CreateDefaultPalette(tileMap.SpriteCollectionInst, editorData.paletteBrush, editorData.paletteTilesPerRow);
			}
			
			GUILayout.BeginHorizontal();
			editorData.brushDisplayScale = EditorGUILayout.FloatField("Display Scale", editorData.brushDisplayScale);
			editorData.brushDisplayScale = Mathf.Clamp(editorData.brushDisplayScale, 1.0f / 16.0f, 4.0f);
			if (GUILayout.Button("Reset", EditorStyles.miniButtonRight, GUILayout.ExpandWidth(false)))
			{
				editorData.brushDisplayScale = 1.0f;
				Repaint();
			}
			GUILayout.EndHorizontal();
			
			EditorGUILayout.PrefixLabel("Preview");
			Rect innerRect = brushRenderer.GetBrushViewRect(editorData.paletteBrush, editorData.paletteTilesPerRow);
			paletteSettingsScrollPos = EditorGUILayout.BeginScrollView(paletteSettingsScrollPos, GUILayout.MinHeight(innerRect.height * editorData.brushDisplayScale + 32.0f));
			innerRect.width *= editorData.brushDisplayScale;
			innerRect.height *= editorData.brushDisplayScale;
			tk2dGrid.Draw(innerRect);
			brushRenderer.DrawBrush(tileMap, editorData.paletteBrush, editorData.brushDisplayScale, true, editorData.paletteTilesPerRow);
			EditorGUILayout.EndScrollView();
			EditorGUI.indentLevel--;
		}

		if (Foldout(ref editorData.setupMode, tk2dTileMapEditorData.SetupMode.Import, "Import"))
		{
			EditorGUI.indentLevel++;
			
			if (GUILayout.Button("Import TMX"))
			{
				if (tk2dEditor.TileMap.Importer.Import(tileMap, tk2dEditor.TileMap.Importer.Format.TMX)) 
				{
					Build(true);	
					width = tileMap.width;
					height = tileMap.height;
					partitionSizeX = tileMap.partitionSizeX;
					partitionSizeY = tileMap.partitionSizeY;
				}
			}
			
			EditorGUI.indentLevel--;
		}
	}