public void PlaceTileColliders(SuperMap map, SuperTile tile, TileIdMath tileId, Vector3Int pos) { // Do we have any collider objects defined for this tile? if (!tile.m_CollisionObjects.IsEmpty()) { var polygons = AcquireTilePolygonCollection(tile, tileId, map.m_Orientation); foreach (var poly in polygons.Polygons) { // Offset the polygon so that it is in the location of the tile var offset = map.CellPositionToLocalPosition(pos.x, pos.y, m_ImportContext); var points = poly.Points.Select(pt => pt + offset).ToArray(); CollisionClipperKey key = poly.MakeKey(); CollisionClipper clipper; if (!m_CollisionClippers.TryGetValue(key, out clipper)) { // Add a new clipper for the layer clipper = new CollisionClipper(); m_CollisionClippers.Add(key, clipper); } // Add the path to our clipper if (poly.IsClosed) { clipper.AddClosedPath(points); } else { clipper.AddOpenPath(points); } } } }
private void PlaceTiles(GameObject goTilemap, Chunk chunk, List <uint> tileIds) { // Only report each missing tile Id once HashSet <int> badTiles = new HashSet <int>(); for (int i = 0; i < tileIds.Count; i++) { uint utId = tileIds[i]; if (utId != 0) { var tileId = new TileIdMath(utId); Vector3Int int3 = m_MapComponent.TiledIndexToGridCell(i, chunk.X, chunk.Y, chunk.Width); SuperTile tile; if (m_GlobalTileDatabase.TryGetTile(tileId.JustTileId, out tile)) { var cx = i % chunk.Width; var cy = i / chunk.Width; cx += chunk.X; cy += chunk.Y; PlaceTile(goTilemap, cx, cy, tile, int3, tileId); } else if (!badTiles.Contains(tileId.JustTileId)) { ReportError("Could not find tile {0}. Make sure the tilesets were successfully imported.", tileId.JustTileId); badTiles.Add(tileId.JustTileId); } } } }
public void PlaceTileColliders(SuperMap map, SuperTile tile, TileIdMath tileId, Vector3Int pos) { Assert.IsNotNull(m_Tilemap, "Need a Tilemap component if we are going to gather tile colliders"); // Tile y position is always off by one pos.y++; // Do we have any collider objects defined for this tile? if (!tile.m_CollisionObjects.IsEmpty()) { var polygons = AcquireTilePolygonCollection(tile, tileId); float cell_w = m_Tilemap.cellSize.x; float cell_h = m_Tilemap.cellSize.y; float halfCell_w = m_Tilemap.cellSize.x * 0.5f; float halfCell_h = m_Tilemap.cellSize.y * 0.5f; foreach (var poly in polygons.Polygons) { // Offset the polygon so that it is in the location of the tile var tileHeight = m_ImportContext.MakeScalar(tile.m_Height); var tileDiff = m_Tilemap.cellSize.y - tileHeight; var offset = Vector2.zero; // Our offset depends on map orientation. Isometric is such a pain in the ass. if (map.m_Orientation == MapOrientation.Isometric) { var x = (pos.x - pos.y) * halfCell_w; var y = (pos.x + pos.y) * halfCell_h; offset = new Vector2(x + halfCell_w, y - tileDiff); } else { offset = new Vector2(pos.x * cell_w, pos.y * cell_h - tileDiff); } var points = poly.Points.Select(pt => pt + offset).ToArray(); CollisionClipperKey key = poly.MakeKey(); CollisionClipper clipper; if (!m_CollisionClippers.TryGetValue(key, out clipper)) { // Add a new clipper for the layer clipper = new CollisionClipper(); m_CollisionClippers.Add(key, clipper); } // Add the path to our clipper if (poly.IsClosed) { clipper.AddClosedPath(points); } else { clipper.AddOpenPath(points); } } } }
private void PlaceTileAsTile(GameObject goTilemap, SuperTile tile, TileIdMath tileId, Vector3Int pos3) { var tilemap = goTilemap.GetComponent <Tilemap>(); tilemap.SetTile(pos3, tile); // Do we have any colliders on the tile to be gathered? m_CurrentCollisionBuilder.PlaceTileColliders(tile, tileId, pos3); }
public TilePolygonCollection(SuperTile tile, TileIdMath tileId, SuperImportContext importContext) { m_ImportContext = importContext; m_Tile = tile; m_TileId = tileId; CalculateTransform(); CollectTilePolygons(); }
public TilePolygonCollection(SuperTile tile, TileIdMath tileId, SuperImportContext importContext, MapOrientation orientation) { m_ImportContext = importContext; m_Tile = tile; m_TileId = tileId; m_Transform = m_Tile.GetTransformMatrix(m_TileId.FlipFlags, orientation); CollectTilePolygons(); }
private TilePolygonCollection AcquireTilePolygonCollection(SuperTile tile, TileIdMath tileId, MapOrientation orientation) { TilePolygonCollection polygons; if (m_TilePolygonDatabase.TryGetValue(tileId.ImportedlTileId, out polygons)) { return(polygons); } // If we're here then we don't have a polygon collection for this tile yet polygons = new TilePolygonCollection(tile, tileId, m_ImportContext, orientation); m_TilePolygonDatabase.Add(tileId.ImportedlTileId, polygons); return(polygons); }
private void PlaceTileAsTile(GameObject goTilemap, SuperTile tile, TileIdMath tileId, Vector3Int pos3) { // Burn our layer index into the z component of the tile position // This allows us to support Tilemaps being shared by groups pos3.z = RendererSorter.CurrentTileZ; // Set the tile (sprite, transform matrix, flags) var tilemap = goTilemap.GetComponentInParent <Tilemap>(); tilemap.SetTile(pos3, tile); tilemap.SetTransformMatrix(pos3, tile.GetTransformMatrix(tileId.FlipFlags)); tilemap.SetTileFlags(pos3, TileFlags.LockAll); // Do we have any colliders on the tile to be gathered? m_CurrentCollisionBuilder.PlaceTileColliders(m_MapComponent, tile, tileId, pos3); }
public void PlaceTileColliders(SuperMap map, SuperTile tile, TileIdMath tileId, Vector3Int pos) { Assert.IsNotNull(m_Tilemap, "Need a Tilemap component if we are going to gather tile colliders"); // Do we have any collider objects defined for this tile? if (!tile.m_CollisionObjects.IsEmpty()) { var polygons = AcquireTilePolygonCollection(tile, tileId, map.m_Orientation); foreach (var poly in polygons.Polygons) { // Offset the polygon so that it is in the location of the tile var offset = map.CellPositionToLocalPosition(pos.x, pos.y); if (map.m_Orientation == MapOrientation.Isometric || map.m_Orientation == MapOrientation.Staggered) { offset -= m_ImportContext.MakePointPPU(map.m_TileWidth, 0) * 0.5f; } else if (map.m_Orientation == MapOrientation.Hexagonal) { offset -= m_ImportContext.MakePointPPU(map.m_TileWidth, map.m_TileHeight) * 0.5f; } var points = poly.Points.Select(pt => pt + offset).ToArray(); CollisionClipperKey key = poly.MakeKey(); CollisionClipper clipper; if (!m_CollisionClippers.TryGetValue(key, out clipper)) { // Add a new clipper for the layer clipper = new CollisionClipper(); m_CollisionClippers.Add(key, clipper); } // Add the path to our clipper if (poly.IsClosed) { clipper.AddClosedPath(points); } else { clipper.AddOpenPath(points); } } } }
private void PlaceTileAsTile(GameObject goTilemap, SuperTile tile, TileIdMath tileId, Vector3Int pos3) { // Burn our layer index into the z component of the tile position // This is needed for when using a custom sort axis pos3.z = m_TileLayerCounter; // Set the flip data var tilemapData = goTilemap.GetComponentInParent <TilemapData>(); tilemapData.SetFlipFlags(pos3, tileId.FlipFlags); // Set the tile var tilemap = goTilemap.GetComponentInParent <Tilemap>(); tilemap.SetTile(pos3, tile); // Do we have any colliders on the tile to be gathered? m_CurrentCollisionBuilder.PlaceTileColliders(m_MapComponent, tile, tileId, pos3); }
public void PlaceTileColliders(SuperTile tile, TileIdMath tileId, Vector3Int pos) { Assert.IsNotNull(m_Tilemap, "Need a Tilemap component if we are going to gather tile colliders"); // Tile y position is always off by one pos.y++; // Do we have any collider objects defined for this tile? if (!tile.m_CollisionObjects.IsEmpty()) { var polygons = AcquireTilePolygonCollection(tile, tileId); foreach (var poly in polygons.Polygons) { // Offset the polygon so that it is in the location of the tile var tileHeight = m_ImportContext.MakeScalar(tile.m_Height); var tileDiff = m_Tilemap.cellSize.y - tileHeight; var offset = new Vector2(pos.x * m_Tilemap.cellSize.x, pos.y * m_Tilemap.cellSize.y - tileDiff); var points = poly.Points.Select(pt => pt + offset).ToArray(); CollisionClipperKey key = poly.MakeKey(); CollisionClipper clipper; if (!m_CollisionClippers.TryGetValue(key, out clipper)) { // Add a new clipper for the layer clipper = new CollisionClipper(); m_CollisionClippers.Add(key, clipper); } // Add the path to our clipper if (poly.IsClosed) { clipper.AddClosedPath(points); } else { clipper.AddOpenPath(points); } } } }
private void ProcessTile(XElement xObject) { uint gId = xObject.GetAttributeAs <uint>("gid", 0); if (gId != 0) { Assert.IsNotNull(m_GlobalTileDatabase); var tileId = new TileIdMath(gId); // Store a reference to the tile SuperTile tile; if (m_GlobalTileDatabase.TryGetTile(tileId.JustTileId, out tile)) { m_ObjectTemplate.m_Tile = tile; } else { ReportError("Could not find tile '{0}' in tileset", tileId.JustTileId); } } }
private void PlaceTiles(GameObject goTilemap, Chunk chunk, List <uint> tileIds) { // Only report each missing tile Id once HashSet <int> badTiles = new HashSet <int>(); for (int i = 0; i < tileIds.Count; i++) { uint utId = tileIds[i]; if (utId != 0) { var tileId = new TileIdMath(utId); var cx = i % chunk.Width; var cy = i / chunk.Width; cx += chunk.X; cy += chunk.Y; // Y position is tricky. We want the origin to be the top-left corner Vector3Int int3 = m_MapComponent.TileIndexToGridPosition(i, chunk.Width); int3.y = -int3.y; int3.y -= 1; SuperTile tile; if (m_GlobalTileDatabase.TryGetTile(tileId.JustTileId, out tile)) { PlaceTile(goTilemap, cx, cy, tile, int3, tileId); } else if (!badTiles.Contains(tileId.JustTileId)) { ReportError("Could not find tile {0}. Your imported map will have holes until this is fixed.", tileId.JustTileId); badTiles.Add(tileId.JustTileId); } } } }
private void PlaceTileAsTile(GameObject goTilemap, Tilemap tilemap, TilemapRenderer tilemapRenderer, SuperTile tile, TileIdMath tileId, Vector3Int pos3) { // Burn our layer index into the z component of the tile position // This allows us to support Tilemaps being shared by groups pos3.z = RendererSorter.CurrentTileZ; if (SuperImportContext.LayerIgnoreMode != LayerIgnoreMode.Visual) { // Set the tile (sprite, transform matrix, flags) tilemap.SetTile(pos3, tile); tilemap.SetTransformMatrix(pos3, tile.GetTransformMatrix(tileId.FlipFlags, m_MapComponent.m_Orientation)); #if UNITY_2018_3_OR_NEWER if (tilemapRenderer.mode == TilemapRenderer.Mode.Individual) { // Each tile color must be set individually tilemap.SetColor(pos3, tilemap.color); } #endif tilemap.SetTileFlags(pos3, TileFlags.LockAll); } if (SuperImportContext.LayerIgnoreMode != LayerIgnoreMode.Collision) { // Do we have any colliders on the tile to be gathered? m_CurrentCollisionBuilder.PlaceTileColliders(m_MapComponent, tile, tileId, pos3); } }
private void PlaceTileAsObject(GameObject goTilemap, SuperTile tile, int cx, int cy, TileIdMath tileId, Vector3Int pos3) { Assert.IsNotNull(goTilemap.GetComponentInParent <SuperMap>()); Assert.IsNotNull(goTilemap.GetComponentInParent <SuperLayer>()); var superMap = goTilemap.GetComponentInParent <SuperMap>(); var superLayer = goTilemap.GetComponentInParent <SuperLayer>(); var color = superLayer.CalculateColor(); string tileName = string.Format("tile ({0}, {1})", cx, cy); var goTRS = new GameObject(string.Format("{0} (TRS)", tileName)); goTilemap.AddChildWithUniqueName(goTRS); // Create a faux SuperObject component to add to our placed tile // We need this in case we have custom scripts that are looking for tile object via component { var tileObject = goTRS.AddComponent <SuperObject>(); tileObject.m_Id = m_ObjectIdCounter++; tileObject.m_TiledName = string.Format("AsObject_{0}", tileObject.m_Id); tileObject.m_X = pos3.x * superMap.m_TileWidth; tileObject.m_Y = -pos3.y * superMap.m_TileHeight; tileObject.m_Width = tile.m_Width; tileObject.m_Height = tile.m_Height; tileObject.m_TileId = (uint)tile.m_TileId; tileObject.m_Visible = true; // Does the tile have any properties? if (!tile.m_CustomProperties.IsEmpty()) { var component = tileObject.gameObject.AddComponent <SuperCustomProperties>(); component.m_Properties = new List <CustomProperty>(); component.m_Properties.CombineFromSource(tile.m_CustomProperties); } } Vector3 translate, rotate, scale; tile.GetTRS(tileId.FlipFlags, m_MapComponent.m_Orientation, out translate, out rotate, out scale); var cellPos = superMap.CellPositionToLocalPosition(pos3.x, pos3.y, SuperImportContext); translate.x += cellPos.x; translate.y += cellPos.y; // Add the game object for the tile goTRS.transform.localPosition = translate; goTRS.transform.localRotation = Quaternion.Euler(rotate); goTRS.transform.localScale = scale; // Add the sprite renderer component var renderer = goTRS.AddComponent <SpriteRenderer>(); renderer.sprite = tile.m_Sprite; renderer.color = color; AssignMaterial(renderer, m_CurrentTileLayer.m_TiledName); AssignSpriteSorting(renderer); if (!tile.m_AnimationSprites.IsEmpty()) { var tileAnimator = goTRS.AddComponent <TileObjectAnimator>(); tileAnimator.m_AnimationFramerate = SuperImportContext.Settings.AnimationFramerate; tileAnimator.m_AnimationSprites = tile.m_AnimationSprites; } // Add any colliders that may be on the tile object tile.AddCollidersForTileObject(goTRS, SuperImportContext); }
private void PlaceTile(GameObject goTilemap, Tilemap tilemap, TilemapRenderer tilemapRenderer, int cx, int cy, SuperTile tile, Vector3Int pos3, TileIdMath tileId) { if (m_TilesAsObjects) { PlaceTileAsObject(goTilemap, tile, cx, cy, tileId, pos3); } else { PlaceTileAsTile(goTilemap, tilemap, tilemapRenderer, tile, tileId, pos3); } }
private void ProcessTileObject(SuperObject superObject, XElement xObject) { Assert.IsNull(superObject.m_SuperTile); Assert.IsNotNull(GlobalTileDatabase, "Cannot process tile objects without a tileset database"); SuperTile tile = null; var tileId = new TileIdMath(superObject.m_TileId); int justTileId = tileId.JustTileId; // Are we getting the tile from a template? var template = xObject.GetAttributeAs("template", ""); if (!string.IsNullOrEmpty(template)) { var asset = Importer.RequestAssetAtPath <ObjectTemplate>(template); if (asset == null) { Importer.ReportError("Template file '{0}' was not found.", template); return; } tile = asset.m_Tile; if (tile == null) { Importer.ReportError("Missing tile '{0}' from template '{1}' on tile object '{2}'", justTileId, template, superObject.name); return; } } // Are we getting the tile from our tile database? if (tile == null) { GlobalTileDatabase.TryGetTile(justTileId, out tile); if (tile == null) { Importer.ReportError("Missing tile '{0}' on tile object '{1}'", justTileId, template, superObject.name); return; } } // Our type may come from the tile as well (this is 'Typed Tiles' in Tiled) if (string.IsNullOrEmpty(superObject.m_Type)) { superObject.m_Type = tile.m_Type; } // Construct the game objects for displaying a single tile var inversePPU = Importer.SuperImportContext.Settings.InversePPU; bool flip_h = tileId.HasHorizontalFlip; bool flip_v = tileId.HasVerticalFlip; var scale = Vector3.one; scale.x = xObject.GetAttributeAs("width", 1.0f); scale.y = xObject.GetAttributeAs("height", 1.0f); scale.x /= tile.m_Width; scale.y /= tile.m_Height; var tileOffset = new Vector3(tile.m_TileOffsetX * inversePPU, -tile.m_TileOffsetY * inversePPU); var translateCenter = new Vector3(tile.m_Width * 0.5f * inversePPU, tile.m_Height * 0.5f * inversePPU); // Our root object will contain the translation, rotation, and scale of the tile object var goTRS = superObject.gameObject; goTRS.transform.localScale = scale; // Add another object to handle tile flipping // This object will center us into the tile and perform the flips through scaling // This object also contains the tile offset in her transform var goCF = new GameObject(); goCF.name = string.Format("{0} (CF)", superObject.m_TiledName); goTRS.AddChildWithUniqueName(goCF); goCF.transform.localPosition = translateCenter + tileOffset; goCF.transform.localRotation = Quaternion.Euler(0, 0, 0); goCF.transform.localScale = new Vector3(flip_h ? -1 : 1, flip_v ? -1 : 1, 1); // Note: We may not want to put the tile "back into place" depending on our coordinate system var fromCenter = -translateCenter; // Isometric maps referece tile objects by bottom center if (SuperMap.m_Orientation == MapOrientation.Isometric) { fromCenter.x -= Importer.SuperImportContext.MakeScalar(tile.m_Width * 0.5f); } // Add another child, putting our coordinates back into the proper place var goTile = new GameObject(superObject.m_TiledName); goCF.AddChildWithUniqueName(goTile); goTile.transform.localPosition = fromCenter; goTile.transform.localRotation = Quaternion.Euler(0, 0, 0); goTile.transform.localScale = Vector3.one; if (Importer.SuperImportContext.LayerIgnoreMode != LayerIgnoreMode.Visual) { // Add the renderer var renderer = goTile.AddComponent <SpriteRenderer>(); renderer.sprite = tile.m_Sprite; renderer.color = new Color(1, 1, 1, superObject.CalculateOpacity()); Importer.AssignMaterial(renderer, m_ObjectLayer.m_TiledName); Importer.AssignSpriteSorting(renderer); // Add the animator if needed if (!tile.m_AnimationSprites.IsEmpty()) { var tileAnimator = goTile.AddComponent <TileObjectAnimator>(); tileAnimator.m_AnimationFramerate = AnimationFramerate; tileAnimator.m_AnimationSprites = tile.m_AnimationSprites; } } if (Importer.SuperImportContext.LayerIgnoreMode != LayerIgnoreMode.Collision) { // Add any colliders that were set up on the tile in the collision editor tile.AddCollidersForTileObject(goTile, Importer.SuperImportContext); } // Store a reference to our tile object superObject.m_SuperTile = tile; }
private void PlaceTile(GameObject goTilemap, int cx, int cy, SuperTile tile, Vector3Int pos3, TileIdMath tileId) { // We're either placing tiles or objects as tiles Assert.IsTrue(m_TilesAsObjects || m_MapComponent.m_Orientation == MapOrientation.Isometric || goTilemap.GetComponent <Tilemap>() != null); // Bake transform flags into the z component (for flipped/rotated tiles) pos3.z = tileId.PlacementZ; bool tilesAsObjects = m_MapComponent.m_Orientation == MapOrientation.Isometric || m_TilesAsObjects; if (tilesAsObjects) { PlaceTileAsObject(goTilemap, tile, cx, cy, pos3); } else { PlaceTileAsTile(goTilemap, tile, tileId, pos3); } }