I'm trying to draw a grid around the cursor that represents buildable area.
this cursor grid, aligns to the global grid. all building placements must be on the grid and so this visual queue must aid in understanding that.
I also will have deforming terrain.
here's what I got so far, this is a grid drawing method that uses GL.Lines :
(by the way I'm using the Cartesian Coordinate system so that's why I iterated over x and y instead of x and z don't let that throw you off, y is not 3D height in the following)
private void drawSize50Grid(int entryX, int entryY)
{
if (!mat)
{
Debug.LogError("Please Assign a material on the inspector");
return;
}
int amountOfGridToDraw = 50;
GL.Begin(GL.LINES);
mat.SetPass(0);
float currentX = entryX;
float currentY = entryY;
for (int x = 0; x < amountOfGridToDraw; x++)
{
for (int y = 0; y < amountOfGridToDraw; y++)
{
//divisionFactor is float which makes the grid the size I want (smaller than the unity visual queue when you have nothing in a scene)
float nextX = divisionFactor/100f + currentX;
float nextY = divisionFactor/100f + currentY;
// fixed height of 0.0001f, this is temporary, I'll pass height when I get there.
var point = new Vector3(currentX, 0.0001f, currentY);
var drawPoint2 = new Vector3(nextX, 0.0001f, currentY);
var drawPoint3 = new Vector3(currentX, 0.0001f, nextY);
GL.Color(Color.red);
GL.Vertex(point);
GL.Vertex(drawPoint2);
if (currentY != amountOfGridToDraw)
{
GL.Vertex(point);
GL.Vertex(drawPoint3);
currentY += divisionFactor/100f;
}
}
currentY = 0f;
currentX += divisionFactor/100f;
}
GL.End();
}
here's my point conversion methods :
public Vector3 GetNearestPointOn3DGrid(Vector3 position)
{
position -= transform.position;
Vector3 result = new Vector3(
// width
magicFormula(position.x),
// length
magicFormula(position.z));
result += transform.position;
return result;
}
private float magicFormula (float entryPoint)
{
float decimalPart = entryPoint % 1;
float intergerPart = entryPoint - decimalPart;
return Mathf.RoundToInt(decimalPart / (1 / divisionFactor)) * (1 / divisionFactor) + intergerPart;
};
If I call my grid in this way :
void OnRenderObject()
{
drawSize50Grid(100f, 100f);
}
Then, when I run the game, my grid shows up starting at (LeftHand coordinate system) point 100f,0.0001f, 100f.
But OnRenderObject()
is called only once.
This lifecycle will not allow me to have a grid that follows the cursor.
Also it seems that this is a GL.Line hard limit : they cannot be redrawn at runtime.
I realize drawing and redrawing tons of segments as the mouse zooms around is bound to be taxing to the CPU & GPU but I've tampered my expectations :
// I guess I would call drawGridAroundCursor() inside Update()?
// right now doing this does nothing because GL.Lines refuse to draw after OnRenderObject()
public void drawGridAroundCursor()
{
if (camera.GetCurrentDistanceToGround() < 60f && isShiftCurrentlyHeldDown)
{
gridAdjustedCursor = GetNearestPointOn3DGrid(cursorRayHit);
drawSize50Grid(gridAdjustedCursor.x, gridAdjustedCursor.z)
}
}
- I'm only doing 50x50 grid (that's 4950 lines) (actually I'm willing to go down further than that 15x15 might cut it)
- I'm only rendering the grid if the camera is close to the ground (where it shows up)
- and only showing it when holding down shift.
that should limit the load.
But if there's even more things I can do to optimize I'm open to ideas, so long as it doesn't involve sacrificing correct placement of the lines.
here's what my above code WOULD look like if it rendered at real time :
(camera viewing straight down at the terrain, also not at all to scale, the cursor is GIGANTIC in this mock-up)
And in the end here's what I'm going to do (draw from -25 -25 relative to grid-adjusted to cursorRayHit and chose a more and more transparent color the further the point are to the center of the grid) :
so obviously when the cursor moves the faded out borders follow it around but the grid points will stay in place (and go transparent when the cursor is too far away)
This effect was inspired by this :
And after I get to that step I want to add height variation to match the terrain and then add color input per cell of the grid depending on whether or not the terrain is constructible or not.
So the final solution would look something like this :