I’m making a top-down view game as seen below. The tan grid background is the base art, and as a player (P) moves and uncovers tiles, I will be using a sprite for the bordering walls as they become visible.

The map tiles with the red X’s will not show unless the player has vision.
I need a technique for determining which tiles are visible. I’ve written a lot of line of sight (LoS) code over the years, but I’m wondering how best to achieve this in Unity with 2.5D. It feels silly to code 3D stuff that may already be built in.
The only solution I’ve come up with so far was to manually put in some invisible box colliders as “walls” wherever the black lines are, then do something with line casting from the player. Anyone have any suggestions for how best to solve this problem? I’d really appreciate some advice here.
If the tiles have a Renderer attached to them you can use the built-in variable Renderer.isVisible to check if they’re in the camera’s view.
Since nobody has answered, I will just provide a nudge in the right direction. There is an awesome explanation of how to achieve this over at: www.redblobgames.com
While the explanation is not unity specific, this can very well be achieved in unity.
Here is my function that will test line of sight for blocked tiles on a square grid.
Note there are a few simple external functions you need to adapt to your application:
CanSeeThroughTile(x, y) Returns true if you can see through this tile, false if not
IsTileValid(x, y) Returns true if tile is within your map bounds.
public bool CheckLOS(int x, int y, int x1, int y1) // Check LOS between x,y and x1,y1 Returns True if LOS exists, False if blocked
{
long sx; long sy; long tx; long ty; long ex; long ey;
if (MapManager.Instance.IsTileValid(x, y)==false) { return false; } // Test for valid input values Exit false if outside map bounds!
if (MapManager.Instance.IsTileValid(x1, y1) == false) { return false; }
sx = x * 3780; sy = y * 3780;
tx = x1 * 3780; ty = y1 * 3780;
tx = tx - sx; ty = ty - sy; sx = 0; sy = 0;
// Repeat the following until we reach the target square or we are blocked
while (y!=y1 || x!=x1)
{
if (ty == 0) //Horizontal straight line
{ x = x + (1 * (int)Mathf.Sign(tx)); }
else
{
if (tx == 0) //"Vertical straight line
{ y = y + (1 * (int)Mathf.Sign(ty)); }
else
{
ey = 1890 * (int)Mathf.Sign(ty);
ex = sx + (ey - sy) * tx / ty;
if (Mathf.Abs(ex) < 1890)
{ sx = ex; sy = ey*-1; y = y+(int)Mathf.Sign(ty); }
else
{
ex = 1890 * (int)Mathf.Sign(tx);
ey = sy + (ex - sx) * ty / tx;
if (Mathf.Abs(ey) < 1890)
{ sx = ex * -1; sy = ey ; x = x + (int)Mathf.Sign(tx); }
else // We must be going through a corner
{
if (MapManager.Instance.CanSeeThroughTile(x, y + (int)Mathf.Sign(ty)) == false && MapManager.Instance.CanSeeThroughTile(x + (int)Mathf.Sign(tx), y) == false) // Can't see through two corners diagnally opposite
{ return false; }
else
{ sx = -1 * ex; sy = -1 * ey; y = y + (int)Mathf.Sign(ty); x = x + (int)Mathf.Sign(tx); }
}
}
}
}
if (y != y1 || x != x1)
{
if (MapManager.Instance.CanSeeThroughTile(x, y) == false) { return false; }
}
} // wend while (y!=y1 || x!=x1)
return true;
}