/// <summary> /// Converts a tile index or position into 3D world coordinates /// </summary> /// <param name="posX">Tile index or position of object in tiled</param> /// <param name="posY">Tile index or position of object in tiled</param> /// <param name="posZ">zIndex of object</param> /// <param name="tile">Tile to get size from</param> /// <returns>World's X, Y and Z position</returns> public Vector3 TiledPositionToWorldPoint(float posX, float posY, float posZ, Tile tile = null) { Vector3 p = new Vector3(); Vector2 p2d = TiledPositionToWorldPoint(posX, posY, tile); // No need to change Z value, this function is just a helper p.x = p2d.x; p.y = p2d.y; p.z = posZ; return p; }
public Vector2 TiledPositionToWorldPoint(Vector2 position, Tile tile = null) { return TiledPositionToWorldPoint(position.x, position.y, tile); }
/// <summary> /// Creates a copy of the current tile. /// </summary> /// <returns>A new Tile with the same properties as the current tile.</returns> public virtual Tile Clone() { Tile t = new Tile(TileSet, Source, OriginalID, Properties); t.TileSprite = TileSprite; t.SpriteEffects = SpriteEffects; t.MapTileWidth = MapTileWidth; return t; }
/// <summary> /// Converts a tile index or position into world coordinates /// </summary> /// <param name="posX">Tile index or position of object in tiled</param> /// <param name="posY">Tile index or position of object in tiled</param> /// <param name="tile">Tile to get size from</param> /// <returns>World's X and Y position</returns> public Vector2 TiledPositionToWorldPoint(float posX, float posY, Tile tile = null) { Vector2 p = Vector2.zero; float currentTileWidth = TileWidth; float currentTileHeight = TileHeight; if (tile == null) { Dictionary<int, Tile>.ValueCollection.Enumerator enumerator = Tiles.Values.GetEnumerator(); enumerator.MoveNext(); currentTileWidth = enumerator.Current.TileSet.TileWidth; currentTileHeight = enumerator.Current.TileSet.TileHeight; } else { currentTileWidth = tile.TileSet.TileWidth; currentTileHeight = tile.TileSet.TileHeight; } if (Orientation == Orientation.Orthogonal) { p.x = posX * (TileWidth / currentTileWidth); p.y = -posY * (TileHeight / currentTileHeight) * (currentTileHeight / currentTileWidth); } else if (Orientation == Orientation.Isometric) { p.x = (TileWidth / 2.0f * (Width - posY + posX)) / (float)TileWidth;//(TileWidth / 2.0f * (Width / 2.0f - posY + posX)) / (float)TileWidth;// p.y = -Height + TileHeight * (Height - ((posX + posY) / (TileWidth / (float)TileHeight)) / 2.0f) / (float)TileHeight; } else if (Orientation == X_UniTMX.Orientation.Staggered) { p.x = posX * (TileWidth / currentTileWidth); if (Mathf.FloorToInt(Mathf.Abs(posY)) % 2 > 0) p.x += 0.5f; p.y = -posY * (TileHeight / 2.0f / currentTileHeight) * (currentTileHeight / currentTileWidth); } return p; }
void CreateTileGameObject(Tile t, int x, int y) { // Create Tile's GameObject t.CreateTileObject(Name + "[" + x + ", " + y + "]", LayerGameObject.transform, Name, BaseMap.DefaultSortingOrder + BaseMap.GetSortingOrder(x, y), GetTileWorldPosition(x, y, t.TileSet), BaseMaterials, Opacity); if (t.TileSet.AnimatedTiles.ContainsKey(t.OriginalID)) { AnimatedSprite _animatedTile = t.TileGameObject.AddComponent<AnimatedSprite>(); // Tiled defaults to LOOP _animatedTile.AnimationMode = SpriteAnimationMode.LOOP; foreach (var tileFrame in t.TileSet.AnimatedTiles[t.OriginalID].TileFrames) { Tile tile; if (BaseMap.Tiles.TryGetValue(tileFrame.TileID, out tile)) { _animatedTile.AddSpriteFrame(tile.TileSprite, tileFrame.Duration); } else { Debug.LogWarning("Invalid Tile ID while building tile animation: " + tileFrame.TileID); } } } }
void GetVerticesForTile(Tile t, int x, int y, int preVertexCount, out Vector3[] vertices, out int[] triangles) { vertices = new Vector3[4]; Vector3 tilePos = GetTileWorldPosition(x, y, t.TileSet); float tileHeightInUnits = t.Source.height / (float)BaseMap.TileWidth; float tileWidthInUnits = t.Source.width / (float)BaseMap.TileWidth; // normal vertices: // 1 ----- 3 // | \ | // | \ | // | \ | // 0 ----- 2 vertices[0] = tilePos; vertices[1] = tilePos + new Vector3(0, tileHeightInUnits); vertices[2] = tilePos + new Vector3(tileWidthInUnits, 0); vertices[3] = tilePos + new Vector3(tileWidthInUnits, tileHeightInUnits); triangles = new int[] { preVertexCount , preVertexCount + 1, preVertexCount + 2, preVertexCount + 2, preVertexCount + 1, preVertexCount + 3, }; // Then, rotate / flip if needed if (t.SpriteEffects != null) { if (t.SpriteEffects.flippedAntiDiagonally || t.SpriteEffects.flippedHorizontally || t.SpriteEffects.flippedVertically) { float ratioHW = t.TileSet.TileHeight / (float)t.TileSet.TileWidth; Vector3 flipAnchor = tilePos + new Vector3(0.5f, tileHeightInUnits / 2.0f); Vector3 rotateAnchor = tilePos; if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].FlipPointHorizontally(flipAnchor); } } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].FlipPointVertically(flipAnchor); } } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].FlipPointDiagonally(flipAnchor); } } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == true) { flipAnchor = tilePos + new Vector3(0, 0.5f); for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, new Vector3(0, 0, 90)); vertices[i] = vertices[i].FlipPointVertically(flipAnchor) + new Vector3(ratioHW, 0); } } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == true) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, new Vector3(0, 0, -90)) + Vector3.up; } } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == true) { for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, new Vector3(0, 0, 90)) + new Vector3(ratioHW, 0); } } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == true) { flipAnchor = tilePos + new Vector3(0, -0.5f); for (int i = 0; i < vertices.Length; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, new Vector3(0, 0, -90)); vertices[i] = vertices[i].FlipPointVertically(flipAnchor) + Vector3.up; } } } } }
/// <summary> /// Applies to gameObject any custom X-UniTMX properties present on tile /// </summary> /// <param name="gameObject">GameObject to apply custom properties to</param> /// <param name="tile">Tile to read custom properties from</param> public static void ApplyCustomProperties(GameObject gameObject, Tile tile) { ApplyCustomProperties(gameObject, tile.Properties); }
/// <summary> /// Converts a tile index or position into 3D world coordinates /// </summary> /// <param name="position">Tile index or position of object in Tiled</param> /// <param name="tile">Tile to get size from</param> /// <returns>World's X and Y position</returns> public static Vector2 TiledPositionToWorldPoint(this Map map, Vector2 position, Tile tile = null) { return TiledPositionToWorldPoint(map, position.x, position.y, tile); }
/// <summary> /// Converts a tile index or position into world coordinates /// </summary> /// <param name="posX">Tile index or position of object in tiled</param> /// <param name="posY">Tile index or position of object in tiled</param> /// <param name="tile">Tile to get size from</param> /// <returns>World's X and Y position</returns> public static Vector2 TiledPositionToWorldPoint(this Map map ,float posX, float posY, Tile tile = null) { Vector2 p = Vector2.zero; MapRenderParameters mrp = map.MapRenderParameter; float currentTileWidth = mrp.TileWidth; float currentTileHeight = mrp.TileHeight; bool staggeredInY = mrp.MapStaggerAxis.Equals(StaggerAxis.Y); bool staggeredEven = mrp.MapStaggerIndex.Equals(StaggerIndex.Even); //if (tile == null) //{ // Dictionary<int, Tile>.ValueCollection.Enumerator enumerator = map.Tiles.Values.GetEnumerator(); // enumerator.MoveNext(); // if (enumerator.Current != null && enumerator.Current.TileSet != null) // { // currentTileWidth = enumerator.Current.TileSet.TileWidth; // currentTileHeight = enumerator.Current.TileSet.TileHeight; // } //} //else if(tile != null) { if (tile.TileSet != null) { currentTileWidth = tile.TileSet.TileWidth; currentTileHeight = tile.TileSet.TileHeight; } } if (mrp.Orientation == Orientation.Orthogonal) { p.x = posX * (mrp.TileWidth / currentTileWidth); p.y = -posY * (mrp.TileHeight / currentTileHeight) * (currentTileHeight / currentTileWidth); } else if (mrp.Orientation == Orientation.Isometric) { p.x = (mrp.TileWidth / 2.0f * (mrp.Width - posY + posX)) / (float)mrp.TileWidth;//(TileWidth / 2.0f * (Width / 2.0f - posY + posX)) / (float)TileWidth;// p.y = -mrp.Height + mrp.TileHeight * (mrp.Height - ((posX + posY) / (mrp.TileWidth / (float)mrp.TileHeight)) / 2.0f) / (float)mrp.TileHeight; } else if (mrp.Orientation == X_UniTMX.Orientation.Staggered) { if (staggeredInY) { p.x = posX * (mrp.TileWidth / currentTileWidth); if ((!staggeredEven && Mathf.FloorToInt(Mathf.Abs(posY)) % 2 > 0) || (staggeredEven && Mathf.FloorToInt(Mathf.Abs(posY)) % 2 < 1)) p.x += 0.5f; p.y = -posY * (mrp.TileHeight / 2.0f / currentTileHeight) * (currentTileHeight / currentTileWidth); } else { p.y = -posY * (mrp.TileHeight / 2.0f / currentTileHeight); if ((!staggeredEven && Mathf.FloorToInt(Mathf.Abs(posX)) % 2 > 0) || (staggeredEven && Mathf.FloorToInt(Mathf.Abs(posX)) % 2 < 1)) p.y -= (mrp.TileHeight / 2.0f / currentTileHeight) * (currentTileHeight / currentTileWidth); p.x = posX * (mrp.TileWidth / currentTileWidth) * (currentTileHeight / currentTileWidth); } } else if (mrp.Orientation == X_UniTMX.Orientation.Hexagonal) { if (staggeredInY) { float halfGap = (mrp.TileHeight - mrp.HexSideLength) / 2.0f; float tileDisplacement = halfGap + mrp.HexSideLength; p.x = posX * (mrp.TileWidth / currentTileWidth); if ((!staggeredEven && Mathf.FloorToInt(Mathf.Abs(posY)) % 2 > 0) || (staggeredEven && Mathf.FloorToInt(Mathf.Abs(posY)) % 2 < 1)) p.x += (mrp.TileWidth / currentTileWidth) / 2.0f; p.y = -posY * (tileDisplacement / currentTileHeight); } else { float halfGap = (mrp.TileWidth - mrp.HexSideLength) / 2.0f; float tileDisplacement = halfGap + mrp.HexSideLength; p.y = -posY * (mrp.TileHeight / currentTileHeight) * (currentTileHeight / currentTileWidth); if ((!staggeredEven && Mathf.FloorToInt(Mathf.Abs(posX)) % 2 > 0) || (staggeredEven && Mathf.FloorToInt(Mathf.Abs(posX)) % 2 < 1)) p.y -= (mrp.TileHeight / currentTileHeight) / 2.0f * (currentTileHeight / currentTileWidth); p.x = posX * (tileDisplacement / currentTileWidth); } } return p; }
// It is ugly, but for a better performance, vertices, triangles and normals lists are globals :X void GetVerticesForTile(Tile t, int x, int y, int preVertexCount) { Vector3 tilePos = GetTileWorldPosition(x, y, t.TileSet); float tileHeightInUnits = (t.Source.height + XUniTMXConfiguration.Instance.PixelCorrection) / (float)BaseMap.MapRenderParameter.TileWidth; float tileWidthInUnits = (t.Source.width + XUniTMXConfiguration.Instance.PixelCorrection) / (float)BaseMap.MapRenderParameter.TileWidth; // normal vertices: // 1 ----- 3 // | \ | // | \ | // | \ | // 0 ----- 2 vertices.Add(tilePos); vertices.Add(tilePos + new Vector3(0, tileHeightInUnits)); vertices.Add(tilePos + new Vector3(tileWidthInUnits, 0)); vertices.Add(tilePos + new Vector3(tileWidthInUnits, tileHeightInUnits)); int preTrianglesCount = triangles.Count; triangles.Add(preVertexCount); triangles.Add(preVertexCount + 1); triangles.Add(preVertexCount + 2); triangles.Add(preVertexCount + 2); triangles.Add(preVertexCount + 1); triangles.Add(preVertexCount + 3); normals.Add(forward); normals.Add(forward); normals.Add(forward); normals.Add(forward); // Then, rotate / flip if needed if (t.SpriteEffects != null) { if (t.SpriteEffects.flippedAntiDiagonally || t.SpriteEffects.flippedHorizontally || t.SpriteEffects.flippedVertically) { float ratioHW = t.TileSet.TileHeight / (float)t.TileSet.TileWidth; Vector3 flipAnchor = tilePos + new Vector3(0.5f, tileHeightInUnits / 2.0f); Vector3 rotateAnchor = tilePos; Vector3 z90Degrees = new Vector3(0, 0, 90); if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].FlipPointHorizontally(flipAnchor); } triangles[preTrianglesCount] = preVertexCount + 1; triangles[preTrianglesCount + 1] = preVertexCount; triangles[preTrianglesCount + 2] = preVertexCount + 2; triangles[preTrianglesCount + 3] = preVertexCount + 1; triangles[preTrianglesCount + 4] = preVertexCount + 2; triangles[preTrianglesCount + 5] = preVertexCount + 3; } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].FlipPointVertically(flipAnchor); } triangles[preTrianglesCount] = preVertexCount + 1; triangles[preTrianglesCount + 1] = preVertexCount; triangles[preTrianglesCount + 2] = preVertexCount + 2; triangles[preTrianglesCount + 3] = preVertexCount + 1; triangles[preTrianglesCount + 4] = preVertexCount + 2; triangles[preTrianglesCount + 5] = preVertexCount + 3; } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == false) { for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].FlipPointDiagonally(flipAnchor); } } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == true) { flipAnchor = tilePos + new Vector3(0, 0.5f); for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, z90Degrees); vertices[i] = vertices[i].FlipPointVertically(flipAnchor) + new Vector3(ratioHW, 0); } triangles[preTrianglesCount] = preVertexCount + 1; triangles[preTrianglesCount + 1] = preVertexCount; triangles[preTrianglesCount + 2] = preVertexCount + 2; triangles[preTrianglesCount + 3] = preVertexCount + 1; triangles[preTrianglesCount + 4] = preVertexCount + 2; triangles[preTrianglesCount + 5] = preVertexCount + 3; } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == false && t.SpriteEffects.flippedAntiDiagonally == true) { for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, -z90Degrees) + Vector3.up; } } if (t.SpriteEffects.flippedHorizontally == false && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == true) { for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, z90Degrees) + new Vector3(ratioHW, 0); } } if (t.SpriteEffects.flippedHorizontally == true && t.SpriteEffects.flippedVertically == true && t.SpriteEffects.flippedAntiDiagonally == true) { flipAnchor = tilePos + new Vector3(0, -0.5f); for (int i = preVertexCount; i < vertices.Count; i++) { vertices[i] = vertices[i].RotatePoint(rotateAnchor, -z90Degrees); vertices[i] = vertices[i].FlipPointVertically(flipAnchor) + Vector3.up; } triangles[preTrianglesCount] = preVertexCount + 1; triangles[preTrianglesCount + 1] = preVertexCount; triangles[preTrianglesCount + 2] = preVertexCount + 2; triangles[preTrianglesCount + 3] = preVertexCount + 1; triangles[preTrianglesCount + 4] = preVertexCount + 2; triangles[preTrianglesCount + 5] = preVertexCount + 3; } } } }
void CreateTileGameObject(Tile t, int x, int y) { // if this tile contains the prefab porperty, then generate the prefab if (t.HasProperty(Map.Property_PrefabName)) { MapObject m = new MapObject(t.CurrentID.ToString(), string.Empty, new Rect(x, y, 1, 1), t.Properties, t.OriginalID, null, 0, null); BaseMap.GeneratePrefab(m, XUniTMXConfiguration.Instance.GetTilePrefabsAnchorPoint(), LayerGameObject); return; } // Create Tile's GameObject if(LayerMaterial == null) t.CreateTileObject(Name + "[" + x + ", " + y + "]", LayerGameObject.transform, Name, BaseMap.DefaultSortingOrder + BaseMap.GetSortingOrder(x, y), GetTileWorldPosition(x, y, t.TileSet), BaseMaterials, Opacity); else t.CreateTileObject(Name + "[" + x + ", " + y + "]", LayerGameObject.transform, Name, BaseMap.DefaultSortingOrder + BaseMap.GetSortingOrder(x, y), GetTileWorldPosition(x, y, t.TileSet), LayerMaterial, Opacity); if (t.TileSet.AnimatedTiles.ContainsKey(t.OriginalID)) { AnimatedSprite _animatedTile = t.TileGameObject.AddComponent<AnimatedSprite>(); // Tiled defaults to LOOP _animatedTile.AnimationMode = SpriteAnimationMode.LOOP; foreach (var tileFrame in t.TileSet.AnimatedTiles[t.OriginalID].TileFrames) { Tile tile; if (BaseMap.Tiles.TryGetValue(tileFrame.TileID, out tile)) { _animatedTile.AddSpriteFrame(tile.TileSprite, tileFrame.Duration); } else { Debug.LogWarning("Invalid Tile ID while building tile animation: " + tileFrame.TileID); } } } MapExtensions.ApplyCustomProperties(t.TileGameObject, t); }