/// <summary>
        /// Creates this Tile Object (an object that has OriginalID) if applicable
        /// </summary>
        /// <param name="tiledMap">The base Tile Map</param>
        /// <param name="layerDepth">Layer's zDepth</param>
        /// <param name="sortingLayerName">Layer's SortingLayerName</param>
        /// <param name="parent">Transform to parent this object to</param>
        /// <param name="materials">List of TileSet Materials</param>
        public static GameObject CreateTileObject(this MapObject obj, Map tiledMap, string sortingLayerName, int layerDepth, List<Material> materials, Transform parent = null)
        {
            if (obj.GID > 0)
            {
                Tile objTile = null;
                if (tiledMap.MapRenderParameter.Orientation != Orientation.Orthogonal)
                    objTile = tiledMap.Tiles[obj.GID].Clone(new Vector2(0.5f, 0.5f));
                else
                    objTile = tiledMap.Tiles[obj.GID].Clone();

                objTile.CreateTileObject(obj.Name,
                    parent != null ? parent : obj.ParentObjectLayer.LayerGameObject.transform,
                    sortingLayerName,
                    tiledMap.DefaultSortingOrder + tiledMap.GetSortingOrder(obj.Bounds.x, obj.Bounds.y),
                    tiledMap.TiledPositionToWorldPoint(obj.Bounds.x, obj.Bounds.y, layerDepth),
                    materials);
                obj.Bounds.Set(obj.Bounds.x, obj.Bounds.y - 1, obj.Bounds.width, obj.Bounds.height);

                objTile.TileGameObject.SetActive(obj.Visible);

                // Since Tiled 0.12, TileObjects' Bounds will have the desired width and height of the image, so scale accordingly
                if(obj.Bounds.width != 1 || obj.Bounds.height != 1)
                    objTile.TileGameObject.transform.localScale = new Vector3(obj.Bounds.width / objTile.TileSprite.bounds.size.x, obj.Bounds.height / objTile.TileSprite.bounds.size.y);

                return objTile.TileGameObject;
            }
            return null;
        }
 /// <summary>
 /// Adds a Box Collider 2D or 3D to an existing GameObject using one MapObject as properties source
 /// </summary>
 /// <param name="gameObject">GameObject to add a Box Collider</param>
 /// <param name="obj">MapObject which properties will be used to generate this collider.</param>
 /// <param name="isTrigger">True for Trigger Collider, false otherwise</param>
 /// <param name="zDepth">Z Depth of the collider.</param>
 /// <param name="colliderWidth">Width of the collider, in Units</param>
 /// <param name="used2DColider">True to generate a 2D collider, false to generate a 3D collider.</param>
 /// <param name="createRigidbody">True to attach a Rigidbody to the created collider</param>
 /// <param name="rigidbodyIsKinematic">Sets if the attached rigidbody is kinematic or not</param>
 public static void AddBoxCollider(Map map, GameObject gameObject, MapObject obj, bool used2DColider = true, bool isTrigger = false, float zDepth = 0, float colliderWidth = 1.0f, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
 {
     if (used2DColider)
         AddBoxCollider2D(map, gameObject, obj, isTrigger, null, zDepth, createRigidbody, rigidbodyIsKinematic);
     else
         AddBoxCollider3D(map, gameObject, obj, isTrigger, null, zDepth, colliderWidth, createRigidbody, rigidbodyIsKinematic);
 }
        /// <summary>
        /// Creates a Map Object Layer from node
        /// </summary>
        /// <param name="node">XML node to parse</param>
        /// <param name="tiledMap">MapObjectLayer parent Map</param>
        /// <param name="layerDepth">This Layer's zDepth</param>
        /// <param name="materials">List of Materials containing the TileSet textures</param>
        public MapObjectLayer(NanoXMLNode node, Map tiledMap, int layerDepth)
            : base(node, tiledMap)
        {
            if (node.GetAttribute("color") != null)
            {
                // get the color string, removing the leading #
                string color = node.GetAttribute("color").Value.Substring(1);

                // get the RGB individually
                string r = color.Substring(0, 2);
                string g = color.Substring(2, 2);
                string b = color.Substring(4, 2);

                // convert to the color
                Color = new Color(
                    (byte)int.Parse(r, NumberStyles.AllowHexSpecifier),
                    (byte)int.Parse(g, NumberStyles.AllowHexSpecifier),
                    (byte)int.Parse(b, NumberStyles.AllowHexSpecifier));
            }

            Objects = new List<MapObject>();

            foreach (NanoXMLNode objectNode in node.SubNodes)
            {
                if (!objectNode.Name.Equals("object"))
                    continue;

                MapObject mapObjectContent = new MapObject(objectNode, this);

                mapObjectContent = mapObjectContent.ScaleObject(tiledMap.MapRenderParameter) as MapObject;

                // Object names need to be unique for our lookup system, but Tiled
                // doesn't require unique names.
                string objectName = mapObjectContent.Name;
                int duplicateCount = 2;

                // if a object already has the same name...
                if (Objects.Find(o => o.Name.Equals(objectName)) != null)
                {
                    // figure out a object name that does work
                    do
                    {
                        objectName = string.Format("{0}{1}", mapObjectContent.Name, duplicateCount);
                        duplicateCount++;
                    } while (Objects.Find(o => o.Name.Equals(objectName)) != null);

                    // log a warning for the user to see
                    //Debug.LogWarning("Renaming object \"" + mapObjectContent.Name + "\" to \"" + objectName + "\" in layer \"" + Name + "\" to make a unique name.");

                    // save that name
                    mapObjectContent.Name = objectName;
                }
                //mapObjectContent.CreateTileObject(tiledMap, Name, layerDepth, materials);

                AddObject(mapObjectContent);
            }
        }
        void SetPlayerNewPosition(Map lastMap, Vector2 _doorFromPosition)
        {
            Vector2 fromDoorIndex = lastMap.WorldPointToTileIndex(_doorFromPosition);

            // Change door tile to opened door :P
            int originalID = lastMap.GetTileLayer("Layer 0").Tiles[fromDoorIndex.x, fromDoorIndex.y].OriginalID;
            lastMap.GetTileLayer("Layer 0").SetTile(fromDoorIndex.x, fromDoorIndex.y, originalID + 2);

            int lastMapWidth = lastMap.Width;
            int lastMapHeight = lastMap.Height;
            // Position player
            MapObjectLayer mol = _currentMap.GetObjectLayer("Doors");
            for (int i = 0; i < mol.Objects.Count; i++)
            {
                // This is a Left Door - X = 0
                if (mol.Objects[i].Bounds.x < 1)
                {
                    // And we came from a Right Door!
                    if (fromDoorIndex.x >= lastMapWidth - 1)
                    {
                        _player.transform.localPosition = _currentMap.TiledPositionToWorldPoint(1.5f, mol.Objects[i].Bounds.y + 0.5f);
                    }
                }
                // This is a Right Door - X = _currentMap.Width - 1
                if (mol.Objects[i].Bounds.x >= _currentMap.Width - 1)
                {
                    // And we came from a Left Door!
                    if (fromDoorIndex.x < 1)
                    {
                        _player.transform.localPosition = _currentMap.TiledPositionToWorldPoint(mol.Objects[i].Bounds.x - 1, mol.Objects[i].Bounds.y + 0.5f);
                    }
                }
                // This is an Up Door - Y = 0
                if (mol.Objects[i].Bounds.y < 1)
                {
                    // And we came from a Down Door!
                    if (fromDoorIndex.y >= lastMapHeight - 1)
                    {
                        _player.transform.localPosition = _currentMap.TiledPositionToWorldPoint(mol.Objects[i].Bounds.x + 0.5f, 1.4f);
                    }
                }
                // This is a Down Door - Y = _currentMap.Height - 1
                if (mol.Objects[i].Bounds.y >= _currentMap.Height - 1)
                {
                    // And we came from an Up Door!
                    if (fromDoorIndex.y < 1)
                    {
                        _player.transform.localPosition = _currentMap.TiledPositionToWorldPoint(mol.Objects[i].Bounds.x, mol.Objects[i].Bounds.y - 0.5f);
                    }
                }
            }

            _player.gameObject.GetComponent<X_UniTMX.Utils.SortingOrderAutoCalculator>().SetMap(_currentMap);
        }
        /// <summary>
        /// Adds a BoxCollider2D to a GameObject
        /// </summary>
        /// <param name="gameObject">GameObject to add the collider</param>
        /// <param name="obj">MapObject which properties will be used to generate this collider</param>
        /// <param name="isTrigger">True for Trigger Collider, false otherwise</param>
        /// <param name="physicsMaterial">PhysicsMaterial2D to be set to the collider</param>
        /// <param name="zDepth">Z Depth of the collider</param>
        /// <param name="createRigidbody">True to attach a Rigidbody to the created collider</param>
        /// <param name="rigidbodyIsKinematic">Sets if the attached rigidbody is kinematic or not</param>
        public static void AddBoxCollider2D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicsMaterial2D physicsMaterial = null, float zDepth = 0, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            // Orthogonal and Staggered maps can use BoxCollider, Isometric maps must use polygon collider
            if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric)
            {
                BoxCollider2D bx = gameObject.AddComponent<BoxCollider2D>();
                bx.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);
            #if UNITY_5
                bx.offset = new Vector2(obj.Bounds.width / 2.0f, -obj.Bounds.height / 2.0f);
            #else
                bx.center = new Vector2(obj.Bounds.width / 2.0f, -obj.Bounds.height / 2.0f);
            #endif
                bx.size = new Vector2(obj.Bounds.width, obj.Bounds.height);
                if (physicsMaterial != null)
                    bx.sharedMaterial = physicsMaterial;
            }
            else if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Isometric)
            {
                PolygonCollider2D pc = gameObject.AddComponent<PolygonCollider2D>();
                pc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);
                Vector2[] points = new Vector2[4];
                points[0] = map.TiledPositionToWorldPoint(obj.Bounds.xMin - obj.Bounds.x, obj.Bounds.yMax - obj.Bounds.y);
                points[1] = map.TiledPositionToWorldPoint(obj.Bounds.xMin - obj.Bounds.x, obj.Bounds.yMin - obj.Bounds.y);
                points[2] = map.TiledPositionToWorldPoint(obj.Bounds.xMax - obj.Bounds.x, obj.Bounds.yMin - obj.Bounds.y);
                points[3] = map.TiledPositionToWorldPoint(obj.Bounds.xMax - obj.Bounds.x, obj.Bounds.yMax - obj.Bounds.y);
                points[0].x -= map.MapRenderParameter.Width / 2.0f;
                points[1].x -= map.MapRenderParameter.Width / 2.0f;
                points[2].x -= map.MapRenderParameter.Width / 2.0f;
                points[3].x -= map.MapRenderParameter.Width / 2.0f;
                pc.SetPath(0, points);
                if (physicsMaterial != null)
                    pc.sharedMaterial = physicsMaterial;
            }

            if (createRigidbody)
            {
                Rigidbody2D r = gameObject.AddComponent<Rigidbody2D>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }
예제 #6
0
        /// <summary>
        /// Creates a Tile Layer from node
        /// </summary>
        /// <param name="node">XML node to parse</param>
        /// <param name="map">TileLayer parent Map</param>
        /// <param name="layerDepth">This Layer's zDepth</param>
        /// <param name="makeUnique">true to generate Unique Tiles</param>
        /// <param name="materials">List of Materials containing the TileSet textures</param>
        public TileLayer(NanoXMLNode node, Map map, int layerDepth, bool makeUnique, List<Material> materials)
            : base(node)
        {
            NanoXMLNode dataNode = node["data"];
            Data = new uint[Width * Height];
            LayerDepth = layerDepth;

            MakeUniqueTiles = makeUnique;

            // figure out what encoding is being used, if any, and process
            // the data appropriately
            if (dataNode.GetAttribute("encoding") != null)
            {
                string encoding = dataNode.GetAttribute("encoding").Value;

                if (encoding == "base64")
                {
                    ReadAsBase64(dataNode);
                }
                else if (encoding == "csv")
                {
                    ReadAsCsv(dataNode);
                }
                else
                {
                    throw new Exception("Unknown encoding: " + encoding);
                }
            }
            else
            {
                // XML format simply lays out a lot of <tile gid="X" /> nodes inside of data.

                int i = 0;
                foreach (NanoXMLNode tileNode in dataNode.SubNodes)
                {
                    if (tileNode.Name.Equals("tile"))
                    {
                        Data[i] = uint.Parse(tileNode.GetAttribute("gid").Value, CultureInfo.InvariantCulture);
                        i++;
                    }
                }

                if (i != Data.Length)
                    throw new Exception("Not enough tile nodes to fill data");
            }

            Initialize(map, Data, materials);
        }
        /// <summary>
        /// Creates an Image Layer from node
        /// </summary>
        /// <param name="node">XML node to parse</param>
        /// <param name="map">ImageLayer parent Map</param>
        /// <param name="mapPath">Map's directory path</param>
        /// <param name="baseMaterial">Material to use on this SpriteRenderer</param>
        public ImageLayer(NanoXMLNode node, Map map, string mapPath)
            : base(node, map)
        {
            NanoXMLNode imageNode = node["image"];
            this.Image = imageNode.GetAttribute("source").Value;

            if (node.GetAttribute("x") != null)
            {
                Position.x = float.Parse(node.GetAttribute("x").Value, NumberStyles.Float) / (float)map.MapRenderParameter.TileWidth;
            }
            if (node.GetAttribute("y") != null)
            {
                Position.y = -float.Parse(node.GetAttribute("y").Value, NumberStyles.Float) / (float)map.MapRenderParameter.TileHeight;
            }
            // if the image is in any director up from us, just take the filename
            //if (this.Image.StartsWith(".."))
            //	this.Image = Path.GetFileName(this.Image);

            if (imageNode.GetAttribute("trans") != null)
            {
                string color = imageNode.GetAttribute("trans").Value;
                string r = color.Substring(0, 2);
                string g = color.Substring(2, 2);
                string b = color.Substring(4, 2);
                this.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16));
            }

            SortingOrder = map.DefaultSortingOrder - LayerDepth;
            _ppu = map.MapRenderParameter.TileWidth;

            useWWWToLoad = map.UsingStreamingAssetsPath;

            string texturePath = mapPath;
            if (!useWWWToLoad)
            {
                texturePath = Utils.XUniTMXHelpers.ParsePath(mapPath, Image);
            }
            else
            {
                if (!texturePath.Contains("://"))
                    texturePath = "file://" + texturePath + Path.GetFileName(this.Image);
            }

            Image = texturePath;
        }
예제 #8
0
        public TileLayer(XmlNode node, Map map, float layerDepth, bool makeUnique, List<Material> materials)
            : base(node)
        {
            XmlNode dataNode = node["data"];
            Data = new uint[Width * Height];
            LayerDepth = layerDepth;
            Debug.Log("Layer Depth: " + LayerDepth);
            // figure out what encoding is being used, if any, and process
            // the data appropriately
            if (dataNode.Attributes["encoding"] != null)
            {
                string encoding = dataNode.Attributes["encoding"].Value;

                if (encoding == "base64")
                {
                    ReadAsBase64(node, dataNode);
                }
                else if (encoding == "csv")
                {
                    ReadAsCsv(node, dataNode);
                }
                else
                {
                    throw new Exception("Unknown encoding: " + encoding);
                }
            }
            else
            {
                // XML format simply lays out a lot of <tile gid="X" /> nodes inside of data.

                int i = 0;
                foreach (XmlNode tileNode in dataNode.SelectNodes("tile"))
                {
                    Data[i] = uint.Parse(tileNode.Attributes["gid"].Value, CultureInfo.InvariantCulture);
                    i++;
                }

                if (i != Data.Length)
                    throw new Exception("Not enough tile nodes to fill data");
            }

            Initialize(map, Data, makeUnique, materials);
        }
예제 #9
0
        public ImageLayer(XElement node, Map map, string mapPath, Material baseMaterial)
            : base(node)
        {
            XElement imageNode = node.Element("image");
            this.Image = imageNode.Attribute("source").Value;

            // if the image is in any director up from us, just take the filename
            if (this.Image.StartsWith(".."))
                this.Image = Path.GetFileName(this.Image);

            if (imageNode.Attribute("trans") != null)
            {
                string color = imageNode.Attribute("trans").Value;
                string r = color.Substring(0, 2);
                string g = color.Substring(2, 2);
                string b = color.Substring(4, 2);
                this.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16));
            }

            string texturePath = mapPath;
            if (Path.GetDirectoryName(this.Image).Length > 0)
                texturePath += Path.GetDirectoryName(this.Image) + Path.AltDirectorySeparatorChar;
            this.Texture = (Texture2D)Resources.Load(texturePath + Path.GetFileNameWithoutExtension(this.Image), typeof(Texture2D));

            LayerGameObject = new GameObject(Name);
            LayerGameObject.transform.parent = map.MapObject.transform;
            LayerGameObject.transform.localPosition = new Vector3(0, 0, this.LayerDepth);

            LayerGameObject.isStatic = true;
            LayerGameObject.SetActive(Visible);

            SpriteRenderer tileRenderer = LayerGameObject.AddComponent<SpriteRenderer>();
            tileRenderer.sprite = Sprite.Create(Texture, new Rect(0, 0, Texture.width, Texture.height), Vector2.up, map.TileWidth);
            tileRenderer.sprite.name = Texture.name;
            tileRenderer.sortingOrder = map.DefaultSortingOrder - LayerDepth;
            // Use Layer's name as Sorting Layer
            tileRenderer.sortingLayerName = this.Name;
            //tileRenderer.material = new Material(baseMaterial);
            //tileRenderer.material.mainTexture = Texture;
        }
        public void LoadMap(string map, Vector2 _doorFromPosition)
        {
            if (map.Equals(_currentMap.MapObject.name))
                return;

            Map lastMap = _currentMap;
            _currentMap.MapObject.SetActive(false);

            Map nextMap = null;
            // If map was already loaded, just enable its GameObject
            if (_loadedMaps.TryGetValue(map, out nextMap))
            {
                nextMap.MapObject.SetActive(true);
                _currentMap = nextMap;
            }
            else
            {
                // Else, load the map and generate its collisions
                for (int i = 0; i < _maps.Length; i++)
                {
                    if (_maps[i].name.Equals(map))
                    {
                        nextMap = new Map(_maps[i].text, map, _tiledMapComponent.MapTMXPath, _tiledMapComponent.gameObject, _tiledMapComponent.materialDefaultFile, _tiledMapComponent.DefaultSortingOrder, true);
                        nextMap.GenerateTileCollisions();
                        nextMap.GenerateCollidersFromLayer("WallColliders");
                        nextMap.GenerateCollidersFromLayer("Doors", true, true);
                        _loadedMaps.Add(map, nextMap);
                        _currentMap = nextMap;
                        break;
                    }
                }
            }
            if (nextMap == null)
                return;

            // Set the player's position on the new map
            SetPlayerNewPosition(lastMap, _doorFromPosition);
        }
예제 #11
0
        protected Layer(NanoXMLNode node, Map tileMap)
        {
            //string Type = node.Name;
            Name = node.GetAttribute("name").Value;
            if (string.IsNullOrEmpty(Name))
                Name = "Layer";

            if (node.GetAttribute("width") != null)
                Width = int.Parse(node.GetAttribute("width").Value, CultureInfo.InvariantCulture);
            else
                Width = 0;
            if (node.GetAttribute("height") != null)
                Height = int.Parse(node.GetAttribute("height").Value, CultureInfo.InvariantCulture);
            else
                Height = 0;

            if (node.GetAttribute("opacity") != null)
            {
                Opacity = float.Parse(node.GetAttribute("opacity").Value, CultureInfo.InvariantCulture);
            }
            else
                Opacity = 1;

            if (node.GetAttribute("visible") != null)
            {
                Visible = int.Parse(node.GetAttribute("visible").Value, CultureInfo.InvariantCulture) == 1;
            }
            else
                Visible = true;

            NanoXMLNode propertiesNode = node["properties"];
            if (propertiesNode != null)
            {
                Properties = new PropertyCollection(propertiesNode);
            }

            BaseMap = tileMap;
        }
        private static void ApproximateEllipse3D(Map map, GameObject newCollider, MapObject obj, bool isTrigger = false, PhysicMaterial physicsMaterial = null, float zDepth = 0, float colliderWidth = 1.0f, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            // since there's no "EllipseCollider", we must create one by approximating a polygon collider
            //newCollider.transform.localPosition = TiledPositionToWorldPoint(obj.Bounds.x, obj.Bounds.y, zDepth);

            Mesh colliderMesh = new Mesh();
            colliderMesh.name = "Collider_" + obj.Name;
            MeshCollider mc = newCollider.AddComponent<MeshCollider>();
            mc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

            int segments = XUniTMXConfiguration.Instance.EllipsoideColliderApproximationFactor;

            // Segments per quadrant
            int incFactor = Mathf.FloorToInt(segments / 4.0f);
            float minIncrement = 2 * Mathf.PI / (incFactor * segments / 2.0f);
            int currentInc = 0;
            bool grow = true;

            Vector2[] points = new Vector2[segments];

            float width = obj.Bounds.width;
            float height = obj.Bounds.height;

            Vector2 center = new Vector2(width / 2.0f, height / 2.0f);

            float r = 0;
            float angle = 0;
            for (int i = 0; i < segments; i++)
            {
                // Calculate radius at each point
                //angle = i * increment;
                angle += currentInc * minIncrement;
                r = width * height / Mathf.Sqrt(Mathf.Pow(height * Mathf.Cos(angle), 2) + Mathf.Pow(width * Mathf.Sin(angle), 2)) / 2.0f;
                points[i] = r * new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) + center;
                if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Staggered)
                    points[i].y *= -1;

                if (grow)
                    currentInc++;
                else
                    currentInc--;
                if (currentInc > incFactor - 1 || currentInc < 1)
                    grow = !grow;

                // POG :P
                if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric)
                {
                    if (i < 1 || i == segments / 2 - 1)
                        points[i].y += obj.Bounds.height / 20.0f;
                    if (i >= segments - 1 || i == segments / 2)
                        points[i].y -= obj.Bounds.height / 20.0f;
                }
            }

            List<Vector3> vertices = new List<Vector3>();
            List<int> triangles = new List<int>();

            GenerateVerticesAndTris(map, new List<Vector2>(points), vertices, triangles, zDepth, colliderWidth, false, !(map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Staggered));

            // Connect last point with first point (create the face between them)
            triangles.Add(vertices.Count - 1);
            triangles.Add(1);
            triangles.Add(0);

            triangles.Add(0);
            triangles.Add(vertices.Count - 2);
            triangles.Add(vertices.Count - 1);

            FillFaces(points, triangles);

            colliderMesh.vertices = vertices.ToArray();
            colliderMesh.uv = new Vector2[colliderMesh.vertices.Length];
            //colliderMesh.uv1 = colliderMesh.uv;
            colliderMesh.uv2 = colliderMesh.uv;
            colliderMesh.triangles = triangles.ToArray();
            colliderMesh.RecalculateNormals();

            mc.sharedMesh = colliderMesh;

            if (physicsMaterial != null)
                mc.sharedMaterial = physicsMaterial;
        }
예제 #13
0
        /*private GameObject GenerateSingleMesh(List<Vector3> vertices, Tile t)
        {
            GameObject obj = new GameObject();
            MeshFilter mfilter = obj.AddComponent<MeshFilter>();
            MeshRenderer mrender = obj.AddComponent<MeshRenderer>();

            Vector3 TopLeft = new Vector3(Mathf.Infinity, Mathf.NegativeInfinity, Mathf.Infinity);
            Vector3 TopRight = new Vector3(Mathf.NegativeInfinity, Mathf.NegativeInfinity, Mathf.Infinity);
            Vector3 BottomLeft = new Vector3(Mathf.Infinity, Mathf.Infinity, Mathf.Infinity);
            Vector3 BottomRight = new Vector3(Mathf.NegativeInfinity, Mathf.Infinity, Mathf.Infinity);

            foreach (Vector3 vertex in vertices)
            {
                if (vertex.x < TopLeft.x && -vertex.y > TopLeft.y)
                    TopLeft = vertex;
                if (vertex.x > TopRight.x && -vertex.y > TopRight.y)
                    TopRight = vertex;
                if (vertex.x < BottomLeft.x && -vertex.y < BottomLeft.y)
                    BottomLeft = vertex;
                if (vertex.x > BottomRight.x && -vertex.y < BottomRight.y)
                    BottomRight = vertex;
            }

            Debug.Log("TopLeft: " + TopLeft + "\nTopRight: " + TopRight + "\nBottomLeft: " + BottomLeft + "\nBottomRight: " + BottomRight);

            Mesh mesh = new Mesh();
            mesh.vertices = vertices.ToArray();

            float uTileWidth = (float)t.TileSet.TileWidth / (float)t.TileSet.Texture.width;
            float vTileHeight = (float)t.TileSet.TileHeight / (float)t.TileSet.Texture.height;
            float u = t.Source.x / (float)t.TileSet.Texture.width;
            float v = 1.0f - t.Source.y / (float)t.TileSet.Texture.height;
            mesh.uv = new Vector2[] {
                new Vector2(u + uTileWidth, v),
                new Vector2(u + uTileWidth, v - vTileHeight),
                new Vector2(u, v),
                new Vector2(u, v - vTileHeight)
            };
            mesh.triangles = new int[] {
                0, 1, 2,
                2, 1,  3,
            };
            mesh.RecalculateNormals();

            mfilter.mesh = mesh;
            Material mat = new Material(Shader.Find("Unlit/Transparent"));
            mat.mainTexture = t.TileSet.Texture;
            mrender.material = mat;

            return obj;
        }
        */
        // Renders the tile vertices.
        // Basically, it reads the tiles and creates its 4 vertexes (forming a rectangle or square according to settings)
        private void GenerateLayerMesh(Map map, List<Material> materials)
        {
            LayerGameObject = new GameObject(Name);//(GameObject)GameObject.Instantiate(Resources.Load("Tilemap"));//
            LayerGameObject.transform.position = new Vector3(0f,0f,0f);
            LayerMesh = new Mesh();

            LayerMeshFilter = (MeshFilter)LayerGameObject.AddComponent("MeshFilter");
            LayerMeshRenderer = (MeshRenderer)LayerGameObject.AddComponent("MeshRenderer");

            List<Vector3> vertices = new List<Vector3>();
            List<Vector2> uv = new List<Vector2>();
            List<int> triangles = new List<int>();
            List<Texture2D> textures = new List<Texture2D>();
            Tile t;
            /*List<GameObject> meshes = new List<GameObject>();
            Tile lastTile = null;
            int lastGID = -1;
            //int j = 0;
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    t = Tiles[i, j];
                    if (t != null)
                    {
                        Debug.Log(t.GID);
                        if (lastGID == t.GID)
                        {
                            vertices.AddRange(new Vector3[] {
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * -j, 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * (-j - 1), 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * -j, 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * (-j - 1), 0)
                            });
                            lastTile = t;
                        }
                        else
                        {
                            lastGID = t.GID;
                            if(vertices.Count > 0)
                                meshes.Add(GenerateSingleMesh(vertices, lastTile));
                            vertices.Clear();
                            vertices.AddRange(new Vector3[] {
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * -j, 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * (-j - 1), 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * -j, 0),
                                new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * (-j - 1), 0)
                            });
                            lastTile = t;
                        }
                    }

                    j++;
                }
            }

            CombineInstance[] combine = new CombineInstance[meshes.Count];
            List<Material> materials = new List<Material>();
            for (int i = 0; i < meshes.Count; i++)
            {
                combine[i].mesh = meshes[i].GetComponent<MeshFilter>().mesh;
                combine[i].transform = meshes[i].GetComponent<MeshFilter>().transform.localToWorldMatrix;
                materials.Add(meshes[i].GetComponent<MeshRenderer>().material);
            }

            LayerMesh.CombineMeshes(combine);
            LayerMeshFilter.mesh = LayerMesh;
            LayerMeshRenderer.materials = materials.ToArray();
            */

            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    t = Tiles[i, j];
                    if(t != null) {

                        // Add Tile's vertices to layer's mesh
                        vertices.AddRange(new Vector3[] {
                            new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * -j, 0),
                            new Vector3 (t.Source.width / t.TileSet.TileWidth * (i + 1), t.Source.height / t.TileSet.TileHeight * (-j - 1), 0),
                            new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * -j, 0),
                            new Vector3 (t.Source.width / t.TileSet.TileWidth * i, t.Source.height / t.TileSet.TileHeight * (-j - 1), 0)
                        });
                        // Generate this Tile's Triangles on Layer's mesh
                        triangles.AddRange(new int[] {
                            VertexCount, VertexCount + 1, VertexCount + 2,
                            VertexCount + 2, VertexCount + 1, VertexCount + 3,
                        });

                        VertexCount += 4;

                        // Add Tile's texture source to textures list, to create the materials
                        if (textures.Find(text => text.name == t.TileSet.Texture.name) == null)
                            textures.Add(t.TileSet.Texture);

                        // Save UV mapping of this Tile on it's texture
                        //Debug.Log(t.Source);
                        float uTileWidth = (float)t.TileSet.TileWidth / (float)t.TileSet.Texture.width;
                        float vTileHeight = (float)t.TileSet.TileHeight / (float)t.TileSet.Texture.height;
                        //float uBorderWidth = (float)t.TileSet.Spacing / t.TileSet.Texture.width;
                        //float vBorderHeight = (float)t.TileSet.Spacing / t.TileSet.Texture.height;
                        float u = t.Source.x / (float)t.TileSet.Texture.width;//(uTileWidth + uBorderWidth) * t.Source.x + uBorderWidth / 2;
                        float v = 1.0f - t.Source.y / (float)t.TileSet.Texture.height;//1.0f - (vTileHeight - vBorderHeight) * t.Source.y - vBorderHeight / 2;
                        uv.AddRange(new Vector2[] {
                            new Vector2(u + uTileWidth, v),
                            new Vector2(u + uTileWidth, v - vTileHeight),
                            new Vector2(u, v),
                            new Vector2(u, v - vTileHeight)
                        });
                    }
                }
            }
            //t = null;
            LayerMesh.vertices = vertices.ToArray();
            LayerMesh.uv = uv.ToArray();
            LayerMesh.triangles = triangles.ToArray();
            LayerMesh.RecalculateNormals();

            LayerMeshFilter.mesh = LayerMesh;
            List<Material> layerMaterials = new List<Material>();
            // Generate Materials
            for (int i = 0; i < textures.Count; i++)
            {
                //Material layerMat = new Material(Shader.Find("Unlit/Transparent"));
                //layerMat.mainTexture = textures[i];
                //materials.Add(layerMat);
                for (int j = 0; j < materials.Count; j++)
                {
                    if (materials[j].mainTexture.name == textures[i].name)
                        layerMaterials.Add(materials[j]);
                }
            }
            LayerMeshRenderer.sharedMaterials = layerMaterials.ToArray();

            LayerGameObject.transform.parent = map.Parent.transform;
            LayerGameObject.transform.position = new Vector3(0, 0, this.LayerDepth);
            Debug.Log(LayerGameObject.name + LayerGameObject.transform.position);
            LayerGameObject.isStatic = true;
        }
예제 #14
0
        /// <summary>
        /// Creates a map object layer from .tmx
        /// </summary>
        /// <param name="node"></param>
        public MapObjectLayer(XElement node, Map tiledMap, int layerDepth, List<Material> materials)
            : base(node)
        {
            if (node.Attribute("color") != null)
            {
                // get the color string, removing the leading #
                string color = node.Attribute("color").Value.Substring(1);

                // get the RGB individually
                string r = color.Substring(0, 2);
                string g = color.Substring(2, 2);
                string b = color.Substring(4, 2);

                // convert to the color
                Color = new Color(
                    (byte)int.Parse(r, NumberStyles.AllowHexSpecifier),
                    (byte)int.Parse(g, NumberStyles.AllowHexSpecifier),
                    (byte)int.Parse(b, NumberStyles.AllowHexSpecifier));
            }

            Objects = new List<MapObject>();

            foreach (XElement objectNode in node.Descendants("object"))
            {
                MapObject mapObjectContent = new MapObject(objectNode);
                //if (tiledMap.Orientation == Orientation.Orthogonal)
                //{
                //	mapObjectContent.ScaleObject(tiledMap.TileWidth, tiledMap.TileHeight);
                //}
                //// In Isometric maps, we must consider tile width == height for objects so their size can be correctly calculated
                //else if (tiledMap.Orientation == Orientation.Isometric)
                //{
                //	mapObjectContent.ScaleObject(tiledMap.TileHeight, tiledMap.TileHeight);
                //}
                //// In Staggered maps, we must pre-alter object position, as it comes mixed between staggered and orthogonal properties
                //else if (tiledMap.Orientation == Orientation.Staggered)
                //{
                //	float x = mapObjectContent.Bounds.x / (float)tiledMap.TileWidth;
                //	float y = mapObjectContent.Bounds.y / (float)tiledMap.TileHeight * 2.0f;
                //	float width = mapObjectContent.Bounds.width / (float)tiledMap.TileWidth;
                //	float height = mapObjectContent.Bounds.height / (float)tiledMap.TileWidth;

                //	if (Mathf.FloorToInt(Mathf.Abs(y)) % 2 > 0)
                //		x -= 0.5f;

                //	mapObjectContent.Bounds = new Rect(x, y, width, height);

                //	if (mapObjectContent.Points != null)
                //	{
                //		for (int i = 0; i < mapObjectContent.Points.Count; i++)
                //		{
                //			mapObjectContent.Points[i] = new Vector2(mapObjectContent.Points[i].x / (float)tiledMap.TileWidth, mapObjectContent.Points[i].y / (float)tiledMap.TileHeight * 2.0f);
                //		}
                //	}
                //}
                mapObjectContent.ScaleObject(tiledMap.TileWidth, tiledMap.TileHeight, tiledMap.Orientation);
                mapObjectContent.Name = this.Name + "_" + mapObjectContent.Name;
                // Object names need to be unique for our lookup system, but Tiled
                // doesn't require unique names.
                string objectName = mapObjectContent.Name;
                int duplicateCount = 2;

                // if a object already has the same name...
                if (Objects.Find(o => o.Name.Equals(objectName)) != null)
                {
                    // figure out a object name that does work
                    do
                    {
                        objectName = string.Format("{0}{1}", mapObjectContent.Name, duplicateCount);
                        duplicateCount++;
                    } while (Objects.Find(o => o.Name.Equals(objectName)) != null);

                    // log a warning for the user to see
                    Debug.Log("Renaming object \"" + mapObjectContent.Name + "\" to \"" + objectName + "\" in layer \"" + Name + "\" to make a unique name.");

                    // save that name
                    mapObjectContent.Name = objectName;
                }
                mapObjectContent.CreateTileObject(tiledMap, Name, layerDepth, materials);

                AddObject(mapObjectContent);
            }
        }
        public static void AddPolylineCollider3D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicMaterial physicsMaterial = null, float zDepth = 0, float colliderWidth = 1.0f, bool innerCollision = false, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            Mesh colliderMesh = new Mesh();
            colliderMesh.name = "Collider_" + obj.Name;
            MeshCollider mc = gameObject.AddComponent<MeshCollider>();

            mc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

            List<Vector3> vertices = new List<Vector3>();
            List<int> triangles = new List<int>();

            GenerateVerticesAndTris(map, obj.Points, vertices, triangles, zDepth, colliderWidth, innerCollision);

            colliderMesh.vertices = vertices.ToArray();
            colliderMesh.uv = new Vector2[colliderMesh.vertices.Length];
            //colliderMesh.uv1 = colliderMesh.uv;
            colliderMesh.uv2 = colliderMesh.uv;
            colliderMesh.triangles = triangles.ToArray();
            colliderMesh.RecalculateNormals();

            mc.sharedMesh = colliderMesh;

            if (physicsMaterial != null)
                mc.sharedMaterial = physicsMaterial;

            if (createRigidbody)
            {
                Rigidbody r = gameObject.AddComponent<Rigidbody>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            if (obj.GetPropertyAsBoolean(Map.Property_CreateMesh))
            {
                if (gameObject.GetComponent<MeshFilter>() == null)
                    gameObject.AddComponent<MeshFilter>();

                if (gameObject.GetComponent<MeshRenderer>() == null)
                    gameObject.AddComponent<MeshRenderer>();

                MeshFilter _meshFilter = gameObject.GetComponent<MeshFilter>();
                if (mc != null)
                {
                    mc.sharedMesh.RecalculateBounds();
                    mc.sharedMesh.RecalculateNormals();
                    MathfExtensions.CalculateMeshTangents(mc.sharedMesh);
                    _meshFilter.sharedMesh = mc.sharedMesh;
                }
            }
            ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }
        public static void AddPolylineCollider2D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicsMaterial2D physicsMaterial = null, float zDepth = 0, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            EdgeCollider2D edgeCollider = gameObject.AddComponent<EdgeCollider2D>();

            edgeCollider.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

            Vector2[] points = obj.Points.ToArray();

            for (int i = 0; i < points.Length; i++)
            {
                points[i] = map.TiledPositionToWorldPoint(points[i].x, points[i].y);
                if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Isometric)
                    points[i].x -= map.MapRenderParameter.Width / 2.0f;
            }

            edgeCollider.points = points;
            if (physicsMaterial != null)
                edgeCollider.sharedMaterial = physicsMaterial;

            if (createRigidbody)
            {
                Rigidbody2D r = gameObject.AddComponent<Rigidbody2D>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }
        public static void AddEllipseCollider3D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicMaterial physicsMaterial = null, float zDepth = 0, float colliderWidth = 1.0f, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            GameObject gameObjectMesh = null;
            if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric && obj.Bounds.width == obj.Bounds.height)
            {
                CapsuleCollider cc = null;
                if (obj.GetPropertyAsBoolean(Map.Property_CreateMesh))
                {
                    gameObjectMesh = GameObject.CreatePrimitive(PrimitiveType.Capsule);
                    gameObjectMesh.name = obj.Name;
                    gameObjectMesh.transform.parent = gameObject.transform;
                    gameObjectMesh.transform.localPosition = new Vector3(obj.Bounds.height / 2.0f, -obj.Bounds.width / 2.0f);

                    cc = gameObjectMesh.GetComponent<CapsuleCollider>();
                    cc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);
                    gameObjectMesh.transform.localScale = new Vector3(obj.Bounds.width, colliderWidth, obj.Bounds.height);
                    gameObjectMesh.transform.localRotation = Quaternion.AngleAxis(90, Vector3.right);
                }
                else
                {
                    cc = gameObject.AddComponent<CapsuleCollider>();

                    cc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

                    cc.center = new Vector3(obj.Bounds.height / 2.0f, -obj.Bounds.width / 2.0f);

                    cc.direction = 0;
                    cc.radius = obj.Bounds.height / 2.0f;
                    cc.height = obj.Bounds.width;
                }
                if (physicsMaterial != null)
                    cc.sharedMaterial = physicsMaterial;
            }
            else
            {
                ApproximateEllipse3D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, colliderWidth, createRigidbody, rigidbodyIsKinematic);
            }

            if (createRigidbody)
            {
                Rigidbody r = gameObject.AddComponent<Rigidbody>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            if (gameObjectMesh)
                ApplyCustomProperties(gameObjectMesh, obj);
            else
                ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }
        // Callback for when the map has been loaded.
        void OnMapLoaded(Map map)
        {
            // Set the loaded map
            tiledMap = map;

            /*
             * Generate the map with the following options:
             *
             * TileManager's GameObject is the parent in the hierarchy
             * The default material is the default sprite's material
             */
            tiledMap.Generate(this.gameObject, defaultMaterial);

            // Generate any tile collisions
            tiledMap.GenerateTileCollisions();

            MapObjectLayer resourcesObjectLayer;    // The object layer for resources

            // Check if the map has a resources object layer
            if ((resourcesObjectLayer = tiledMap.GetObjectLayer("Resources")) != null)
            {
                // Get the list of MapObjects on the resources layer
                List<MapObject> resourceObjects = resourcesObjectLayer.Objects;

                // Check if the game is new
                if (GameMaster.Instance.IsNew)
                {
                    // The game is new so add all the resources to the list
                    foreach (var resource in resourceObjects)
                    {
                        resourcePositions.Add(ToMap(resource.Bounds));
                    } // end foreach

                    // Finally, save the resource positions list
                    GameMaster.Instance.SaveResources();
                } // end if
                else
                {
                    // The game isn't new so load all the saved resources
                    resourcePositions = GameMaster.Instance.LoadResources();
                } // end else

                // Loop through the objects to check if they're on the resources list
                foreach (var resource in resourceObjects)
                {
                    // Make sure the resource is in the list
                    if (resourcePositions.Contains(ToMap(resource.Bounds)))
                    {
                        // Generate the prefab for the resource
                        tiledMap.GeneratePrefab(resource, Vector2.zero, null, false, true);
                    } // end if
                } // end foreach
            } // end if

            // Check if the map has a markets object layer
            if (tiledMap.GetObjectLayer("Markets") != null)
            {
                // Get the list of MapObjects on the markets layer
                List<MapObject> marketObjects = tiledMap.GetObjectLayer("Markets").Objects;

                // Add all the markets to the list
                foreach (var market in marketObjects)
                {
                    marketPositions.Add(ToMap(market.Bounds));
                } // end foreach

                // Generate the colliders from this layer
                tiledMap.GenerateCollidersFromLayer("Markets");
                // Generate the prefabs from this layer
                tiledMap.GeneratePrefabsFromLayer("Markets", Vector2.zero, false, true);
            } // end if

            // Finally, Update the TileUtils static class
            SetDimensions(tiledMap.MapRenderParameter.TileHeight, tiledMap.MapRenderParameter.Width,
                tiledMap.MapRenderParameter.Height);
        }
예제 #19
0
 void OnGenerateFinished(Map map)
 {
     tiledMap = map;
     Resources.UnloadUnusedAssets();
     GenerateColliders();
     GeneratePrefabs();
     if (OnTiledMapInitialized != null)
         OnTiledMapInitialized();
 }
예제 #20
0
        // Renders the tile vertices.
        // Basically, it reads the tiles and creates its 4 vertexes (forming a rectangle or square according to settings)
        private void GenerateLayer(Map map, List<Material> materials)
        {
            LayerGameObject = new GameObject(Name);
            Tile t;

            // We must create tiles in reverse order so Z order is correct according to the majority of tilesets
            for (int x = Width - 1; x > -1; x--)
            {
                for (int y = Height - 1; y > -1; y--)
                {
                    t = Tiles[x, y];
                    if(t != null) {
                        Vector3 pos = Vector3.zero;
                        // Set Tile's position according to map orientation
                        // Can't use Map.TiledPositionToWorldPoint as sprites' anchors doesn't follow tile anchor point
                        if (map.Orientation == Orientation.Orthogonal)
                        {
                            pos = new Vector3(
                                x * (map.TileWidth / (float)t.TileSet.TileWidth),
                                (-y - 1) * (map.TileHeight / (float)t.TileSet.TileHeight) * ((float)t.TileSet.TileHeight / (float)t.TileSet.TileWidth),
                                0);
                        }
                        else if (map.Orientation == Orientation.Isometric)
                        {
                            pos = new Vector3(
                                (map.TileWidth / 2.0f * (map.Width - y + x) - t.TileSet.TileWidth / 2.0f) / (float)map.TileWidth,
                                -map.Height + map.TileHeight * (map.Height - ((x + y) / (map.TileWidth / (float)map.TileHeight)) / 2.0f) / (float)map.TileHeight - (map.TileHeight / (float)map.TileWidth),
                                0);
                        }
                        else if (map.Orientation == Orientation.Staggered)
                        {
                            // In Staggered maps, odd rows and even rows are handled differently
                            if (y % 2 < 1)
                            {
                                // Even row
                                pos.x = x * (map.TileWidth / (float)t.TileSet.TileWidth);
                                pos.y = (-y - 2) * (map.TileHeight / 2.0f / (float)t.TileSet.TileHeight) * ((float)t.TileSet.TileHeight / (float)t.TileSet.TileWidth);
                            }
                            else
                            {
                                // Odd row
                                pos.x = x * (map.TileWidth / (float)t.TileSet.TileWidth) + (map.TileWidth / (float)t.TileSet.TileWidth) / 2.0f;
                                pos.y = (-y - 2) * (map.TileHeight / 2.0f / (float)t.TileSet.TileHeight) * ((float)t.TileSet.TileHeight / (float)t.TileSet.TileWidth);
                            }
                        }

                        // Create Tile's GameObject
                        t.CreateTileObject(Name + "[" + x + ", " + y + "]",
                            LayerGameObject.transform,
                            Name,
                            pos,
                            materials,
                            Opacity);

                    }
                }
            }

            LayerGameObject.transform.parent = map.MapObject.transform;
            LayerGameObject.transform.localPosition = new Vector3(0, 0, this.LayerDepth);
            LayerGameObject.isStatic = true;
            LayerGameObject.SetActive(Visible);
        }
        private static void ApproximateEllipse2D(Map map, GameObject newCollider, MapObject obj, bool isTrigger = false, PhysicsMaterial2D physicsMaterial = null, float zDepth = 0, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            // since there's no "EllipseCollider2D", we must create one by approximating a polygon collider
            newCollider.transform.localPosition = map.TiledPositionToWorldPoint(obj.Bounds.x, obj.Bounds.y, zDepth);

            PolygonCollider2D polygonCollider = newCollider.AddComponent<PolygonCollider2D>();

            polygonCollider.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

            int segments = XUniTMXConfiguration.Instance.EllipsoideColliderApproximationFactor;

            // Segments per quadrant
            int incFactor = Mathf.FloorToInt(segments / 4.0f);
            float minIncrement = 2 * Mathf.PI / (incFactor * segments / 2.0f);
            int currentInc = 0;
            // grow represents if we are going right on x-axis (true) or left (false)
            bool grow = true;

            Vector2[] points = new Vector2[segments];
            // Ellipsoide center
            Vector2 center = new Vector2(obj.Bounds.width / 2.0f, obj.Bounds.height / 2.0f);

            float r = 0;
            float angle = 0;
            for (int i = 0; i < segments; i++)
            {
                // Calculate radius at each point
                angle += currentInc * minIncrement;

                r = obj.Bounds.width * obj.Bounds.height / Mathf.Sqrt(Mathf.Pow(obj.Bounds.height * Mathf.Cos(angle), 2) + Mathf.Pow(obj.Bounds.width * Mathf.Sin(angle), 2)) / 2.0f;
                // Define the point localization using the calculated radius, angle and center
                points[i] = r * new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) + center;

                points[i] = map.TiledPositionToWorldPoint(points[i].x, points[i].y);

                // Offset points where needed
                if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Isometric)
                    points[i].x -= map.MapRenderParameter.Width / 2.0f;
                if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Staggered)
                    points[i].y *= map.MapRenderParameter.TileWidth / (float)map.MapRenderParameter.TileHeight * 2.0f;
                if (map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Hexagonal)
                {
                    points[i].y *= map.MapRenderParameter.TileWidth / (float)map.MapRenderParameter.TileHeight * 2.0f;
                }

                // if we are "growing", increment the angle, else, start decrementing it to close the polygon
                if (grow)
                    currentInc++;
                else
                    currentInc--;
                if (currentInc > incFactor - 1 || currentInc < 1)
                    grow = !grow;

                // POG :P -> Orthogonal and Staggered Isometric generated points are slightly offset on Y
                if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric)
                {
                    if (i < 1 || i == segments / 2 - 1)
                        points[i].y -= obj.Bounds.height / 20.0f;
                    if (i >= segments - 1 || i == segments / 2)
                        points[i].y += obj.Bounds.height / 20.0f;
                }
            }

            polygonCollider.SetPath(0, points);

            if (physicsMaterial != null)
                polygonCollider.sharedMaterial = physicsMaterial;
        }
 public static void AddCollider3D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicMaterial physicsMaterial = null, float zDepth = 0, float colliderWidth = 1, bool innerCollision = false, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
 {
     switch (obj.ObjectType)
     {
         case ObjectType.Box:
             AddBoxCollider3D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, colliderWidth, createRigidbody, rigidbodyIsKinematic);
             break;
         case ObjectType.Ellipse:
             AddEllipseCollider3D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, colliderWidth, createRigidbody, rigidbodyIsKinematic);
             break;
         case ObjectType.Polygon:
             AddPolygonCollider3D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, colliderWidth, innerCollision, createRigidbody, rigidbodyIsKinematic);
             break;
         case ObjectType.Polyline:
             AddPolylineCollider3D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, colliderWidth, innerCollision, createRigidbody, rigidbodyIsKinematic);
             break;
     }
 }
        /// <summary>
        /// Adds a 3D BoxCollider to a GameObject
        /// </summary>
        /// <param name="gameObject">GameObject to add the collider</param>
        /// <param name="obj">MapObject which properties will be used to generate this collider</param>
        /// <param name="isTrigger">True for Trigger Collider, false otherwise</param>
        /// <param name="physicsMaterial">PhysicMaterial to be set to the collider</param>
        /// <param name="zDepth">Z Depth of the collider</param>
        /// <param name="colliderWidth">Width of the collider, in Units</param>
        /// <param name="createRigidbody">True to attach a Rigidbody to the created collider</param>
        /// <param name="rigidbodyIsKinematic">Sets if the attached rigidbody is kinematic or not</param>
        public static void AddBoxCollider3D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicMaterial physicsMaterial = null, float zDepth = 0, float colliderWidth = 1.0f, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            GameObject gameObjectMesh = null;
            // Orthogonal and Staggered maps can use BoxCollider, Isometric maps must use polygon collider
            if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric)
            {
                BoxCollider boxCollider = null;
                if (obj.GetPropertyAsBoolean(Map.Property_CreateMesh))
                {
                    gameObjectMesh = GameObject.CreatePrimitive(PrimitiveType.Cube);
                    gameObjectMesh.name = obj.Name;
                    gameObjectMesh.transform.parent = gameObject.transform;
                    gameObjectMesh.transform.localPosition = new Vector3(0.5f, -0.5f);
                    boxCollider = gameObjectMesh.GetComponent<BoxCollider>();
                }
                else
                {
                    boxCollider = gameObject.AddComponent<BoxCollider>();
                    boxCollider.center = new Vector3(0.5f, -0.5f);
                }
                boxCollider.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

                if (physicsMaterial != null)
                    boxCollider.sharedMaterial = physicsMaterial;

                gameObject.transform.localScale = new Vector3(obj.Bounds.width, obj.Bounds.height, colliderWidth);
            }
            else
            {
                List<Vector2> points = new List<Vector2>();
                points.Add(new Vector2(obj.Bounds.xMin - obj.Bounds.x, obj.Bounds.yMax - obj.Bounds.y));
                points.Add(new Vector2(obj.Bounds.xMin - obj.Bounds.x, obj.Bounds.yMin - obj.Bounds.y));
                points.Add(new Vector2(obj.Bounds.xMax - obj.Bounds.x, obj.Bounds.yMin - obj.Bounds.y));
                points.Add(new Vector2(obj.Bounds.xMax - obj.Bounds.x, obj.Bounds.yMax - obj.Bounds.y));
                X_UniTMX.MapObject isoBox = new MapObject(obj.Name, obj.Type, obj.Bounds, obj.Properties, obj.GID, points, obj.Rotation, obj.ParentObjectLayer);

                AddPolygonCollider3D(map, gameObject, isoBox, isTrigger, physicsMaterial, zDepth, colliderWidth);
                //gameObject = GeneratePolygonCollider3D(isoBox, isTrigger, zDepth, colliderWidth);
            }

            if (createRigidbody)
            {
                Rigidbody r = gameObject.AddComponent<Rigidbody>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            if (gameObjectMesh != null)
                ApplyCustomProperties(gameObjectMesh, obj);
            else
                ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }
예제 #24
0
        /// <summary>
        /// Creates this Tile Object (an object that has GID) if applicable
        /// </summary>
        /// <param name="tiledMap">The base Tile Map</param>
        public void CreateTileObject(Map tiledMap, string sortingLayerName, int layerDepth, List<Material> materials)
        {
            if(GID > 0) {
                Tile objTile = tiledMap.Tiles[GID].Clone();
                objTile.CreateTileObject(Name,
                    tiledMap.MapObject.transform,
                    sortingLayerName,
                    new Vector3(Bounds.x, -Bounds.y, layerDepth),
                    materials);

                objTile.TileObject.SetActive(Visible);
            }
        }
예제 #25
0
        private void Initialize(Map map, uint[] data, bool makeUnique, List<Material> materials)
        {
            Tiles = new TileGrid(Width, Height);

            // data is left-to-right, top-to-bottom
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    uint index = data[y * Width + x];

                    // compute the SpriteEffects to apply to this tile
                    SpriteEffects spriteEffects = SpriteEffects.None;
                    if ((index & FlippedHorizontallyFlag) != 0)
                        spriteEffects |= SpriteEffects.FlipHorizontally;
                    if ((index & FlippedVerticallyFlag) != 0)
                        spriteEffects |= SpriteEffects.FlipVertically;

                    // strip out the flip flags to get the real ID
                    int id = (int)(index & ~(FlippedVerticallyFlag | FlippedHorizontallyFlag));
                    //Debug.Log("Tile ID: " + id + " (index : " + index + ")");
                    // get the tile
                    Tile t = null;
                    map.Tiles.TryGetValue(id, out t);

                    // if the tile is non-null...
                    if (t != null)
                    {
                        // if we want unique instances, clone it
                        if (makeUnique)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }

                        // otherwise we may need to clone if the tile doesn't have the correct effects
                        // in this world a flipped tile is different than a non-flipped one; just because
                        // they have the same source rect doesn't mean they're equal.
                        else if (t.SpriteEffects != spriteEffects)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }
                    }

                    // put that tile in our grid
                    Tiles[x, y] = t;
                }
            }

            GenerateLayer(map, materials);
        }
 private static void CreateFrontBackPoints(Map map, Vector3 refPoint, out Vector3 refFront, out Vector3 refBack, float zDepth, float colliderWidth, bool calculateWorldPos = true, bool ignoreOrientation = false)
 {
     if (calculateWorldPos)
     {
         refFront = map.TiledPositionToWorldPoint(refPoint.x, refPoint.y, zDepth - colliderWidth / 2.0f);
         refBack = map.TiledPositionToWorldPoint(refPoint.x, refPoint.y, zDepth + colliderWidth / 2.0f);
     }
     else
     {
         refFront = new Vector3(refPoint.x, refPoint.y, zDepth - colliderWidth / 2.0f);
         refBack = new Vector3(refPoint.x, refPoint.y, zDepth + colliderWidth / 2.0f);
     }
     if (!ignoreOrientation && map.MapRenderParameter.Orientation == X_UniTMX.Orientation.Isometric)
     {
         refFront.x -= map.MapRenderParameter.Width / 2.0f;
         refBack.x -= map.MapRenderParameter.Width / 2.0f;
     }
 }
예제 #27
0
        private void Initialize(Map map, uint[] data, List<Material> materials)
        {
            Tiles = new TileGrid(Width, Height);
            BaseMap = map;
            BaseMaterials = materials;
            LayerTileSets = new List<TileSet>();
            // data is left-to-right, top-to-bottom
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    uint id = data[y * Width + x];

                    // compute the SpriteEffects to apply to this tile
                    SpriteEffects spriteEffects = new SpriteEffects();

                    // MARIO: new method to verify flipped tiles
                    spriteEffects.flippedHorizontally = (id & FlippedHorizontallyFlag) == FlippedHorizontallyFlag;
                    spriteEffects.flippedVertically = (id & FlippedVerticallyFlag) == FlippedVerticallyFlag;
                    spriteEffects.flippedAntiDiagonally = (id & FlippedAntiDiagonallyFlag) == FlippedAntiDiagonallyFlag;

                    // MARIO: new strip out the flip flags to get the real ID
                    // Fixed for AntiDiagonallyFlgs
                    id &= ~(FlippedHorizontallyFlag |
                            FlippedVerticallyFlag |
                            FlippedAntiDiagonallyFlag);

                    // get the tile
                    Tile t = null;
                    BaseMap.Tiles.TryGetValue((int)id, out t);

                    // if the tile is non-null...
                    if (t != null)
                    {
                        // if we want unique instances, clone it
                        if (MakeUniqueTiles)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }

                        // otherwise we may need to clone if the tile doesn't have the correct effects
                        // in this world a flipped tile is different than a non-flipped one; just because
                        // they have the same source rect doesn't mean they're equal.
                        else if (t.SpriteEffects != spriteEffects)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }

                        // Add this Tile's TileSet to LayerTileSets list, if it is not there yet
                        if (!LayerTileSets.Contains(t.TileSet))
                            LayerTileSets.Add(t.TileSet);
                    }

                    // put that tile in our grid
                    Tiles[x, y] = t;
                }
            }

            GenerateLayer();
        }
        private static void GenerateVerticesAndTris(Map map, List<Vector2> points, List<Vector3> generatedVertices, List<int> generatedTriangles, float zDepth = 0, float colliderWidth = 1.0f, bool innerCollision = false, bool calculateWorldPos = true, bool ignoreOrientation = false)
        {
            Vector3 firstPoint = (Vector3)points[0];
            Vector3
                firstFront = Vector3.zero,
                firstBack = Vector3.zero,
                secondPoint = Vector3.zero,
                secondFront = Vector3.zero,
                secondBack = Vector3.zero;

            CreateFrontBackPoints(map, firstPoint, out firstFront, out firstBack, zDepth, colliderWidth, calculateWorldPos, ignoreOrientation);

            if (innerCollision)
            {
                generatedVertices.Add(firstBack); // 3
                generatedVertices.Add(firstFront); // 2
            }
            else
            {
                generatedVertices.Add(firstFront); // 3
                generatedVertices.Add(firstBack); // 2
            }

            // Calculate line planes
            for (int i = 1; i < points.Count; i++)
            {
                secondPoint = (Vector3)points[i];
                CreateFrontBackPoints(map, secondPoint, out secondFront, out secondBack, zDepth, colliderWidth, calculateWorldPos, ignoreOrientation);

                if (innerCollision)
                {
                    generatedVertices.Add(secondBack); // 1
                    generatedVertices.Add(secondFront); // 0
                }
                else
                {
                    generatedVertices.Add(secondFront); // 1
                    generatedVertices.Add(secondBack); // 0
                }

                generatedTriangles.Add((i - 1) * 2 + 3);
                generatedTriangles.Add((i - 1) * 2 + 2);
                generatedTriangles.Add((i - 1) * 2 + 0);

                generatedTriangles.Add((i - 1) * 2 + 0);
                generatedTriangles.Add((i - 1) * 2 + 1);
                generatedTriangles.Add((i - 1) * 2 + 3);

                firstPoint = secondPoint;
                firstFront = secondFront;
                firstBack = secondBack;
            }
        }
예제 #29
0
        /// <summary>
        /// Creates this Tile Object (an object that has OriginalID) if applicable
        /// </summary>
        /// <param name="tiledMap">The base Tile Map</param>
        /// <param name="layerDepth">Layer's zDepth</param>
        /// <param name="sortingLayerName">Layer's SortingLayerName</param>
        /// <param name="parent">Transform to parent this object to</param>
        /// <param name="materials">List of TileSet Materials</param>
        public void CreateTileObject(Map tiledMap, string sortingLayerName, int layerDepth, List<Material> materials, Transform parent = null)
        {
            if(GID > 0) {
                Tile objTile = null;
                if(tiledMap.Orientation != Orientation.Orthogonal)
                    objTile = tiledMap.Tiles[GID].Clone(new Vector2(0.5f, 0.5f));
                else
                    objTile = tiledMap.Tiles[GID].Clone();

                //string sortingLayer = GetPropertyAsString("SortingLayer");
                //int sortingOrder = GetPropertyAsInt("SortingOrder");

                objTile.CreateTileObject(Name,
                    parent != null ? parent : ParentObjectLayer.LayerGameObject.transform,
                    sortingLayerName,
                    tiledMap.DefaultSortingOrder + tiledMap.GetSortingOrder(Bounds.x, Bounds.y),
                    tiledMap.TiledPositionToWorldPoint(Bounds.x, Bounds.y, layerDepth),
                    materials);
                this.Bounds = new Rect(Bounds.x, Bounds.y - 1, 1, 1);
                /*Debug.Log(Bounds);
                tiledMap.AddBoxCollider(objTile.TileGameObject, this);*/
                objTile.TileGameObject.SetActive(Visible);
            }
        }
        public static void AddEllipseCollider2D(Map map, GameObject gameObject, MapObject obj, bool isTrigger = false, PhysicsMaterial2D physicsMaterial = null, float zDepth = 0, bool createRigidbody = false, bool rigidbodyIsKinematic = true)
        {
            if (map.MapRenderParameter.Orientation != X_UniTMX.Orientation.Isometric && obj.Bounds.width == obj.Bounds.height)
            {
                CircleCollider2D cc = gameObject.AddComponent<CircleCollider2D>();
                cc.isTrigger = isTrigger || obj.Type.Equals(Map.Object_Type_Trigger);

                gameObject.transform.localPosition = map.TiledPositionToWorldPoint(obj.Bounds.x, obj.Bounds.y, zDepth);
            #if UNITY_5
                cc.offset = new Vector2(obj.Bounds.width / 2.0f, -obj.Bounds.height / 2.0f);
            #else
                cc.center = new Vector2(obj.Bounds.width / 2.0f, -obj.Bounds.height / 2.0f);
            #endif

                cc.radius = obj.Bounds.width / 2.0f;
                if (physicsMaterial != null)
                    cc.sharedMaterial = physicsMaterial;

            }
            else
            {
                ApproximateEllipse2D(map, gameObject, obj, isTrigger, physicsMaterial, zDepth, createRigidbody, rigidbodyIsKinematic);
            }

            if (createRigidbody)
            {
                Rigidbody2D r = gameObject.AddComponent<Rigidbody2D>();
                r.isKinematic = rigidbodyIsKinematic;
            }

            if (obj.Rotation != 0)
                gameObject.transform.localRotation = Quaternion.AngleAxis(obj.Rotation, Vector3.forward);

            ApplyCustomProperties(gameObject, obj);

            // Link this collider to the MapObject
            obj.LinkedGameObject = gameObject;
        }