2D Toolkit Forum
2D Toolkit => Support => Topic started by: Euthyphro on July 10, 2014, 06:23:44 am
-
I have about 40 tile maps and multiple layers, rather than modifying each one by hand and wishing I was a robot, I'm trying to write a script to do that. The problem is that this is leaving the old layers under the render data game object and creating the layers rather oddly. Obviously I'm doing this wrong, what is the best practice to add/remove tile map layers through code to ensure everything is taken care of?
Here is my code for what I have:
if(GUILayout.Button("Create Tile Map Layers"))
{
List<tk2dTileMapData> tileMapDataList = new List<tk2dTileMapData>();
tileMaps = FindObjectsOfType(typeof(tk2dTileMap)) as tk2dTileMap[];
Debug.LogError("Size: "+tileMaps.Count().ToString());
foreach (tk2dTileMap tileMap in tileMaps)
{
tileMap.data.tileMapLayers.Clear();
tileMap.BeginEditMode();
for(int i = 0; i < 5; i++)
{
tk2dRuntime.TileMap.LayerInfo newLayer = new tk2dRuntime.TileMap.LayerInfo();
newLayer.name = "Layer "+i.ToString();
newLayer.generateCollider = false;
newLayer.useColor = true;
newLayer.z = i;
newLayer.unityLayer = 20 + i;
newLayer.sortingOrder = i;
newLayer.hash = 0x70d32b98;
if(i == 1)
{
newLayer.generateCollider = true;
}
if(i == 0)
{
tileMap.data.tileMapLayers[i] = newLayer;
}
else tileMap.data.tileMapLayers.Add(newLayer);
Debug.LogError(tileMap.name+" i:"+i.ToString());
}
tileMap.EndEditMode();
}
}
-
If you wnat to delete a layer, look at tk2dTIleMapUtility.DeleteLayer. That deletes a layer correct - its what the editor code uses.
-
If you wnat to delete a layer, look at tk2dTIleMapUtility.DeleteLayer. That deletes a layer correct - its what the editor code uses.
Any chance on a quick little tutorial on looping through to create tile map layers properly? This is getting extremely messy having to modify methods and functions that are not public and either rewrite them or change the tk2d scripts.
The problem I'm having creating them is that they aren't all instantiating after having essentially copied and pasted the FindOrCreateLayer(tilemap, name) function. I guess there is more to it but that is my point, it's getting very messy because you can't just access tk2deditor from outside scripts without doing several other things.
-
int layerId = -1;
for (int i = 0; i < tm.data.Layers.Length; ++i) {
if (tm.data.Layers[i].name == "Blocker") {
layerId = i;
break;
}
}
tm.BeginEditMode();
if (layerId != -1) {
tk2dEditor.TileMap.TileMapUtility.DeleteLayer(tm, layerId);
}
int newLayerIndex = tk2dEditor.TileMap.TileMapUtility.FindOrCreateLayer(tm, "Hello");
tm.EndEditMode();
You dont need to modify or copy any of the functions. tk2dEditor IS accessible from editor scripts, and if you're doing that in the editor you should be using an editor script.
-
You dont need to modify or copy any of the functions. tk2dEditor IS accessible from editor scripts, and if you're doing that in the editor you should be using an editor script.
How might I do that? The beginning of my class looks like this, and as far as I'm aware, this would make it an editor script. With that said, not able to access tk2dEditor. "Using tk2dEditor" is no go and calling tk2dEditor from anywhere it doesn't show up within any methods or functions of this editor script.
*Edit* I think I got it, I put it in the same folder as tk2deditor and it seems to be working now.
#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using tk2dRuntime.TileMap;
[CustomEditor(typeof(TileDataScript))] //tile data script attached to GameManager GameObject.
public class TileDataEditor : Editor {
/***
functions and methods etc
*/
}
#endif
-
And editor script can be in any folder called "Editor". It doesn't have to be in the same dir. But otherwise, glad you've got that working.
-
Since having done this edit I seem to be having a problem with the TileMapData file. It works perfectly until I close the editor and open. When I reopen the editor, the tilemap render layers create a new gameobject for the layers.
Here is a screen grab of before and after followed by code based on your suggestions - which like I said, works wonderfully until closing/opening - in which case I then have to rebuild the layers. Likewise I cannot compile an exe without this same issue happening when opening the exe after.
Before close:
(http://i.imgur.com/1fmQ9Ct.png)
After close/reopen of Unity (this also happens when compiling the game into exe and running out of the editor)
(http://i.imgur.com/S4ZlVSX.png)
public tk2dTileMap[] tileMaps;
public void BuildLayers()
{
tileMaps = FindObjectsOfType(typeof(tk2dTileMap)) as tk2dTileMap[];
Debug.Log("Tile map count: "+tileMaps.Count().ToString());
int counterMaps = 0;
int counterLayers = 0;
foreach (tk2dTileMap tileMap in tileMaps)
{
//not entirely sure why this is here, it was in example given by unikronsoftware
int layerId = -1;
for (int i = 0; i < tileMap.data.Layers.Length; ++i) {
if (tileMap.data.Layers[i].name == "Blocker") {
layerId = i;
break;
}
}
tileMap.BeginEditMode();
//clear old layers out since we'll be recreating them. May not be necessary as we can just use "FindOrCrateLayer()" but kept in for now.
for(int i = 0; i <tileMap.data.Layers.Length; i++)
{
Debug.LogError("Deleting layer: "+tileMap.data.Layers[i].name);
tk2dEditor.TileMap.TileMapUtility.DeleteLayer(tileMap, i);
}
//set tilemap so that we are using the sorting layer sort method
tileMap.data.useSortingLayers = true;
for(int i = 0; i < 6; i++)
{
int newLayerIndex = tk2dEditor.TileMap.TileMapUtility.FindOrCreateLayer(tileMap, "Layer "+i.ToString());
// tileMap.data.Layers[].generateCollider = true;
//index from TileMapUtility is oddly not ordered based on the order it was created. Sometimes
// the new layer index returned is different. i.e. this is created from 0 to 5 but sometimes index returned is not sequential to the order created.
//instead we just give the layer the name "Layer +" index number.
tileMap.data.Layers[newLayerIndex].name = "Layer "+newLayerIndex.ToString();
tileMap.data.Layers[newLayerIndex].z = 1;
tileMap.data.Layers[newLayerIndex].unityLayer = 20+i;
int t = 5-i;
tileMap.data.Layers[newLayerIndex].sortingLayerName = "TileMapLayer"+t.ToString();
if(newLayerIndex != 0)
{
tileMap.data.Layers[newLayerIndex].generateCollider = false;
}
counterLayers++;
tileMap.Layers[newLayerIndex].Optimize();
}
counterMaps++;
Debug.Log("Completed maps: "+counterMaps.ToString()+" Completed layers: "+counterLayers.ToString());
tileMap.EndEditMode();
}
}
-
Where are you running that code from? It looks like its losing the references to the objects - you might need to call SetDirty on the tilemap / tilemap data objects....
-
That fixed it, thanks again!