If your blocks are in a grid, then it should be easy enough to do it without worrying about physics.
That said, if you do want to do it with physics, I would recommend using two colliders. The first is the cube itself, then there is a child game object which has a larger one which is marked as a trigger. Use OnTriggerEnter/Exit in a MonoBehaviour on the child GameObject to show/hide the parent's mesh.
Now, if you want to do it using a multidimensional array instead, that could be a bit more precise about having exactly the walls you want to be visible.
This example will put all of the code in a player class. It will also make a few assumptions about the cubes.
Assumption 1: All cubes are tagged with a special "wall" tag.
Assumption 2: All cubes are at integer positions and are of unit size (1x1x1). For example, a cube could be located at 1,1, but not at 1.5,1. If this is not the case, then some adjustments will need to be made to find all the cubes and put them in the right places in the array.
Assumption 3: the cubes are on the X-Y plane. If they are on the X-Z plane, minor adjustments will be needed.
Assumption 4: The size of the grid is not too big. A 100x100 grid is a 10,000 element array. Keep this in mind.
Some of these assumptions are to make it easier to find the cubes when the game starts. It is also possible to do this at design time, but it's a bit more work.
First, you'll need to keep track of all of the cubes in an array.
public class Player {
MeshRenderer[,] grid;
Vector2 minPos;
int gridW, gridH;
void Start() {
GameObject[] walls = FindObjectsWithTag("wall");
Bounds b = new Bounds(walls[0].transform.position, Vector3.zero);
foreach (var wall in walls) {
b.Encapsulate(wall.transform.position);
}
Vector2 size = b.size;
minPos = b.min;
gridW = (int)size.x;
gridH = (int)size.y;
grid = new MeshRenderer[gridW, gridH];
foreach (var wall in walls) {
Vector2 pos = wall.transform.position - minPos;
var renderer = wall.GetComponent<MeshRenderer>();
renderer.enabled = false;
grid[(int)pos.x, (int)pos.y] = renderer;
}
}
}
So far so good. The grid is populated with cubes. It is basically a representation of your maze in code. If we wanted to, we could write a solver now. But that's not what we're here for. Now we just need to turn on the cubes near the player whenever they move and turn off the old ones. We should keep track of the old and new grid positions of the player so we can turn off old cubes and turn on the new ones without iterating through the whole grid.
int oldX = int.MinValue;
int oldY = int.MinValue;
void Update() {
Vector2 pos = transform.position - minPos;
int x = Mathf.RoundToInt(pos.x);
int y = Mathf.RoundToInt(pos.y);
if (oldX != x || oldY != y) {
SetCubesEnabled(oldX, oldY, false);
SetCubesEnabled(x, y, true);
oldX = x;
oldY = y;
}
}
void SetCubesEnabled(int x, int y, bool enable) {
SetCubeEnabled(x-1,y,enabled);
SetCubeEnabled(x,y-1,enabled);
SetCubeEnabled(x+1,y,enabled);
SetCubeEnabled(x,y+1,enabled);
}
void SetCubeEnabled(int x, int y, bool enable) {
if (x >= 0 && x < gridW && y >= 0 && y < gridH && grid[x,y] != null) {
grid[x,y].enabled = enable;
}
}
This should be sufficient to do the basics of what you want without relying on the physics system. Although relying on the physics system is a viable option as well, as I outlined above.