Grid drawing problem

Hi,

i am new to Unity and hope that someone can help me with a problem i have.
I would like to achieve something similar like shown in the image below and i don’t know how to implement it with Unity.

Basically i need to draw a grid with lines on a specific area of the terrain. Then, based on some actions during gameplay, some tiles of grid need be filled with a solid color, showing for example where a Unit on the field can move or shoot. Then there should be a possibility to hide/show the grid

Would the Line Renderer be used for that kind of problem. Or would it be better to draw single quads with textures on them? Is maybe a projector the solution? Or does anybody have a better idea?

I tried out the LineRenderer, but i didn’t get it to work the way i want it.
So i would be really happy if someone can point out some hints or tips how to achieve drawing the grid.

thanks,

cheers
Mike

49106--1808--$grid_570.jpg

It all depends on exactly what you want in terms of graphics and terrain. Will it always be flat? Do you want a tiled look, or would you prefer the ground texture to be separate from the grid? And so on.

I would probably keep the two separate and create a quad object that’s semitransparent (or if you shoot for low-end hardware, opaque “frames”) and place these on top of the terrain whenever you need to display terrain cost, etc.

thanks for your answer dfvdan.

The terrain will not always be flat. Depends on the Map the players play on. Some maps may be indoors, like a dungeon, some outdoors on terrain with hills and so on. The possibilities are endless. The grid should like project onto the scene, with all the elevations and so on. And the terrain texture must shine through, like in the image i attached. So the grid must be transparent.

The player should be able to hide the grid, so that only the terrain will be visible. But if he takes an action, like selecting a unit on the field and choosing for example the move action, all possible tiles where the unit can move should be highlighted.

So my basic question is firstly, just how would i go about implementing a basic grid on the whole playing field and secondly, highlight parts of the grid after certain user acions. I don’t know if i should draw lines , use quads with textures and so on or use a projector to project a grid on the field.

What do you mean by ‘opaque frames’? how would i do that?

What would be the performance issue if i use hundreds of quads on top
of the terrain?

thanks for your help.

Mike

I think this is more a aesthetic decision than a technical one. How do you want it to look? Do you want the terrain to be “grid based”, or smooth? Do you want the grid to follow the terrain exactly (then I would lean towards projection), or more be an overlay (then I’d use separate objects).

With “opaque frames” I meant non-transparent polygon-based frames that you would place above the terrai, just to frame a portion of it. Again, that’s only if you think transparency might be a problem.

OTOH, I don’t think transparency would be a performance problem. I’m sure someone can correct me if I’m wrong, but a 10-100 transparent quads that all share the same texture shouldn’t be a problem. Transparency sorting might be though, but that’s solveable.

Again, it’s a problem with a multitude of solution. It’s hard to say which one is right. :wink:

Actually the terrain should look smooth and the grid should appear as if
it were projected onto it. That’s why i thought about using a projector. But the grid size should be dynamic, so i don’t know how you would project a fixed grid texture onto the terrain.

So i think that using overlays would be a great idea.
But depending on the map size, the number of quads can go into the thousands and not hundreds. That’s why i thought about drawing lines to show the basic grid. And on top of it draw some quads that show for example all the possible tiles a character can move to, which should be less than 100.

But i didn’t get the LineRender to work to draw hundreds of lines on top of the terrain. I even want to start small and draw maybe a 10x10 grid onto a plane, but i don’t have a glue how to start.

may you can help.

thanks
Mike

Using the linerenderer is pretty straightforward, just check the docs for the class. You’d set the number of vertices to the number of grids you want to cover with each line (to be able to adjust to the terrain height) and then just draw X * Y lines depending on the grid size.

You would probably have to do a raycast or something to determine the terrain height at each vertex, but you would only have to do this once (assuming the terrain is static).

thanks for your help dfvdan.

I tried to use the linerenderer based on the docs, but i can’t seem to get it
work. It won’t show any lines. I’m probably doing something wrong.

Coming from an OpenGL background, i assumed that it would behave like drawing lines in gl. Looking at the docs, they add a texture (a flame or so) to the material shader. Is that the texture the line that i am supposed to see, or does it fill the regions between lines, like it would fill a tile in the grid, which contains 4 lines ?

Can you please explain the line renderer a little bit further? So to get me started drawing a grid. Is it possible to fill single quads of grid with different textures/colors when using the line renderer, or do i need multiple linerenderers? Or do i need to use a combination of a line renderer and drawing textured quads to achieve this?

any help concerning the line renderer and how to draw a scene like in the image would be a real help.

thanks
Mike

The line renderer is a bit confusing, as I seem to remember the docs being a bit contradicting. You want to read the scripting reference, and ignore the component reference as I never made any sense of the description of the line array.

In practice, it works like this:

  • each object with a linerenderer draws ONE line, with a defined number of segments. You define this by setting vertexcount for the linerenderer component.

  • you assign a material, which can be useful if you want smooth edges or some other effect. You could use this to indicate terrain cost or whatever

In your case, since you need a grid and each linerenderer only draws one line, you’ll have to decide how to combine lines to get the grid you want. (Do you want each line to draw one grid square, or make up one “gridline” - ie. a set of lines in the X direction and another set in the Y direction.

Creating a line in javascript looks something like this:

//moveLineSource is my line prefab
moveLine=Instantiate(moveLineSource,Vector3(0,0,0),Quaternion.identity);

numVerts = 2;

moveLine.GetComponent(LineRenderer).SetVertexCount(numVerts); //<<--- this defines the number of segments

moveLine.GetComponent(LineRenderer).SetPosition(0,some_position); //<<-- sets the position of the first vertex.

moveLine.GetComponent(LineRenderer).SetPosition(1,some_position); // second vertex

I still would consider the transparent overlay approach. I think it could look nicer, and any performance problems can certainly be worked around / solved. The linerenderer approach however would be quite quick, as I remember someone (Yoggy?) having a project with a pretty big number of lines going on.

Good luck!

thanks dfvdan, you’ve been a great help.
I may try both options tomorrow.

Personally, i also like the transparent overlay method more.
What would be the best approach for the overlay method?
Use the Graphics.DrawQuad Method? Or build a mesh in Cheetah or any other modeller? How would you go about implementing it?

thanks again,
Mike

The advantage of runtime mesh/quad creation would be that it’s probably easier for you to get a seamless, terrain following mesh that way. I’m not sure about Graphics.DrawQuad though, check out the example package dealing with mesh creation/deformation for some ideas.

I don’t know if this will help, but I’ve created grids using Illustrator and then mapped them onto plane objects in C4D so that the grid corresponds to the plane’s lines, then divided the plane into separate quads. Then in Unity, I can manipulate each quad to act independently of each other as separate objects, scripting different texture effects, scrolling and color changes into each one, depending on how it’s triggered… In your case, you could lay the planes/grids side by side and make each one inactive until the player enters into it. Or you could instantiate/destroy it in a particular position. You could use an alpha texture showing only the grid lines and have the plane hovering slightly above the ground (without using a collider, of course). You could set up each quad as a trigger.

I realize it’s trickier with hilly terrain, but you could separate and duplicate squarish sections of the hilly parts and do the same kind of texturing and separation into quads.

I’m trying to do something like this, using a projector to display a grid texture over a terrain, and its working except that I can’t get the material cookie tiling to affect anything. Is this a known bug or is there something I am missing?

If anyone has a working example of this kind of grid they would be happy to post it would be a great help.

Even some basic code could point me in the right direction.

thanks

Not sure if you have already created a solution to this problem or if its alright to reply to a old post like this.

But here is a script that will change a plane so that it has the same shape as the terrain under it.

using UnityEngine;
using System.Collections;

public class GridPlane : MonoBehaviour {

    public float PlaneSizeX = 10;
    public float PlaneSizeZ = 10;

    // only change if using with a custom created plane that has a different number of segments
    private int m_planeSegments = 10;

	// Use this for initialization
	void Start () {
        UpdatePlane();
	}
	
	// Update is called once per frame
	void Update () {
      //  UpdatePlane();
	}

    /// <summary>
    /// Update the plane so that its the same shape as the terrain under it
    /// Call after the position of the plane has changed
    /// </summary>
    public void UpdatePlane()
    {
        Mesh mesh = ((MeshFilter)GetComponent(typeof(MeshFilter))).mesh as Mesh;
        if (mesh != null)
        {
            Vector3 position = new Vector3(transform.position.x+ (PlaneSizeX/2), transform.position.y, transform.position.z+(PlaneSizeZ/2));
            Vector3[] vertices = mesh.vertices;
            float xStep = (PlaneSizeX / m_planeSegments);
            float zStep = (PlaneSizeZ / m_planeSegments);
            int squaresize = m_planeSegments + 1;
            for (int n = 0; n < squaresize; n++)
            {
                for (int i = 0; i < squaresize; i++)
                {
                    vertices[(n*squaresize)+i].y = Terrain.activeTerrain.SampleHeight(position);
                    position.x -= xStep;
                }
                position.x += (((float)squaresize) *xStep);
                position.z -= zStep;
            }
            mesh.vertices = vertices;
            mesh.RecalculateBounds();
        }
    }
}

To Use:

  • Create a Plane gameobject and then add that script to that object.

  • Set PlaneSizeX and PlaneSizeZ to the scale (of the gameobject) * 10. So for a default plane with scale 1,1,1 leave them at 10.

  • Set the Y position of the gameobject to just above the base height of the terrain. So around 0.15f seems to work.

  • Add your transparent grid texture/material. (to change the colours of the grid squares you could draw to the Texture)

  • Then just call the UpdatePlane method any time the gameobject/plane moves position.

Note: If you want better resolution, then you would need to use it with a custom created plane mesh that has more than 10 segments (and change the m_planeSegments field to match)

do u have any project example for creating such a grid like the image above??
i know its maybe clear for some of you how to do it but am really having a hard time doing it… so if there’s a simple project, it will help me a lot :slight_smile:

Best Wishes

Heya Mike,

Did you end up getting a solution to this problem? I’m trying to achieve something similar and have yet to find anyone that knows how it can be accomplished.