Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Creating and snapping to a grid?

Discussion in 'Scripting' started by astralislux, Aug 27, 2014.

  1. astralislux

    astralislux

    Joined:
    Aug 8, 2014
    Posts:
    10
    I'm trying to create an in-game grid so the player can position objects. I'm new to Unity and C# programming, but I'm familiar with programming.

    I've been looking at some grid examples and I've found several links to the following code:

    Code (CSharp):
    1. Vector3 currentPos = transform.position;
    2. transform.position = Vector3( Mathf.Round( currentPos.x / gridSize.x ),
    3.     Mathf.Round( currentPos.y / gridSize.y ),
    4.     Mathf.Round( currentPos.z / gridSize.z ) );    
    How would I implement this as a method to create a grid?

    For example, I have the player carrying an object. As the player selects a position to drop an object, I want the object to snap to the grid, then when it's dropped (or mouse-clicked) it positions on a grid point -- that's the concept, at least.

    I've been looking for a tutorial how to do this, but every answer I've found simply posts the code above, presuming everyone would know how to implement it.

    Below is my grid where I apply it to a plane prefab, if this is of any help:

    Code (CSharp):
    1. public class Grid : MonoBehaviour {
    2.  
    3.     public GameObject plane;
    4.     public int width = 10;
    5.     public int height = 10;
    6.  
    7.     private GameObject [,] grid = new GameObject[100,100];
    8.  
    9.     void Awake()
    10.     {
    11.         for (int x = 0; x < width; x++) //width
    12.         {
    13.             for (int z = 0; z < height; z++) //rows/height
    14.             {
    15.                 GameObject gridPlane = (GameObject)Instantiate(plane);
    16.                 gridPlane.transform.position = new Vector3(gridPlane.transform.position.x + x,
    17.                                                            gridPlane.transform.position.y,
    18.                                                            gridPlane.transform.position.z + z);
    19.                 grid[x,z] = gridPlane;
    20.             }
    21.         }
    22.  
    23.  
    24.     }
    25. }
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    So first of all - don't make a grid out of individual GameObjects. The performance simply won't be good enough.

    Secondly - the approach is pretty straight forward. You just round each component of the position to the nearest grid increment. So if your grid is in 1 unit increments (which it looks like it is) then simply rounding to the nearest whole number will do it.
     
  3. astralislux

    astralislux

    Joined:
    Aug 8, 2014
    Posts:
    10
    I'm understanding, I think, so find the position via raycast where I'm dropping the object, then round that to the nearest whole number.

    As for producing a grid, any recommended tutorials?
     
  4. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    If you're just trying to show a grid visually you can fake it with a texture - otherwise you're in the realm of building the mesh at runtime which is a bit more complicated.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    If your grid is dynamic, I might recommend Vectrosity, in the asset store. I've been impressed with it. As I recall, it comes with a demo of its application to drawing a grid, and the performance was impressive.

    Of course if your grid never changes at runtime, then a big plane with a repeated texture could work just as well.
     
  6. astralislux

    astralislux

    Joined:
    Aug 8, 2014
    Posts:
    10
    Forgive my ignorance because I'm new to Unity (but not programming).

    Using this grid script, I must have a grid object that it references? I understand my current grid is bad because it's created with multiple objects. I don't need that. And I only want the grid behavior, I don't need to see the grid.

    For clarity, you're saying I must have a grid object for this script to work?

    Code (CSharp):
    1. Vector3 currentPos = transform.position;
    2. transform.position = Vector3( Mathf.Round( currentPos.x / gridSize.x ),
    3.     Mathf.Round( currentPos.y / gridSize.y ),
    4.     Mathf.Round( currentPos.z / gridSize.z ) );
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Your grid "object" can be a 2 dimensional array of Vector3's. Having them be GameObjects is a bad idea though.
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I don't think even the array of Vector3's is needed. Astra, if by "grid" behavior you just mean that you want objects to snap to some regular arrangement of rows/columns, then just take that original rounding code, and apply it wherever the object moves. For example:
    OK, objects dropping doesn't just happen — there's some code that implements "remove this from the player's inventory, and stick it in the world" (which may mean just changing the parent to nil).

    So, find that code, and then insert the rounding code from your first post. Boom, done. Now when the object is placed into the world, its position is also snapped to this imaginary grid.

    Why don't you try that, and then explain where you got stuck, including what happened and how this was different from what you wanted/expected.
     
    astralislux likes this.
  9. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    687
    If you do need a visual grid, it's very easy with a texture that's just a one-pixel (or thicker if you want) white box/border over a transparent background. Change the tiling settings for X and Y to suit. And using white means you can tint it if you use a shader that provides tinting.