0
\$\begingroup\$

I am trying to separate unconnected contiguous areas in one tilemap into their own separate tilemaps.split one into two.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ This sounds like a good goal. How have you tried achieving it so far, and what step are you stuck on? Are you having trouble identifying which chunks of tiles are contiguous (standard connected components search)? Or creating a new tilemap object from script? Or populating that tilemap with tiles from the source? Or erasing the tiles from the source once you're done? Or something else? \$\endgroup\$
    – DMGregory
    Aug 5, 2021 at 16:35
  • \$\begingroup\$ @dmgregory My issue at the moment is identifying contiguous areas, as I am... less than an expert in many things. any help would be appreciated! \$\endgroup\$ Aug 5, 2021 at 16:38
  • \$\begingroup\$ We have existing Q&A about finding connected components on a map, and Wikipedia also covers this. Based on your research of these existing sources, have you run into any specific difficulty applying them to your case? \$\endgroup\$
    – DMGregory
    Aug 5, 2021 at 16:41

1 Answer 1

0
\$\begingroup\$

thanks to @dmgregory for helping me help my idiot self.

public List<List<Vector3Int>> FindConnectedGroups(Tilemap world)
{
    var visited = new List<Vector3Int>();
    var dirs = new List<Vector3Int>{Vector3Int.up, Vector3Int.down, Vector3Int.left, Vector3Int.right};
    var groups = new List<List<Vector3Int>>();
    for (int x = world.cellBounds.xMin; x < world.cellBounds.xMax; x++)
    {
        for (int y = world.cellBounds.yMin; y < world.cellBounds.yMax; y++)
        {
            var group = new List<Vector3Int>();
            var visit = new List<Vector3Int>();
            var tile = new Vector3Int(x, y, 0);                
            if (!visited.Contains(tile))
            {
                visit.Add(tile);
                for (int z = 0; z < visit.Count;z++)
                {
                    var t = visit[z];
                    if (!visited.Contains(t) && world.GetTile(t))
                    {
                        visited.Add(t);
                        group.Add(t);
                        foreach (var d in dirs)
                        {
                            if (!visited.Contains(t + d))
                            {
                                visit.Add(t + d);
                            }
                        }
                    }
                    else if(!world.GetTile(t))
                    {
                        visit.Remove(t);
                    }
                }
            }
            if (group.Count > 0)
            {
                groups.Add(group);
            }
        }
    }
    visited.Clear();
    return groups;

}

It's less elegant than it could be, but more functional then what I was trying before.

\$\endgroup\$
1
  • \$\begingroup\$ Remember to mark this answer as Accepted if it worked for you. \$\endgroup\$
    – DMGregory
    Sep 5, 2021 at 11:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .