Beispiel #1
0
        private void DrawProceduralField(TilesetBrush brush, Tileset tileset)
        {
            using (var content = ControlContent.WithTrailableTip(
                       TileLang.ParticularText("Property", "Procedural"),
                       TileLang.Text("Allows individual atlas brushes to override property of tileset.")
                       )) {
                // Need to make width of "Procedural" popup shorter.
                GUILayout.BeginHorizontal(GUILayout.Width(200));
                InheritYesNo newProcedural = (InheritYesNo)EditorGUILayout.EnumPopup(content, brush.procedural);
                if (newProcedural != brush.procedural)
                {
                    brush.procedural = newProcedural;

                    if (!brush.IsProcedural)
                    {
                        // Ensure that required procedural mesh exists!
                        if (BrushUtility.EnsureTilesetMeshExists(tileset, brush.tileIndex))
                        {
                            AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tileset.tileMeshAsset));
                        }
                    }
                }

                Rect position = GUILayoutUtility.GetLastRect();
                GUI.Label(new Rect(position.x + position.width, position.y, 100, position.height), "= " + (brush.IsProcedural ? TileLang.Text("Procedural") : TileLang.Text("Non-Procedural")), EditorStyles.miniLabel);

                GUILayout.EndHorizontal();

                ExtraEditorGUI.TrailingTip(content);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Cleanup tileset mesh assets that are not referenced by tileset brushes.
        /// </summary>
        /// <remarks>
        /// <para>Meshes will become missing in scenes and assets where tile meshes
        /// were previously used (i.e. where previously used tileset brushes have been
        /// deleted). Previously painted tiles should be refreshed.</para>
        /// </remarks>
        /// <param name="tileset">The tileset.</param>
        public static void CleanupTilesetMeshes(Tileset tileset)
        {
            if (tileset == null)
            {
                throw new ArgumentNullException("tileset");
            }

            // No mesh assets to cleanup!
            if (tileset.tileMeshAsset == null || tileset.tileMeshes == null)
            {
                return;
            }

            var tilesetRecord = BrushDatabase.Instance.FindTilesetRecord(tileset);

            if (tilesetRecord == null)
            {
                throw new Exception("Tileset record was not found for '" + tileset.name + "'");
            }

            int keep = 0, lastIndex = 0;

            for (int i = 0; i < tileset.tileMeshes.Length; ++i)
            {
                Mesh m = tileset.tileMeshes[i];
                if (m == null)
                {
                    continue;
                }

                // Find out if at least one tileset brush uses this mesh.
                foreach (BrushAssetRecord record in tilesetRecord.BrushRecords)
                {
                    TilesetBrush brush = record.Brush as TilesetBrush;

                    // Only consider non-procedural tileset brushes!
                    if (brush != null && brush.tileIndex == i && !brush.IsProcedural)
                    {
                        // Do not delete mesh asset!
                        m = null;
                        ++keep;
                        break;
                    }
                }

                if (m != null)
                {
                    tileset.tileMeshes[i] = null;
                    EditorUtility.SetDirty(tileset);

                    Object.DestroyImmediate(m, true);
                }
                else
                {
                    // Index of last mesh that was kept.
                    lastIndex = i;
                }
            }

            // Were any mesh assets required?
            if (keep == 0)
            {
                // Remove asset altogether.
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(tileset.tileMeshAsset));
                tileset.tileMeshAsset = null;
            }
            else
            {
                // Shrink tile mesh map if possible.
                Array.Resize(ref tileset.tileMeshes, lastIndex + 1);

                // Re-import mesh asset.
                AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(tileset.tileMeshAsset));
            }

            DesignerWindow.RepaintWindow();
        }
Beispiel #3
0
    /// <summary>
    /// Upgrades atlas brush (v1.x) into a tileset brush (v2.x).
    /// </summary>
    /// <remarks>
    /// <para>These are now called tileset brushes because they utilise a central
    /// tileset asset which makes it easier to manage such brushes.</para>
    /// </remarks>
    /// <param name="record">Record for existing v1.x brush.</param>
    private void UpgradeAtlasBrush(RtsBrushAssetRecordWrapper record)
    {
        MonoBehaviour oldBrush     = record.brush;
        Transform     oldTransform = oldBrush.transform;

        // Cannot upgrade atlas tile brush if tileset was not generated
        Tileset tileset = GenerateTilesetFromAtlasBrush(oldBrush);

        if (tileset == null)
        {
            Debug.LogError(string.Format("Could not generate tileset for atlas brush '{0}'.", oldBrush.name));
            return;
        }

        Texture2D atlasTexture   = (Texture2D)_fiAtlasTileBrush_atlasTexture.GetValue(oldBrush);
        int       atlasTileWidth = (int)_fiAtlasTileBrush_atlasTileWidth.GetValue(oldBrush);
        int       atlasRow       = (int)_fiAtlasTileBrush_atlasRow.GetValue(oldBrush);
        int       atlasColumn    = (int)_fiAtlasTileBrush_atlasColumn.GetValue(oldBrush);

        // Create the new tileset brush.
        int          atlasColumns = atlasTexture.width / atlasTileWidth;
        int          tileIndex    = atlasRow * atlasColumns + atlasColumn;
        TilesetBrush newBrush     = BrushUtility.CreateTilesetBrush(record.displayName, tileset, tileIndex, InheritYesNo.Inherit);

        // Was unit collider added to original atlas brush?
        BoxCollider automaticCollider = oldBrush.collider as BoxCollider;

        if (automaticCollider != null && automaticCollider.size == Vector3.one && automaticCollider.center == Vector3.zero)
        {
            newBrush.addCollider = true;
        }

        int componentCount = oldTransform.GetComponents <Component>().Length;

        if (newBrush.addCollider)
        {
            --componentCount;
        }

        // Should prefab be generated and attached?
        //   - Attach prefab if it contains child game objects.
        //   - Attach prefab if collider is non-standard.
        //   - Contains extra components (1=transform, 2=brush, 3=filter, 4=renderer).
        bool attachPrefab = (oldTransform.childCount > 0) ||
                            (!newBrush.addCollider && oldBrush.collider != null) ||
                            (componentCount != 4)
        ;

        if (attachPrefab)
        {
            GameObject attachment = PrefabUtility.InstantiatePrefab(oldBrush.gameObject) as GameObject;

            // Destroy the previous brush component.
            Object.DestroyImmediate(attachment.GetComponent(_tyTileBrush));
            // Destroy collider as it's not needed.
            if (newBrush.addCollider)
            {
                Object.DestroyImmediate(attachment.collider);
            }

            // Remove mesh filter and renderer components.
            Object.DestroyImmediate(attachment.renderer);
            Object.DestroyImmediate(attachment.GetComponent <MeshFilter>());

            string assetPath = GetUniqueMigratedPath(oldBrush.name + ".prefab");
            newBrush.attachPrefab = PrefabUtility.CreatePrefab(assetPath, attachment);

            Object.DestroyImmediate(attachment);
        }

        CopyCommonBrushProperties(newBrush, record.brush);
        RtsUpgradedBrushMap.BrushMappings.SetMapping(record.brush, newBrush);

        if (newBrush.visibility == BrushVisibility.Shown)
        {
            newBrush.visibility = BrushVisibility.Favourite;
        }
        else
        {
            newBrush.visibility = BrushVisibility.Shown;
        }
    }
Beispiel #4
0
        private bool FillColliderMeshData()
        {
            //Debug.Log( "[" + ParentTilemap.name + "] FillColliderMeshData -> " + name);
            if (tileSet == null || parent_tileMap.tileMapColliderType == TileMapColliderType.None)
            {
                return(false);
            }

            System.Type collider2DType = parent_tileMap.tileMap2DColliderType == TileMap2DColliderType.EdgeCollider2D ? typeof(EdgeCollider2D) : typeof(PolygonCollider2D);
            Component[] aColliders2D   = null;
            if (parent_tileMap.tileMapColliderType == TileMapColliderType._3D)
            {
                int totalTiles = width * height;
                if (mesh_collider_vertice_list == null)
                {
                    mesh_collider_vertice_list  = new List <Vector3>(totalTiles * 4);
                    mesh_collider_triangle_list = new List <int>(totalTiles * 6);
                }
                else
                {
                    mesh_collider_vertice_list.Clear();
                    mesh_collider_triangle_list.Clear();
                }
            }
            else //if (ParentTilemap.ColliderType == eColliderType._2D)
            {
                has_2D_colliders = true;
                open_edge_list.Clear();
                aColliders2D = GetComponents(collider2DType);
            }
            float halvedCollDepth = parent_tileMap.collider_depth / 2f;
            bool  isEmpty         = true;

            for (int ty = 0, tileIdx = 0; ty < height; ++ty)
            {
                for (int tx = 0; tx < width; ++tx, ++tileIdx)
                {
                    uint tileData = tileData_list[tileIdx];
                    if (tileData != TileSetConst.TileData_Empty)
                    {
                        int  tileId = (int)(tileData & TileSetConst.TileDataMask_TileId);
                        Tile tile   = tileSet.GetTile(tileId);
                        if (tile != null)
                        {
#if ENABLE_MERGED_SUBTILE_COLLIDERS
                            TilesetBrush brush = ParentTilemap.Tileset.FindBrush(Tileset.GetBrushIdFromTileData(tileData));
                            Vector2[]    subTileMergedColliderVertices = brush ? brush.GetMergedSubtileColliderVertices(ParentTilemap, GridPosX + tx, GridPosY + ty, tileData) : null;
#else
                            Vector2[] subTileMergedColliderVertices = null;
#endif
                            bool hasMergedColliders = subTileMergedColliderVertices != null;

                            TileColliderData tileCollData = tile.tileColliderData;
                            if (tileCollData.type != TileColliderType.None || hasMergedColliders)
                            {
                                isEmpty = false;
                                int  neighborCollFlags           = 0; // don't remove, even using neighborTileCollData, neighborTileCollData is not filled if tile is empty
                                bool isSurroundedByFullColliders = true;
                                for (int i = 0; i < neighbor_segment_min_max.Length; ++i)
                                {
                                    neighbor_segment_min_max[i].x = float.MaxValue;
                                    neighbor_segment_min_max[i].y = float.MinValue;
                                }
                                System.Array.Clear(neighbor_tileColliderData, 0, neighbor_tileColliderData.Length);

                                if (!hasMergedColliders)
                                {
                                    if ((tileData & (TileSetConst.TileFlag_FlipH | TileSetConst.TileFlag_FlipV | TileSetConst.TileFlag_Rot90)) != 0)
                                    {
                                        tileCollData = tileCollData.Clone();
                                        tileCollData.ApplyFlippingFlags(tileData);
                                    }
                                    for (int i = 0; i < 4; ++i)
                                    {
                                        uint neighborTileData;
                                        bool isTriggerOrPolygon = parent_tileMap.is_trigger ||
                                                                  parent_tileMap.tileMapColliderType == TileMapColliderType._2D &&
                                                                  parent_tileMap.tileMap2DColliderType == TileMap2DColliderType.PolygonCollider2D;
                                        switch (i)
                                        {
                                        case 0: // Up Tile
                                            neighborTileData = (tileIdx + width) < tileData_list.Count ?
                                                               tileData_list[tileIdx + width]
                      :
                                                               isTriggerOrPolygon ? TileSetConst.TileData_Empty : parent_tileMap.GetTileData(offset_grid_x + tx, offset_grid_y + ty + 1); break;

                                        case 1:                                             // Right Tile
                                            neighborTileData = (tileIdx + 1) % width != 0 ? //(tileIdx + 1) < m_tileDataList.Count ?
                                                               tileData_list[tileIdx + 1]
                      :
                                                               isTriggerOrPolygon ? TileSetConst.TileData_Empty : parent_tileMap.GetTileData(offset_grid_x + tx + 1, offset_grid_y + ty); break;

                                        case 2: // Down Tile
                                            neighborTileData = tileIdx >= width ?
                                                               tileData_list[tileIdx - width]
                      :
                                                               isTriggerOrPolygon ? TileSetConst.TileData_Empty : parent_tileMap.GetTileData(offset_grid_x + tx, offset_grid_y + ty - 1); break;

                                        case 3:                                       // Left Tile
                                            neighborTileData = tileIdx % width != 0 ? //neighborTileId = tileIdx >= 1 ?
                                                               tileData_list[tileIdx - 1]
                      :
                                                               isTriggerOrPolygon ? TileSetConst.TileData_Empty : parent_tileMap.GetTileData(offset_grid_x + tx - 1, offset_grid_y + ty); break;

                                        default: neighborTileData = TileSetConst.TileData_Empty; break;
                                        }

                                        int neighborTileId = (int)(neighborTileData & TileSetConst.TileDataMask_TileId);
                                        if (neighborTileId != TileSetConst.TileId_Empty)
                                        {
                                            Vector2          segmentMinMax;
                                            TileColliderData neighborTileCollider;
                                            neighborTileCollider = tileSet.tile_list[neighborTileId].tileColliderData;
                                            if ((neighborTileData & (TileSetConst.TileFlag_FlipH | TileSetConst.TileFlag_FlipV | TileSetConst.TileFlag_Rot90)) != 0)
                                            {
                                                neighborTileCollider = neighborTileCollider.Clone();
                                                if ((neighborTileData & TileSetConst.TileFlag_FlipH) != 0)
                                                {
                                                    neighborTileCollider.FlipH();
                                                }
                                                if ((neighborTileData & TileSetConst.TileFlag_FlipV) != 0)
                                                {
                                                    neighborTileCollider.FlipV();
                                                }
                                                if ((neighborTileData & TileSetConst.TileFlag_Rot90) != 0)
                                                {
                                                    neighborTileCollider.Rot90();
                                                }
                                            }
                                            neighbor_tileColliderData[i] = neighborTileCollider;
                                            isSurroundedByFullColliders &= (neighborTileCollider.type == TileColliderType.Full);

                                            if (neighborTileCollider.type == TileColliderType.None)
                                            {
                                                segmentMinMax = new Vector2(float.MaxValue, float.MinValue); //NOTE: x will be min, y will be max
                                            }
                                            else if (neighborTileCollider.type == TileColliderType.Full)
                                            {
                                                segmentMinMax      = new Vector2(0f, 1f); //NOTE: x will be min, y will be max
                                                neighborCollFlags |= (1 << i);
                                            }
                                            else
                                            {
                                                segmentMinMax      = new Vector2(float.MaxValue, float.MinValue); //NOTE: x will be min, y will be max
                                                neighborCollFlags |= (1 << i);
                                                for (int j = 0; j < neighborTileCollider.vertices.Length; ++j)
                                                {
                                                    Vector2 v = neighborTileCollider.vertices[j];
                                                    {
                                                        if (i == 0 && v.y == 0 || i == 2 && v.y == 1) //Top || Bottom
                                                        {
                                                            if (v.x < segmentMinMax.x)
                                                            {
                                                                segmentMinMax.x = v.x;
                                                            }
                                                            if (v.x > segmentMinMax.y)
                                                            {
                                                                segmentMinMax.y = v.x;
                                                            }
                                                        }
                                                        else if (i == 1 && v.x == 0 || i == 3 && v.x == 1) //Right || Left
                                                        {
                                                            if (v.y < segmentMinMax.x)
                                                            {
                                                                segmentMinMax.x = v.y;
                                                            }
                                                            if (v.y > segmentMinMax.y)
                                                            {
                                                                segmentMinMax.y = v.y;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            neighbor_segment_min_max[i] = segmentMinMax;
                                        }
                                        else
                                        {
                                            isSurroundedByFullColliders = false;
                                        }
                                    }
                                }
                                // Create Mesh Colliders
                                if (isSurroundedByFullColliders && !hasMergedColliders)
                                {
                                    //Debug.Log(" Surrounded! " + tileIdx);
                                }
                                else
                                {
                                    float     px0          = tx * cell_size.x;
                                    float     py0          = ty * cell_size.y;
                                    Vector2[] collVertices = subTileMergedColliderVertices;
                                    if (!hasMergedColliders)
                                    {
                                        collVertices = tileCollData.type == TileColliderType.Full ?TileConst.Full_Collider_Tile_Vertices : tileCollData.vertices;
                                    }

                                    for (int i = 0; i < collVertices.Length; ++i)
                                    {
                                        Vector2 s0 = collVertices[i];
                                        Vector2 s1 = collVertices[i == (collVertices.Length - 1) ? 0 : i + 1];
                                        if (hasMergedColliders)
                                        {
                                            ++i; // add ++i; in this case to go 2 by 2 because the collVertices for merged colliders will have the segments in pairs
                                        }
                                        // full collider optimization
                                        if ((tileCollData.type == TileColliderType.Full) &&
                                            (
                                                (i == 0 && neighbor_tileColliderData[3].type == TileColliderType.Full) || // left tile has collider
                                                (i == 1 && neighbor_tileColliderData[0].type == TileColliderType.Full) || // top tile has collider
                                                (i == 2 && neighbor_tileColliderData[1].type == TileColliderType.Full) || // right tile has collider
                                                (i == 3 && neighbor_tileColliderData[2].type == TileColliderType.Full)    // bottom tile has collider
                                            )
                                            )
                                        {
                                            continue;
                                        }
                                        // polygon collider optimization
                                        else // if( tileCollData.type == eTileCollider.Polygon ) Or Full colliders if neighbor is not Full as well
                                        {
                                            Vector2 n, m;
                                            if (s0.y == 1f && s1.y == 1f)           // top side
                                            {
                                                if ((neighborCollFlags & 0x1) != 0) // top tile has collider
                                                {
                                                    n = neighbor_segment_min_max[0];
                                                    if (n.x < n.y && n.x <= s0.x && n.y >= s1.x)
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.x == 1f && s1.x == 1f)      // right side
                                            {
                                                if ((neighborCollFlags & 0x2) != 0) // right tile has collider
                                                {
                                                    n = neighbor_segment_min_max[1];
                                                    if (n.x < n.y && n.x <= s1.y && n.y >= s0.y)
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.y == 0f && s1.y == 0f)      // bottom side
                                            {
                                                if ((neighborCollFlags & 0x4) != 0) // bottom tile has collider
                                                {
                                                    n = neighbor_segment_min_max[2];
                                                    if (n.x < n.y && n.x <= s1.x && n.y >= s0.x)
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.x == 0f && s1.x == 0f)      // left side
                                            {
                                                if ((neighborCollFlags & 0x8) != 0) // left tile has collider
                                                {
                                                    n = neighbor_segment_min_max[3];
                                                    if (n.x < n.y && n.x <= s0.y && n.y >= s1.y)
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.y == 1f && s1.x == 1f) // top - right diagonal
                                            {
                                                if ((neighborCollFlags & 0x1) != 0 && (neighborCollFlags & 0x2) != 0)
                                                {
                                                    n = neighbor_segment_min_max[0];
                                                    m = neighbor_segment_min_max[1];
                                                    if ((n.x < n.y && n.x <= s0.x && n.y == 1f) && (m.x < m.y && m.x <= s1.y && m.y == 1f))
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.x == 1f && s1.y == 0f) // right - bottom diagonal
                                            {
                                                if ((neighborCollFlags & 0x2) != 0 && (neighborCollFlags & 0x4) != 0)
                                                {
                                                    n = neighbor_segment_min_max[1];
                                                    m = neighbor_segment_min_max[2];
                                                    if ((n.x < n.y && n.x == 0f && n.y >= s0.y) && (m.x < m.y && m.x <= s1.x && m.y == 1f))
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.y == 0f && s1.x == 0f) // bottom - left diagonal
                                            {
                                                if ((neighborCollFlags & 0x4) != 0 && (neighborCollFlags & 0x8) != 0)
                                                {
                                                    n = neighbor_segment_min_max[2];
                                                    m = neighbor_segment_min_max[3];
                                                    if ((n.x < n.y && n.x == 0f && n.y >= s0.x) && (m.x < m.y && m.x == 0f && m.y >= s1.y))
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else if (s0.x == 0f && s1.y == 1f) // left - top diagonal
                                            {
                                                if ((neighborCollFlags & 0x8) != 0 && (neighborCollFlags & 0x1) != 0)
                                                {
                                                    n = neighbor_segment_min_max[3];
                                                    m = neighbor_segment_min_max[0];
                                                    if ((n.x < n.y && n.x <= s0.y && n.y == 1f) && (m.x < m.y && m.x == 0f && m.y >= s1.x))
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                        }
                                        // Update s0 and s1 to world positions
                                        s0.x = px0 + cell_size.x * s0.x; s0.y = py0 + cell_size.y * s0.y;
                                        s1.x = px0 + cell_size.x * s1.x; s1.y = py0 + cell_size.y * s1.y;
                                        if (parent_tileMap.tileMapColliderType == TileMapColliderType._3D)
                                        {
                                            int collVertexIdx = mesh_collider_vertice_list.Count;
                                            mesh_collider_vertice_list.Add(new Vector3(s0.x, s0.y, -halvedCollDepth));
                                            mesh_collider_vertice_list.Add(new Vector3(s0.x, s0.y, halvedCollDepth));
                                            mesh_collider_vertice_list.Add(new Vector3(s1.x, s1.y, halvedCollDepth));
                                            mesh_collider_vertice_list.Add(new Vector3(s1.x, s1.y, -halvedCollDepth));

                                            mesh_collider_triangle_list.Add(collVertexIdx + 0);
                                            mesh_collider_triangle_list.Add(collVertexIdx + 1);
                                            mesh_collider_triangle_list.Add(collVertexIdx + 2);
                                            mesh_collider_triangle_list.Add(collVertexIdx + 2);
                                            mesh_collider_triangle_list.Add(collVertexIdx + 3);
                                            mesh_collider_triangle_list.Add(collVertexIdx + 0);
                                        }
                                        else //if( ParentTilemap.ColliderType == eColliderType._2D )
                                        {
                                            int linkedSegments    = 0;
                                            int segmentIdxToMerge = -1;
                                            for (int edgeIdx = open_edge_list.Count - 1; edgeIdx >= 0 && linkedSegments < 2; --edgeIdx)
                                            {
                                                LinkedList <Vector2> edgeSegments = open_edge_list[edgeIdx];
                                                if (edgeSegments.First.Value == edgeSegments.Last.Value)
                                                {
                                                    continue; //skip closed edges
                                                }
                                                if (edgeSegments.Last.Value == s0)
                                                {
                                                    if (segmentIdxToMerge >= 0)
                                                    {
                                                        LinkedList <Vector2> segmentToMerge = open_edge_list[segmentIdxToMerge];
                                                        if (s0 == segmentToMerge.First.Value)
                                                        {
                                                            for (LinkedListNode <Vector2> node = segmentToMerge.First.Next; node != null; node = node.Next)
                                                            {
                                                                edgeSegments.AddLast(node.Value);
                                                            }
                                                            open_edge_list.RemoveAt(segmentIdxToMerge);
                                                        }

                                                        /* Cannot join head with head or tail with tail, it will change the segment normal
                                                         * else
                                                         *  for (LinkedListNode<Vector2> node = segmentToMerge.Last.Previous; node != null; node = node.Previous)
                                                         *      edgeSegments.AddLast(node.Value);*/
                                                    }
                                                    else
                                                    {
                                                        segmentIdxToMerge = edgeIdx;
                                                        edgeSegments.AddLast(s1);
                                                    }
                                                    ++linkedSegments;
                                                }

                                                /* Cannot join head with head or tail with tail, it will change the segment normal
                                                 * else if( edgeSegments.Last.Value == s1 )
                                                 * else if (edgeSegments.First.Value == s0)*/
                                                else if (edgeSegments.First.Value == s1)
                                                {
                                                    if (segmentIdxToMerge >= 0)
                                                    {
                                                        LinkedList <Vector2> segmentToMerge = open_edge_list[segmentIdxToMerge];
                                                        if (s1 == segmentToMerge.Last.Value)
                                                        {
                                                            for (LinkedListNode <Vector2> node = edgeSegments.First.Next; node != null; node = node.Next)
                                                            {
                                                                segmentToMerge.AddLast(node.Value);
                                                            }
                                                            open_edge_list.RemoveAt(edgeIdx);
                                                        }

                                                        /* Cannot join head with head or tail with tail, it will change the segment normal
                                                         * else
                                                         *  for (LinkedListNode<Vector2> node = edgeSegments.First.Next; node != null; node = node.Next)
                                                         *      segmentToMerge.AddFirst(node.Value);*/
                                                    }
                                                    else
                                                    {
                                                        segmentIdxToMerge = edgeIdx;
                                                        edgeSegments.AddFirst(s0);
                                                    }
                                                    ++linkedSegments;
                                                }
                                            }
                                            if (linkedSegments == 0)
                                            {
                                                LinkedList <Vector2> newEdge = new LinkedList <Vector2>();
                                                newEdge.AddFirst(s0);
                                                newEdge.AddLast(s1);
                                                open_edge_list.Add(newEdge);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (parent_tileMap.tileMapColliderType == TileMapColliderType._2D)
            {
                //+++ Process Edges
                //(NOTE: this was added to fix issues related with lighting, otherwise leave this commented)
                {
                    // Remove vertex inside a line
                    RemoveRedundantVertices(open_edge_list);

                    // Split segments (NOTE: This is not working with polygon colliders)

                    /*/ commented unless necessary for performance reasons
                     * if (ParentTilemap.Collider2DType == e2DColliderType.EdgeCollider2D)
                     * {
                     *  openEdges = SplitSegments(openEdges);
                     * }
                     * //*/
                }
                //---

                //Create Edges
                for (int i = 0; i < open_edge_list.Count; ++i)
                {
                    LinkedList <Vector2> edgeSegments = open_edge_list[i];
                    bool       reuseCollider          = i < aColliders2D.Length;
                    Collider2D collider2D             = reuseCollider ? (Collider2D)aColliders2D[i] : (Collider2D)gameObject.AddComponent(collider2DType);
                    collider2D.enabled        = true;
                    collider2D.isTrigger      = parent_tileMap.is_trigger;
                    collider2D.sharedMaterial = parent_tileMap.physicMaterial2D;
                    if (parent_tileMap.tileMap2DColliderType == TileMap2DColliderType.EdgeCollider2D)
                    {
                        ((EdgeCollider2D)collider2D).points = edgeSegments.ToArray();
                    }
                    else
                    {
                        ((PolygonCollider2D)collider2D).SetPath(0, edgeSegments.ToArray());
                    }
                }

                //Destroy unused edge colliders
                for (int i = open_edge_list.Count; i < aColliders2D.Length; ++i)
                {
                    if (!is_on_validate)
                    {
                        DestroyImmediate(aColliders2D[i]);
                    }
                    else
                    {
                        ((Collider2D)aColliders2D[i]).enabled = false;
                    }
                }
            }

            return(!isEmpty);
        }
Beispiel #5
0
        // '°', '├', '═', '┤', | 0, 2, 10, 8,
        // '┬', '╔', '╦', '╗', | 4, 6, 14, 12,
        // '║', '╠', '╬', '╣', | 5, 7, 15, 13,
        // '┴', '╚', '╩', '╝', | 1, 3, 11, 9,
        public override uint[] GetSubtiles(global::CreativeSpore.SuperTilemapEditor.Tilemap tilemap, int gridX, int gridY, uint tileData)
        {
            CalculateNeighbourData(tilemap, gridX, gridY, tileData);
            // tiles that need subtile division
            if (s_needsSubTiles)
            {
                uint[] aSubTileData = null;

                if (s_neighIdx == 0) //°
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[6], TileIds[12] };
                }
                else if (s_neighIdx == 4)//┬
                {
                    aSubTileData = new uint[] { TileIds[6], TileIds[12], TileIds[6], TileIds[12] };
                }
                else if (s_neighIdx == 5)//║
                {
                    aSubTileData = new uint[] { TileIds[7], TileIds[13], TileIds[7], TileIds[13] };
                }
                else if (s_neighIdx == 1)//┴
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[9], TileIds[3], TileIds[9] };
                }
                else if (s_neighIdx == 2)//├
                {
                    aSubTileData = new uint[] { TileIds[3], TileIds[3], TileIds[6], TileIds[6] };
                }
                else if (s_neighIdx == 10)//═
                {
                    aSubTileData = new uint[] { TileIds[11], TileIds[11], TileIds[14], TileIds[14] };
                }
                else if (s_neighIdx == 8)//┤
                {
                    aSubTileData = new uint[] { TileIds[9], TileIds[9], TileIds[12], TileIds[12] };
                }
                // NOTE: this case '╬' cut the tiles different (using corner tiles).
                // If it is commented, and default case is used, instead or corner tiles, it will use the center tile '╬'
                // Depending on the graphics it could be interesting add a check box to choose between using this or not.
                else if (s_neighIdx == 15)// ╬
                {
                    aSubTileData = new uint[] { InteriorCornerTileIds[0], InteriorCornerTileIds[1], InteriorCornerTileIds[2], InteriorCornerTileIds[3] };
                }
                else
                {
                    aSubTileData = new uint[] { TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx], TileIds[s_neighIdx] };
                }

                for (int i = 0; i < s_showDiagonal.Length; ++i)
                {
                    if (s_showDiagonal[i])
                    {
                        aSubTileData[i] = InteriorCornerTileIds[3 - i];
                    }
                    // Add animated tiles
                    {
                        TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(aSubTileData[i]));
                        if (brush && brush.IsAnimated())
                        {
                            TilemapChunk.RegisterAnimatedBrush(brush, i);
                        }
                    }
                }

                return(aSubTileData);
            }

            // Add animated tiles
            {
                TilesetBrush brush = Tileset.FindBrush(Tileset.GetBrushIdFromTileData(s_tileData));
                if (brush && brush.IsAnimated())
                {
                    TilemapChunk.RegisterAnimatedBrush(brush);
                }
            }
            return(null);
        }