void LoadTileMap() { RemoveColliders(); List <OTTile>allTiles = new List<OTTile>(); Dictionary<int , OTTile>lookupTile = new Dictionary<int, OTTile>(); if (tileMapXML == null) { if (tileSets == null) tileSets = new OTTileSet[] { }; return; } XmlDocument xd = new XmlDocument(); try { xd.LoadXml(tileMapXML.text); } catch(System.Exception) { Debug.LogError("TileMap XML - invalid XML!"); return; } if (xd.DocumentElement == null) { Debug.LogError("TileMap XML - invalid XML!"); return; } if (xd.DocumentElement.Name != "map") { Debug.LogError("TileMap XML - No Tiled Tilemap found!"); return; } mapSize = new Vector2(AtI(xd.DocumentElement, "width"), AtI(xd.DocumentElement, "height")); mapTileSize = new Vector2(AtI(xd.DocumentElement, "tilewidth"), AtI(xd.DocumentElement, "tileheight")); XmlNodeList xmlTileSets = xd.DocumentElement.SelectNodes("tileset"); if (xmlTileSets.Count == 0) { Debug.LogError("TileMap XML - No Tilesets found!"); return; } XmlNodeList xmlLayers = xd.DocumentElement.SelectNodes("layer"); if (xmlLayers.Count == 0) { Debug.LogError("TileMap XML - No Layers found!"); return; } if (tileSets == null) tileSets = new OTTileSet[] { }; tileSetLookup.Clear(); System.Array.Resize<OTTileSet>(ref tileSets, xmlTileSets.Count); for (int i = 0; i < xmlTileSets.Count; i++) { if (tileSets[i] == null) tileSets[i] = new OTTileSet(); OTTileSet ts = tileSets[i]; XmlNode n = xmlTileSets[i]; ts.name = AtS(n, "name"); ts.firstGid = AtI(n, "firstgid"); ts.margin = AtI(n, "margin"); ts.spacing = AtI(n, "spacing"); ts.tileSize = new Vector2(AtI(n, "tilewidth"), AtI(n, "tileheight")); XmlNode im = n.SelectSingleNode("image"); string source = AtS(im, "source"); if (tileSetImages.Length > 0) { for (int ii = 0; ii < tileSetImages.Length; ii++) if (source.IndexOf(tileSetImages[ii].name) >= 0) ts.image = tileSetImages[ii]; } ts.imageSize = new Vector2(AtI(im, "width"), AtI(im, "height")); ts.tilesXY = new Vector2(Mathf.Round((ts.imageSize.x-(ts.margin*2)) / (ts.tileSize.x+ts.spacing)), Mathf.Round((ts.imageSize.y-(ts.margin*2)) / (ts.tileSize.y+ts.spacing))); int tileCount = (int)(ts.tilesXY.x * ts.tilesXY.y); int idx = 0; for (int ii = ts.firstGid; ii < ts.firstGid + tileCount; ii++) { if (!tileSetLookup.ContainsKey(ii)) tileSetLookup.Add(ii, ts); OTTile tile = new OTTile(); XmlNode tileNode = n.SelectSingleNode("tile[@id='"+idx+"']"); tile.index = idx++; if (tileNode!=null) { tile.collider = TileProp(tileNode,"collider"); tile.name = TileProp(tileNode,"name"); tile.material = TileProp(tileNode,"material"); tile.display = true; string sDisplay = TileProp(tileNode,"display").ToLower(); if (sDisplay=="none" || sDisplay=="false" || sDisplay=="hidden" || sDisplay=="0") tile.display = false; try { tile.height = System.Convert.ToInt16(TileProp(tileNode,"height")); } catch(System.Exception) { tile.height = 0; } if (tile.height == 0) tile.height = (int)mapTileSize.x; if (tile.height == 0) tile.height = 10; tile.gid = ii; if (tile.name=="") tile.name = "tileGUID"+ii; allTiles.Add(tile); lookupTile.Add(ii,tile); } } } if (layers == null) layers = new OTTileMapLayer[] { }; System.Array.Resize<OTTileMapLayer>(ref layers, xmlLayers.Count); for (int i = 0; i < xmlLayers.Count; i++) { if (layers[i] == null) layers[i] = new OTTileMapLayer(); OTTileMapLayer l = layers[i]; XmlNode n = xmlLayers[i]; l.name = AtS(n, "name"); l.depth = 0 - i; l.layerSize = new Vector2(AtI(n, "width"), AtI(n, "height")); int tileCount = (int)(l.layerSize.x * l.layerSize.y); if (l.tiles.Length!=tileCount) System.Array.Resize<int>(ref l.tiles, tileCount); try { try { XmlNodeList props = n.SelectSingleNode("properties").SelectNodes("property"); if (HasProp(props, "depth")) l.depth = GetPropI(props, "depth"); } catch (System.Exception) { } XmlNodeList tiles = n.SelectSingleNode("data").SelectNodes("tile"); if (tiles.Count != tileCount) Debug.LogWarning("TileMap XML - Invalid number of tiles " + tiles.Count+" on layer "+l.name+", size "+l.layerSize.x+" x "+l.layerSize.y+ " , so expected "+tileCount+" tiles."); for (int li = 0; li < tileCount; li++) l.tiles[li] = 0; for (int li = 0; li < tiles.Count; li++) { int gid = AtI(tiles[li],"gid"); if (lookupTile.ContainsKey(gid)) { if (lookupTile[gid].display) l.tiles[li] = AtI(tiles[li],"gid"); else l.tiles[li] = 0; } else l.tiles[li] = AtI(tiles[li],"gid"); } } catch (System.Exception) { Debug.LogError("TileMap XML - Could not load tiles from layer " + l.name); } } meshDirty = true; isDirty = true; size = new Vector2(mapSize.x * mapTileSize.x, mapSize.y * mapTileSize.y); if (generateColliders) CreateColliders(allTiles); }
void CreateTileColliders(OTTile tile) { // create tilemap for collider creation int[] tiles = new int[] {}; for (int i = 0; i < layers.Length; i++) { OTTileMapLayer l = layers[i]; if (i==0) { tiles = l.tiles.Clone() as int[]; for (int t=0; t<tiles.Length; t++) if (tiles[t]!=tile.gid) tiles[t] = 0; } else { for (int t=0; t<l.tiles.Length; t++) if (l.tiles[t]==tile.gid) tiles[t] = tile.gid; } } Vector2 pos = new Vector2(0,0); while (!pos.Equals(mapSize)) { if (tiles[(int)((pos.y * mapSize.x)+pos.x)] == tile.gid) { Vector2 old = pos; Vector2 col = Vector2.one; while (tiles[(int)((pos.y * mapSize.x)+pos.x)]==tile.gid) { if (pos.y==old.y) { if (pos.x - old.x + 1 >= col.x && pos.y - old.y +1 >= col.y) col = new Vector2(pos.x - old.x + 1, pos.y - old.y +1); } else { if (pos.x - old.x + 1 > col.x) break; else col = new Vector2(col.x, pos.y - old.y +1); } pos.x++; if (pos.x==mapSize.x) { pos.x = old.x; pos.y++; if (pos.y==mapSize.y) break; } else { if (tiles[(int)((pos.y * mapSize.x)+pos.x)]!=tile.gid) { if (col.y > 1 && (pos.x - old.x + 1 < col.x)) { --col.y; break; } pos.x = old.x; pos.y++; if (pos.y==mapSize.y) break; } } } pos = old; for (int dx = 0; dx < col.x; dx++) for (int dy = 0; dy < col.y; dy++) tiles[(int)(((pos.y + dy) * mapSize.x)+(pos.x+dx))] = 0; Transform colliders = transform.FindChild("colliders"); if (colliders == null) { GameObject g = new GameObject(); g.name = "colliders"; colliders = g.transform; colliders.parent = transform; colliders.localScale = Vector3.one; colliders.localPosition = Vector3.zero; } Transform tileColliders = colliders.FindChild(tile.name); if (tileColliders == null) { GameObject g = new GameObject(); g.name = tile.name; tileColliders = g.transform; tileColliders.parent = colliders; tileColliders.localScale = Vector3.one; tileColliders.localPosition = Vector3.zero; } GameObject go = new GameObject(); if (tile.collider.ToLower() != "collider") go.name = "tilemapTrigger"; else go.name = "tilemapCollider"; OTTileSet ts = tileSetLookup[tile.gid]; col.x *= ts.tileSize.x / mapTileSize.x; float fy = ts.tileSize.y / mapTileSize.y; col.y *= fy; if (OT.world == OT.World.WorldTopDown2D) { go.transform.localScale = new Vector3(col.x * mapTileSize.x, tile.height, col.y * mapTileSize.y); go.transform.position = transform.position - new Vector3((mapSize.x * mapTileSize.x)/2,tile.height/3, (-mapSize.y * mapTileSize.y)/2); go.transform.position += new Vector3((pos.x * mapTileSize.x) + mapTileSize.x/2,0, -pos.y * mapTileSize.y - (mapTileSize.y/2)); go.transform.position += new Vector3((col.x * mapTileSize.x)/2 - mapTileSize.x/2,0, (-col.y * mapTileSize.y)/2 + mapTileSize.y/2); if (fy>1) go.transform.position += new Vector3(0, 0, mapTileSize.y * (fy-1)); } else { go.transform.localScale = new Vector3(col.x * mapTileSize.x, col.y * mapTileSize.y, tile.height); go.transform.position = transform.position - new Vector3((mapSize.x * mapTileSize.x)/2, (-mapSize.y * mapTileSize.y)/2, tile.height/3); go.transform.position += new Vector3((pos.x * mapTileSize.x) + mapTileSize.x/2, -pos.y * mapTileSize.y - (mapTileSize.y/2),0); go.transform.position += new Vector3((col.x * mapTileSize.x)/2 - mapTileSize.x/2, (-col.y * mapTileSize.y)/2 + mapTileSize.y/2,0); if (fy>1) go.transform.position += new Vector3(0, mapTileSize.y * (fy-1),0); } go.transform.parent = tileColliders; BoxCollider box = go.AddComponent<BoxCollider>() as BoxCollider; if (tile.material != "") { PhysicMaterial pm = Resources.Load(tile.material) as PhysicMaterial; if (pm != null) box.material = pm; } if (tile.collider.ToLower() == "collider") { Rigidbody rb = go.AddComponent<Rigidbody>() as Rigidbody; // rb.useGravity = false; rb.isKinematic = true; } else box.isTrigger = true; } else { pos.x++; if (pos.x==mapSize.x) { pos.x = 0; pos.y++; if (pos.y==mapSize.y) break; } } } }