Example #1
0
        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);
                    }
                }
            }
        }
Example #3
0
        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);
                    }
                }
            }
        }
Example #4
0
        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();
        }
Example #7
0
        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);
        }
Example #9
0
        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);
                }
            }
        }
Example #13
0
        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);
                    }
                }
            }
        }
Example #14
0
        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);
            }
        }
Example #15
0
        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);
        }
Example #16
0
 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);
     }
 }
Example #17
0
        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;
        }
Example #18
0
        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);
            }
        }