Needing Direction

So I have my general test build of a tower defense game down, however I want to create a grid overlay on my terrain, and have the structures only be built within those squares, I’ve been searching everywhere, but have had no luck…

I need to know a good direction to go in, in regards to researching how to go about building the visable grid, with restrictions on what the player can do within the grid. Any help would be appreciated :slight_smile:

This would be a good thing to sketch out if you can; roughly how you’d like it to appear and function. For now, here are some questions…

Are you using Unity’s terrain?
If yes, is this important to you?
What platform are you targeting?

The easiest route is to simply create a grid of tiles that are all separate game objects and maintain them in a coordinate system. If you want to do it on terrain, well, things become more interesting.

Step 1: Displaying the grid
I would do this at run time so that you can ensure it’s set to the proper size/position

Spawn a projector, set it to the exact center of your terrain looking directly at the ground from a distance.
Set the projector to orthographic, make the orthographic size = Mathf.Max(terrain width, terrain height) * 0.5
Set your grid image as the projected graphic
Set your projector to ONLY project against the terrain

Step 2: Creating the grid
Create a multidimensional array to store information about your grid - what data type you use is entirely up to you. To keep things as simple as possible for this example, lets use bools
bool[×][y] gridOpen - set the values all to true to start

Step 3: Coordinate System!
This is where you’ll need to do a bit of mathy work. You need to define:

  1. The origin of the grid (whichever corner of your terrain you’d like to consider 0,0 on the grid)
  2. The scale of the grid in world units (how large a single cell on your grid is). If you have a 10x10 grid and your terrain is 100x100 size in Unity each of your cells are 10x10

Write some simple functions for easy use later like:

bool GetGridStatus(Vector3 worldPoint){} <— Uses worldPoint to figure out which grid cell contains that point, returns the next overload…
bool GetGridStatus(int x, int y){} <---- Uses the x,y coordinate on the grid to get the status from your multidimensional array
void SetGridStatus(Vector3 worldPoint, bool newStatus){} <— same thing, but with set
void SetGridStatus(int x, int y, bool newStatus){} <— same thing, but with set

The next two functions will be for actually placing towers, pathfinding, and projecting the optional feedback brush.
Vector3 GetGridCenter(Vector3 worldPoint){}
Vector3 GetGridCenter(int x, int y){}

Note: You should only need to take the x/z coordinates into consideration here, y has no impact on your grid

Step 4 (Optional): Give feedback to your player!
Create a second projector much in the same way as the first - however, you’ll make it sized so that it only fills the area of a single cell. This projector will use one of two materials, lets say a red square and a green square. It would follow the mouse around; however, instead of following exactly to the mouse position have it snap to GetGridCenter(mouse-ray hit point) so that it locks to your grid.

Step 5: Create game logic
Now you have your grid all set up and you can start writing scripts like…

// sloppy pseudo-code

if (Input.GetMouseButtonDown(0)){
// do a raycast to figure out where on the terrain the mouse is over
if (GetGridStatus(raycast hit point)){
PlaceTower(raycast hit point);
}
}

void PlaceTower(Vector3 worldPos){
SetGridStatus(worldPos, false);
// Instantiate your tower at GetGridCenter(worldPos);
}

Obviously that’s just one super quick-dirty method for creating a grid system on the terrain, and you almost certainly do not want to use bool[ ][ ] - you’ll want to create your own data type like GridNode that contains all the information you need to store about each position. The important part here is:

  1. Use a projector to create the grid on the terrain
  2. Write a method for converting a world position to a GridNode