Пример #1
0
        private void TileSetTextureField(TileSet tileSet)
        {
            int id = tileSet.firstGID;

            if (selectedTileSet == null)
            {
                tileRect = new Rect(-1, -1, 0, 0);
            }

            Texture2D currentTexture = GetTileSetTexture(tileSet, path);
            Texture2D tex            = EditorGUILayout.ObjectField(currentTexture, typeof(Texture2D), false) as Texture2D;

            if (currentTexture != tex)
            {
                Uri textureURI = new Uri("/" + AssetDatabase.GetAssetPath(tex));
                Uri tmxFileURI = new Uri("/" + Path.GetDirectoryName(path));
                tileSet.image.source = "../" + tmxFileURI.MakeRelativeUri(textureURI);
            }

            if (tex == null)
            {
                return;
            }

            float x = Screen.width - 40;
            float y = tex.height * x / (float)tex.width;

            if (x > tex.width)
            {
                x = tex.width;
                y = tex.height;
            }
            Rect r = GUILayoutUtility.GetRect(x, y);

            r.width  = r.height * (float)tex.width / (float)tex.height;
            r.height = r.width * (float)tex.height / (float)tex.width;
            r.x      = (Screen.width - r.width) * 0.5f;
            EditorGUI.DrawPreviewTexture(r, tex, mat);

            if (selectedTileSet != null && selectedTileSet == tileSet && selectedTileIndex > 0)
            {
                TileRect uvTileRect = selectedTileSet.GetTileUVs(selectedTileIndex);
                tileRect         = r;
                tileRect.x      += uvTileRect.x * r.width;
                tileRect.y      += (1 - (uvTileRect.y + uvTileRect.height)) * r.height;
                tileRect.width  *= uvTileRect.width;
                tileRect.height *= uvTileRect.height;
            }

            Handles.DrawSolidRectangleWithOutline(tileRect, Color.clear, Color.white);

            if (Event.current.type == EventType.MouseDown &&
                Event.current.button == 0 &&
                r.Contains(Event.current.mousePosition))
            {
                selectedTileSet   = tileSet;
                selectedTileIndex = GetTileIndex(tileSet, r, Event.current.mousePosition);
                Event.current.Use();
            }
        }
Пример #2
0
        public TileRect GetTileUVs(int tileGID)
        {
            TileRect uvs = GetTileSpriteRect(tileGID);

            uvs.x      /= (float)image.width;
            uvs.y      /= (float)image.height;
            uvs.width  /= (float)image.width;
            uvs.height /= (float)image.height;

            return(uvs);
        }
Пример #3
0
        // TODO: Cache UVs
        public TileRect GetTileSpriteRect(int tileGID)
        {
            TileRect rect      = new TileRect();
            int      tileIndex = tileGID - firstGID;
            int      i         = tileIndex % columns;
            int      j         = (rows - 1) - tileIndex / columns;

            rect.x      = (margin + i * (tileWidth + spacing));
            rect.y      = (margin + j * (tileHeight + spacing));
            rect.width  = tileWidth;
            rect.height = tileHeight;

            return(rect);
        }
Пример #4
0
        public override void OnPreviewGUI(Rect r, GUIStyle background)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            Texture2D tex        = GetTileSetTexture(selectedTileSet, path);
            TileRect  uvTileRect = selectedTileSet.GetTileUVs(selectedTileIndex);

            Rect uvRect = new Rect(uvTileRect.x, uvTileRect.y, uvTileRect.width, uvTileRect.height);

            if (r.height > r.width)
            {
                r.height = r.width;
                r.x     += (r.height - r.width) * 0.5f;
            }
            else if (r.width > r.height)
            {
                r.width = r.height;
                r.y    += (r.width - r.height) * 0.5f;
            }
            r.x = (Screen.width - r.width) * 0.5f;
            GUI.DrawTextureWithTexCoords(r, tex, uvRect, true);

            Tile t = selectedTileSet.GetTile(selectedTileIndex);

            if (t != null && t.objectGroup != null && t.objectGroup.objects != null && t.objectGroup.objects.Length > 0)
            {
                foreach (TileObject obj in t.objectGroup.objects)
                {
                    if (obj.polygonSpecified)
                    {
                        TilePoint[] path = obj.polygon.path;
                        Vector3[]   poly = System.Array.ConvertAll(path, (p) => {
                            Vector3 v = new Vector3(p.x + obj.x, p.y + obj.y, 0);
                            v.x      *= r.width / (float)tmxFile.tileWidth;
                            v.y      *= r.height / (float)tmxFile.tileHeight;
                            v.x      += r.x;
                            v.y      += r.y;
                            return(v);
                        });
                        Handles.color = new Color(1, 1, 1, 0.1f);
                        Handles.DrawAAConvexPolygon(poly);
                    }
                }
            }
        }
Пример #5
0
        public void CreateSpriteTile(GameObject group, TileObject tileObject)
        {
            int        tileID = (int)tileObject.gid;
            GameObject g      = new GameObject(tileObject.name);

            g.transform.SetParent(group.transform);
            float y = tmxFile.height * tmxFile.tileHeight - tileObject.y;

            g.transform.localPosition    = new Vector3(tileObject.x, y, 0) / pixelsPerUnit;
            g.transform.localEulerAngles = Vector3.forward * -tileObject.rotation;

            SpriteRenderer sprite = g.AddComponent <SpriteRenderer>();

            sprite.flipX = TMXFile.FlippedHorizontally(tileObject.gid);
            sprite.flipY = TMXFile.FlippedVertically(tileObject.gid);
            TileSet tileSet = tmxFile.GetTileSetByTileID(tileID);

            if (tileSet != null && tileSet.image != null && !string.IsNullOrEmpty(tileSet.image.source))
            {
                g.transform.localScale = new Vector3(tileObject.width, tileObject.height, pixelsPerUnit) / pixelsPerUnit;
                int       tileSetIndex = System.Array.IndexOf(tmxFile.tileSets, tileSet);
                Material  mat          = tileSetMaterials[tileSetIndex];
                Texture2D tex          = mat.mainTexture as Texture2D;
                TileRect  r            = tileSet.GetTileSpriteRect(tileID);
                Rect      rect         = new Rect(r.x, r.y, r.width, r.height);
                Vector2   pivot        = Vector2.zero;
                sprite.sprite = Sprite.Create(tex, rect, pivot, pixelsPerUnit, 0, SpriteMeshType.FullRect);
            }
            else
            {
                int tileSetIndex = System.Array.IndexOf(tmxFile.tileSets, tileSet);
                sprite.sprite = tileSetSprites[tileSetIndex][tileID - tileSet.firstGID];
            }

            if (idToPhysics.ContainsKey(tileID))
            {
                float             yOff = tmxFile.tileHeight / pixelsPerUnit;
                Vector2[]         path = System.Array.ConvertAll(idToPhysics[tileID], (p) => new Vector2(p.x, p.y + yOff));
                PolygonCollider2D poly = g.AddComponent <PolygonCollider2D>();
                poly.pathCount = 1;
                poly.SetPath(0, path);
            }

            SetProperties(g, tileObject.properties);
        }
Пример #6
0
        public void UpdateMesh(TileLayer layerData, int submeshIndex)
        {
            Dictionary <int, int> firstGIDToIndex = new Dictionary <int, int>();

            for (int i = 0; i < tmxFile.tileSets.Length; i++)
            {
                firstGIDToIndex[tmxFile.tileSets[i].firstGID] = i;
            }

            int vertCount = 0;

            int[] triIDsPerMat = new int[tmxFile.tileSets.Length];
            for (int tileIndex = submeshIndex * 16250; tileIndex < Mathf.Min((submeshIndex + 1) * 16250, layerData.tileIDs.Length); tileIndex++)
            {
                int     tileID  = layerData.tileIDs[tileIndex];
                TileSet tileSet = tmxFile.GetTileSetByTileID(tileID);
                if (tileSet == null || tileID < tileSet.firstGID)
                {
                    continue;
                }

                vertCount += 4;
                triIDsPerMat[firstGIDToIndex[tileSet.firstGID]] += 6;
            }


            List <List <IntPoint> > paths = new List <List <IntPoint> >();

            Vector3[] verts  = new Vector3[vertCount];
            Vector3[] norms  = new Vector3[vertCount];
            Vector2[] uvs    = new Vector2[vertCount];
            Color[]   colors = new Color[vertCount];

            int[][] matTris = new int[tmxFile.tileSets.Length][];
            for (int i = 0; i < triIDsPerMat.Length; i++)
            {
                matTris[i] = new int[triIDsPerMat[i]];
            }

            bool isHexMap  = tmxFile.orientation == "hexagonal";
            bool isIsoMap  = tmxFile.orientation == "isometric";
            bool isStagMap = tmxFile.orientation == "staggered";

            bool staggerX     = tmxFile.staggerAxis == "x";
            int  staggerIndex = (tmxFile.staggerAxis == "even") ? 0 : 1;

            Color color = Color.white;

            if (layerData.tintColorSpecified)
            {
                color = TiledColorFromString(layerData.tintColor);
            }

            int vertIndex = 0;

            int[] matTriIndices = new int[tmxFile.tileSets.Length];
            for (int tileIndex = submeshIndex * 16250; tileIndex < Mathf.Min((submeshIndex + 1) * 16250, layerData.tileIDs.Length); tileIndex++)
            {
                int     tileID  = layerData.tileIDs[tileIndex];
                TileSet tileSet = tmxFile.GetTileSetByTileID(tileID);
                if (tileSet == null || tileID < tileSet.firstGID)
                {
                    continue;
                }

                if (tileSet.columns == 0 || tileSet.rows == 0)
                {
                    if (tileSet.image.width == 0 || tileSet.image.height == 0)
                    {
                        int       tileSetIndex = System.Array.IndexOf(tmxFile.tileSets, tileSet);
                        Texture2D tex          = tileSetMaterials[tileSetIndex].mainTexture as Texture2D;
                        tileSet.image.width  = tex.width;
                        tileSet.image.height = tex.height;
                    }
                    tileSet.columns = (tileSet.image.width - 2 * tileSet.margin) / (tileSet.tileWidth + tileSet.spacing);
                    tileSet.rows    = (tileSet.image.width - 2 * tileSet.margin) / (tileSet.tileWidth + tileSet.spacing);
                }

                TileRect uvRect = tileSet.GetTileUVs(tileID);

                bool flipX        = layerData.FlippedHorizontally(tileIndex);
                bool flipY        = layerData.FlippedVertically(tileIndex);
                bool flipAntiDiag = layerData.FlippedAntiDiagonally(tileIndex);
                bool rotated120   = layerData.RotatedHexagonal120(tileIndex);

                TilePoint tileLocation = layerData.GetTileLocation(tileIndex);
                Vector3   pos          = new Vector3(offset.x + tileLocation.x * tileOffset.x, offset.y + tileLocation.y * tileOffset.y, 0);
                if (isHexMap || isStagMap)
                {
                    if (staggerX)
                    {
                        pos.x = tileLocation.x * tileOffset.z;
                        if (tileLocation.x % 2 == staggerIndex)
                        {
                            pos.y += tileOffset.w * 0.5f;
                        }
                    }
                    else
                    {
                        pos.y = tileLocation.y * tileOffset.w;
                        if (tileLocation.y % 2 == staggerIndex)
                        {
                            pos.x += tileOffset.z * 0.5f;
                        }
                    }
                }
                else if (isIsoMap)
                {
                    pos.x = (tileLocation.x * tileOffset.x / 2) - (tileLocation.y * tileOffset.x / 2);
                    pos.y = (tileLocation.y * tileOffset.y / 2) + (tileLocation.x * tileOffset.y / 2);
                }

                float     widthMult  = (float)tileSet.tileWidth / (float)tmxFile.tileWidth;
                float     heightMult = (float)tileSet.tileHeight / (float)tmxFile.tileHeight;
                Vector3[] v          = new Vector3[] {
                    pos,
                    pos + Vector3.up * tileOffset.y * heightMult,
                    pos + new Vector3(tileOffset.x * widthMult, tileOffset.y * heightMult, 0),
                    pos + Vector3.right * tileOffset.x * widthMult
                };

                if (rotated120 || (flipAntiDiag && isHexMap))
                {
                    float angle = rotated120 ? 120 : 0;
                    angle += flipAntiDiag ? 60 : 0;
                    Vector3 center = (v[0] + v[2]) * 0.5f;
                    for (int i = 0; i < 4; i++)
                    {
                        v[i] = Quaternion.Euler(0, 0, -angle) * (v[i] - center) + center;
                    }
                }

                verts[vertIndex]     = v[0];
                verts[vertIndex + 1] = v[1];
                verts[vertIndex + 2] = v[2];
                verts[vertIndex + 3] = v[3];

                if (idToPhysics.ContainsKey(tileID))
                {
                    Vector3[] phys = new Vector3[idToPhysics[tileID].Length];
                    Vector3   off  = new Vector3(tileOffset.x * 0.5f, tileOffset.y * 0.5f, 0);
                    for (int i = 0; i < phys.Length; i++)
                    {
                        phys[i] = idToPhysics[tileID][i] - off;
                        if (flipAntiDiag)
                        {
                            phys[i] = Quaternion.AngleAxis(180, new Vector3(-1, 1, 0)) * phys[i];
                            if (flipX && flipY)
                            {
                                phys[i] = Quaternion.AngleAxis(180, Vector3.forward) * phys[i];
                            }
                            else if (flipX)
                            {
                                phys[i] = Quaternion.AngleAxis(180, Vector3.up) * phys[i];
                            }
                            else if (flipY)
                            {
                                phys[i] = Quaternion.AngleAxis(180, Vector3.right) * phys[i];
                            }
                        }
                        else
                        {
                            if (flipX)
                            {
                                phys[i] = Quaternion.AngleAxis(180, Vector3.up) * phys[i];
                            }
                            if (flipY)
                            {
                                phys[i] = Quaternion.AngleAxis(180, Vector3.right) * phys[i];
                            }
                        }
                        phys[i] += off;
                    }

                    IntPoint[] path = System.Array.ConvertAll(phys, (p) => Vector2ToIntPoint((Vector2)(p + pos)));
                    paths.Add(new List <IntPoint>(path));
                }

                norms[vertIndex]     = Vector3.back;
                norms[vertIndex + 1] = Vector3.back;
                norms[vertIndex + 2] = Vector3.back;
                norms[vertIndex + 3] = Vector3.back;

                float left   = uvRect.left;
                float right  = uvRect.right;
                float bottom = uvRect.bottom;
                float top    = uvRect.top;

                Vector2[] uvArray = new Vector2[] {
                    new Vector2(left, bottom),
                    new Vector2(left, top),
                    new Vector2(right, top),
                    new Vector2(right, bottom)
                };

                if (flipAntiDiag && !isHexMap)
                {
                    Vector2 tmp = uvArray[0];
                    uvArray[0] = uvArray[2];
                    uvArray[2] = tmp;
                }

                if (tileOffset.x < 0 != flipX)
                {
                    uvArray = new Vector2[] { uvArray[3], uvArray[2], uvArray[1], uvArray[0] };
                }

                if (tileOffset.y < 0 != flipY)
                {
                    uvArray = new Vector2[] { uvArray[1], uvArray[0], uvArray[3], uvArray[2] };
                }

                uvs[vertIndex]     = uvArray[0];
                uvs[vertIndex + 1] = uvArray[1];
                uvs[vertIndex + 2] = uvArray[2];
                uvs[vertIndex + 3] = uvArray[3];

                colors[vertIndex]     = color;
                colors[vertIndex + 1] = color;
                colors[vertIndex + 2] = color;
                colors[vertIndex + 3] = color;

                int matIndex = firstGIDToIndex[tileSet.firstGID];
                matTris[matIndex][matTriIndices[matIndex]]     = vertIndex;
                matTris[matIndex][matTriIndices[matIndex] + 1] = vertIndex + 2;
                matTris[matIndex][matTriIndices[matIndex] + 2] = vertIndex + 1;
                matTris[matIndex][matTriIndices[matIndex] + 3] = vertIndex;
                matTris[matIndex][matTriIndices[matIndex] + 4] = vertIndex + 3;
                matTris[matIndex][matTriIndices[matIndex] + 5] = vertIndex + 2;

                matTriIndices[matIndex] += 6;
                vertIndex += 4;
            }

            int layerIndex = GetLayerIndexFromID(layerData.id);

            GameObject[] subMeshObjects = layerSubmeshObjects[layerIndex];
            GameObject   obj            = subMeshObjects[submeshIndex];
            MeshFilter   filter         = obj.GetComponent <MeshFilter>();

            if (filter.sharedMesh == null)
            {
                filter.sharedMesh      = new Mesh();
                filter.sharedMesh.name = layerData.name;
                if (meshesPerLayer > 1)
                {
                    filter.sharedMesh.name += "_submesh" + submeshIndex;
                }
            }
            filter.sharedMesh.Clear();
            filter.sharedMesh.vertices = verts;
            filter.sharedMesh.normals  = norms;
            filter.sharedMesh.uv       = uvs;
            filter.sharedMesh.colors   = colors;

            List <Material> mats     = new List <Material>();
            List <int[]>    triLists = new List <int[]>();

            for (int i = 0; i < tmxFile.tileSets.Length; i++)
            {
                int[] tris = matTris[i];
                if (tris != null && tris.Length > 0)
                {
                    mats.Add(tileSetMaterials[i]);
                    triLists.Add(tris);
                }
            }
            obj.GetComponent <MeshRenderer>().sharedMaterials = mats.ToArray();

            filter.sharedMesh.subMeshCount = mats.Count;
            for (int i = 0; i < filter.sharedMesh.subMeshCount; i++)
            {
                filter.sharedMesh.SetTriangles(triLists[i], i);
            }

            filter.sharedMesh.RecalculateBounds();

            paths = Clipper.SimplifyPolygons(paths, PolyFillType.pftNonZero);
            paths = RemoveColinnearAndDoubles(paths);

            layerPaths[layerIndex][submeshIndex] = paths;
        }