Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Grid placement

Discussion in 'Scripting' started by Lycoon, May 26, 2018.

  1. Lycoon

    Lycoon

    Joined:
    Apr 27, 2018
    Posts:
    4
    Hello there,

    I'm familiar with C# but new to Unity. I have troubles in making a grid placement system, similar to Clash of Clans or Simcity. I know the subject had already been treated by many but none is helping me for what I'm looking for. I have 3D models of buildings that I want to place according to a grid, however, buildings can have 7*9 cells of width/height, and I don't know how to deal with it. I success in placing these buildings freely but not according to a grid. Thanks.
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Isn't this just a case of using a division of the placement position? For a 2D example,
    Vector2( ((int) x) / 7, ((int) y) / 9 )
    .
     
    Lycoon likes this.
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    Are you sure you can't make your buildings 8x8 cells instead? That would make life dramatically simpler for both you and the player...
     
    Lycoon likes this.
  4. Lycoon

    Lycoon

    Joined:
    Apr 27, 2018
    Posts:
    4
    Using 7*9 dimensions was just an example, I don't want all my buildings to be squares. Some of them will be of 2*5 or maybe 11*7 etc. Even if my buildings would be squares, it doesn't solve the problem of placing my prefabs on several cells according to the grid.
     
  5. Lycoon

    Lycoon

    Joined:
    Apr 27, 2018
    Posts:
    4
    Yes, sure, but how could I do, to make the model be exactly placed on the number of cells I want. Do I have to ask my 3D designer to create its models scaled for a grid, like making the buildings with units depending on how many there will be in the game. For instance, a building of 4*7 has to be designed as it on the 3D Editor ? Can't I scale it with round units in Unity without modifying the shape of it, I mean, only rescaling the base in order to fit to the 4*7 cells.
     
  6. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    You might want to make sure your models are 'sensibly' scaled. So, for example, you may want to view them in Unity with a scaling factor of (1, 1, 1). But I'm unclear as to how that affects a grid system in any way? You could just get some models, place them in the Editor and see how they look and place them at appropriate intervals to suit your grid.

    Yes, if you select the object in the Editor, the scale details are part of the object's transform data in the inspector. Those values are adjustable from within your C# code via the
    transform.localScale
    .

    Are you asking if you can change the base vertices of the model, whilst leaving the higher vertices alone (so, in effect, tapering the building down to the ground)? If so, then you would have to adjust the mesh filter. But that sounds like a lot of hard work to me. :)
     
    Lycoon likes this.
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    Well actually it does. Then all you have to do is round to the grid size, and look up in a simple 2D array whether there's already something there.

    But you need your buildings to be rectangles, so you need your collision array to be at a higher resolution than the objects you're placing. And when checking the grid, you have to take into account the rotation of the building, since that will change it from 11x7 to 7x11 (for example).

    So it's a lot of bookkeeping. There is no trick to it; you'll just have to write a fair amount of code. Create a 2D array for the cells, where each entry is a reference to the building in that cell; you'll also need code that can compute the set of cells for any given building size, position, and rotation. Then you use these when placing a building to check whether it overlaps something already there, and to update the cells array once you place it down.
     
    Lycoon likes this.
  8. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    The trick is to put them in an empty game object (and create a prefab out of them), position the model in relation to the empty game object's position on a way that the empty GO's position will be the place where your grid is positioned.
    Also inside the empty GO your actual model can be rotated and scaled locally. So at the end you will do your math just in units, no fuss with the scales and local positions.
     
    Lycoon and Doug_B like this.
  9. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,886
    Here is the grid snapping code I use in my GridManager:
    Code (csharp):
    1.  
    2. public Vector3 RoundVector3(Vector3 vector, float multiple)
    3.    {
    4.        // Round a Vector 3 to nearest multiple. // https://stackoverflow.com/a/29557629
    5.        return new Vector3(
    6.            Mathf.Floor((vector.x + multiple / 2) / multiple) * multiple,
    7.            Mathf.Floor((vector.y + multiple / 2) / multiple) * multiple,
    8.            Mathf.Floor((vector.z + multiple / 2) / multiple) * multiple
    9.            );
    10.    }
    It's used like this:

    Code (csharp):
    1. [Header("Info")]
    2. public Vector3 _currentlyHoveredWorldPositionSnapped;
    3.  
    4. [Header("Settings")]
    5. public float _gridSnap = 1f;
    6.  
    7. void Update()
    8. {
    9.     Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    10.     RaycastHit hit;
    11.  
    12.     if (Physics.Raycast(ray.origin, ray.direction, out hit, _raycastDistance, _layerMask))
    13.     {
    14.         _currentlyHoveredWorldPositionSnapped = RoundVector3(hit.point, _gridSnap);
    15.     }
    16.  
    17.    
    18. }
    For placement validity, I just brute force this with a permanent GameObject called PlacementValidator that changes the amount of BoxColliders it has based on the building I am placing. It allows L-shaped buildings, etc.

    It is snapped to the grid instantly, so the visual of the building isn't the thing checking for collisions. It's the invisible PlacementValidator instead.

    This way, you can have the building smoothly be dragged around, instead of snapping instantly like an old-school game.
     
    Last edited: May 27, 2018
    Lycoon and Doug_B like this.
  10. Lycoon

    Lycoon

    Joined:
    Apr 27, 2018
    Posts:
    4
    Thank you all for your answers !
     
    Doug_B likes this.