Example #1
0
        private void AddTileObjectElements(TmxObjectTile tmxObjectTile, XElement xmlTileObjectRoot, XElement objComponent)
        {
            // TileObjects can be scaled (this is separate from vertex scaling)
            SizeF scale = tmxObjectTile.GetTileObjectScale();

            // Flipping is done through negative-scaling on the child object
            float flip_w = tmxObjectTile.FlippedHorizontal ? -1.0f : 1.0f;
            float flip_h = tmxObjectTile.FlippedVertical ? -1.0f : 1.0f;

            // Helper values for moving tile about local origin
            float full_w = tmxObjectTile.Tile.TileSize.Width;
            float full_h = tmxObjectTile.Tile.TileSize.Height;
            float half_w = full_w * 0.5f;
            float half_h = full_h * 0.5f;

            // Scale goes onto root node
            xmlTileObjectRoot.SetAttributeValue("scaleX", scale.Width);
            xmlTileObjectRoot.SetAttributeValue("scaleY", scale.Height);

            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxObjectTile.Tile, xmlTileObjectRoot);

            // Treat ObjectComponent as a TileObjectComponent scripting purposes
            {
                objComponent.Name = "TileObjectComponent";
                objComponent.SetAttributeValue("tmx-tile-flip-horizontal", tmxObjectTile.FlippedHorizontal);
                objComponent.SetAttributeValue("tmx-tile-flip-vertical", tmxObjectTile.FlippedVertical);
                objComponent.SetAttributeValue("width", tmxObjectTile.Tile.TileSize.Width * scale.Width * Tiled2Unity.Settings.Scale);
                objComponent.SetAttributeValue("height", tmxObjectTile.Tile.TileSize.Height * scale.Height * Tiled2Unity.Settings.Scale);
                xmlTileObjectRoot.Add(objComponent);
            }

            // Child node positions game object to match center of tile so can flip along x and y axes
            XElement xmlTileObject = new XElement("GameObject");

            xmlTileObject.SetAttributeValue("name", "TileObject");
            if (tmxMap.Orientation == TmxMap.MapOrientation.Isometric)
            {
                // In isometric mode the local origin of the tile is at the bottom middle
                xmlTileObject.SetAttributeValue("x", 0);
                xmlTileObject.SetAttributeValue("y", half_h * Tiled2Unity.Settings.Scale);
            }
            else
            {
                // For non-isometric maps the local origin of the tile is the bottom left
                xmlTileObject.SetAttributeValue("x", half_w * Tiled2Unity.Settings.Scale);
                xmlTileObject.SetAttributeValue("y", half_h * Tiled2Unity.Settings.Scale);
            }
            xmlTileObject.SetAttributeValue("scaleX", flip_w);
            xmlTileObject.SetAttributeValue("scaleY", flip_h);

            // Add any colliders that might be on the tile
            // Note: Colliders on a tile object are always treated as if they are in Orthogonal space
            TmxMap.MapOrientation restoreOrientation = tmxMap.Orientation;
            this.tmxMap.Orientation = TmxMap.MapOrientation.Orthogonal;

            // Only add colliders if collisions are not being ignored
            if (tmxObjectTile.ParentObjectGroup.Ignore != TmxLayerNode.IgnoreSettings.Collision)
            {
                foreach (TmxObject tmxObject in tmxObjectTile.Tile.ObjectGroup.Objects)
                {
                    XElement objElement = null;

                    if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        // Note: Tile objects have orthographic rectangles even in isometric orientations so no need to transform rectangle points
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxObjectTile.Tile.ObjectGroup.Name);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                    }

                    if (objElement != null)
                    {
                        // This object is currently in the center of the Tile Object we are constructing
                        // The collision geometry is wrt the top-left corner
                        // The "Offset" of the collider translation to get to lop-left corner and the collider's position into account
                        float offset_x = (-half_w + tmxObject.Position.X) * Tiled2Unity.Settings.Scale;
                        float offset_y = (half_h - tmxObject.Position.Y) * Tiled2Unity.Settings.Scale;
                        objElement.SetAttributeValue("offsetX", offset_x);
                        objElement.SetAttributeValue("offsetY", offset_y);

                        xmlTileObject.Add(objElement);
                    }
                }
            }
            this.tmxMap.Orientation = restoreOrientation;

            // Add a child for each mesh
            // (The child node is needed due to animation)
            // (Only add meshes if visuals are not being ignored)
            if (tmxObjectTile.ParentObjectGroup.Ignore != TmxLayerNode.IgnoreSettings.Visual)
            {
                foreach (var mesh in tmxObjectTile.Tile.Meshes)
                {
                    XElement xmlMeshObject = new XElement("GameObject");

                    xmlMeshObject.SetAttributeValue("name", mesh.ObjectName);
                    xmlMeshObject.SetAttributeValue("copy", mesh.UniqueMeshName);

                    xmlMeshObject.SetAttributeValue("sortingLayerName", tmxObjectTile.GetSortingLayerName());
                    xmlMeshObject.SetAttributeValue("sortingOrder", tmxObjectTile.GetSortingOrder());

                    // Game object that contains mesh moves position to that local origin of Tile Object (from Tiled's point of view) matches the root position of the Tile game object
                    // Put another way: This translation moves away from center to local origin
                    xmlMeshObject.SetAttributeValue("x", -half_w * Tiled2Unity.Settings.Scale);
                    xmlMeshObject.SetAttributeValue("y", half_h * Tiled2Unity.Settings.Scale);

                    if (mesh.FullAnimationDurationMs > 0)
                    {
                        XElement xmlAnimation = new XElement("TileAnimator",
                                                             new XAttribute("startTimeMs", mesh.StartTimeMs),
                                                             new XAttribute("durationMs", mesh.DurationMs),
                                                             new XAttribute("fullTimeMs", mesh.FullAnimationDurationMs));
                        xmlMeshObject.Add(xmlAnimation);
                    }

                    xmlTileObject.Add(xmlMeshObject);
                }
            }

            xmlTileObjectRoot.Add(xmlTileObject);
        }