- Home /
Grid on uneven terrain
I made a grid using Quads. I added a texture to each and wrote a script for the quads' parent.
Here is the scene before the script:
and here is the scene after the script was applied:
This is my script:
Ray ray;
RaycastHit hit;
public float aboveAmount = 0.5f;
void Start () {
foreach (Transform c in transform) {
if (Physics.Raycast (c.transform.position, -Vector3.up, out hit)) {
c.transform.position = new Vector3 (hit.point.x, hit.point.y + aboveAmount, hit.point.z); // set position
} else if (Physics.Raycast (c.transform.position, Vector3.up, out hit)) {
c.transform.position = new Vector3 (hit.point.x, hit.point.y + aboveAmount, hit.point.z); // set position
} else {
Debug.Log ("couldn't hit anything");
}
}
}
It casts a ray from every tile and puts the tile on the terrain (a fixed amount above it).
I would like the deform the quad's mesh to make it sit on the ground. I idea would be this: cast 9 rays from every quad (corners and inbetween) and deform the mesh to place every point onto the ground. But how would I achieve this in reality?
If there is a better way of creating a dynamic grid, then I would love to know about it. I need every tile to be a prefab, which can be clicked on. This isn't a problem yet, as I'm using box colliders.
Witha grid of this size, you will soon run into performamnce problems if every tile is a sperate gameobject. You better use one mesh with multiple quads and handle the tile selection programmatically (as opposed to collision-based).
Answer by Torigas · Jul 24, 2015 at 02:18 PM
i agree with Cherno, this might cause huge performance issues. Optimizations might include showing / generating the grid in just a small area around the player.
Nonetheless, one way to do this would be to create a Mesh for each grid element and do a raycast or do a terrain height sample at the corner positions.
here they explain on how to create a custom mesh object. Simply put, you have to create 4 Vertices at the Terrain position. http://docs.unity3d.com/ScriptReference/Mesh.html
An alternative would involve a whole lot more scripting but here's the basics of a possible solution:
Given a terrain with a certain size you know the width and height. (float w, float h) You also know the density of your grid --- so you know the size of one tile (float tileW = tileH) So you could technically create a two dimensional array with your grid tiles as a logical element. You also know where the user clicks (raycast and check where it hit). Taking into account the width and height and the size of one tile you can write a function that returns the grid tile which was clicked. (something like
Tile[,] grid;
Tile getTile (Vector3 clickpos)
{
return grid[(int)(clickpos.x/w), (int)(clickpos.y/h)];
}
To get the visualization you can create one "huge" mesh with the method explained above. Just create a new Mesh, take the Vertex positions by sampling the Terrain height at their positions and set the UV coordinates of the vertices to match your tile texture. Meaning the bottom left vertex of a tile should be like 0,0 -- the bottom right at 1,0 and so on.
Thanks, however I will stick to the multiple-mesh way. I need to be able to select each tile and replace its material at run time. I don't see how I would be able to do that with I mesh. Here is what I mean:
You can get the world position of the point the mouse cursor is at with RayCasting. This in turn gets you the coordinates of the tile.
If you take a look at this: http://answers.unity3d.com/questions/15832/how-to-create-a-procedural-mesh-with-multiple-mate.html
You can actually use that. So just assign two materials to the huge mesh etc.
However, considering the picture you just posted, i think you're good for performance. 256 GameObjects doesn't seem too bad.