Mathf.Round makes Tiles snap to grid-intersection instead of grid

I am trying to place thing on my grid in-game, I use the following Script:

Vector3 pos = new Vector3(Mathf.Round(transform.position.x), Mathf.Round(transform.position.y), transform.position.z);
Instantiate(wheat_seed, pos, Quaternion.identity);

This code does snap objects as it should, however it does not land them in the Unity Grid, it lands them in the intersection. In the gif below, the top-line of seeds are placed manually through the editor, as you can see, the one I place in-game are placed in the intersection of 4 grids.

(For some reason inserting it will not work, GIF is here: http://g.recordit.co/IV76GUWtPV.gif

The only way I found around this is a hacky solution where I set the pivot of the seeds to bottom right, then use the following code:

Vector3 pos = new Vector3(Mathf.Round(transform.position.x+0.5f), Mathf.Round(transform.position.y-0.5f), transform.position.z);
Instantiate(wheat_seed, pos, Quaternion.identity);

That code, together with changing the pivot, places the seeds right underneat my player and on the correct grid-location, i.e the middle of a grid-unit.

This solution is really ugly though, surely there must be a better way?

if you want to place seeds in the feet of your player, you have 2 options, one easy and another quite easy.

easy: make the player’s pivot be at bottom center, then you just need to instantiate the seeds in the player’s position.

quite easy: supposing you player has a SpriteRenderer and its sprite has the pivot on center, you can find feet position like this:

float y = transform.position.y - ((renderer.bounds.size.y/2) * transform.localScale.y);
Vector3 feetPosition = new Vector3(transform.x, y , transform.z);

and then you can instantiate the seeds on feetPosition.
PS: you don’t need to worry if your player has been scaled, the localScale will fix whole thing

Thanks for trying to help m8. But the first option is the first thing I tried :slight_smile: My players pivot is at the bottom. And adding the seeds with a center pivot makes the land at the intersection of the grids Im afraid. But indeed at the bottom of my players feet.

It seems the onyl thing that makes a difference is changing the pivot of the seed. Chaning the players pivot only affects what position the seed lands, but still gets snappet to an intersection

Please does anyone know how to solve this without setting pivots on each sprite? setting pivots to bottom-right makes it so that all colliders etc need an offset, and that in turn leads to raycasting being offset. It’s just kinda of a nightmare. IS there anyone who can help with this?

To be clear: What I need is for Mathf.Round to snap my GameObjects to the middle of the unity grid. This is only possible when setting pivots of the sprites to bottom-right. If the pivot is center, the GameObject gets placed at the intersection between 4 grids.I want to somehoe be able to keep my pivot in the center.

I don’t know enough about your setup to give a specific answer but in general I would recommend to decide for one pivot system (if nothing speaks against center, keep center) for all objects.

From the looks of it you just need to offset the grid by 1/2 of the grid size. Either adding 0.5xgridsize to each coordinate before rounding or by placing the objects as is as a child into an offset gameobject with local coordinates

Hi, the first thing I tried was adding 0.5 before rounding (with center pivot) like so:

transform.position = new Vector2(Mathf.Round(mousePos.x + 0.5f), Mathf.Round(mousePos.y + 0.5f));

But this just lead to the GameObject snapping to the intersection of grids next to where it would’ve landed otherwise, it does not land inside the actual grid, for this I think you cannot have pivot center. Not sure how to implement your second idea.

Technically I could set the pivot of everything in my game to bottom-right. I just dont like how that forces me to offset all my colliders etc.

Try to put it on grid paper and figure it out without coding. It can make a difference if you have even or uneven object / Sprite dimensions (assuming you go for something pixel perfect).

I am also not saying 0.5 / i am saying 0.5 x size

Ps: if you can do it manually you can do it in code. Just reverse the process to figure it out :wink: - you can have the pivot in the center, it’s less intuitive if you come from a background with with corner pivot (like me ie c64 sprites) but it is just offsetting coordinates

2nd approach: while you are in play mode just create a new empty game object in the scene. Drag all instantiatied objects under it, then offset its position for the tiles to be in the correct space.

Later you just instantiated this empty object in code at this offset and then set it as parent for the other instantiated objects and set their positions relative to it (transform.localposition)

Same as first approach but instead of changing the formula you just do the adjustment in a parent container object

If you want to change the pivot, stick with bottom left or top left. This Is more common

Thanks for your advice :slight_smile: My sprite dimensions are 16x16, with 16ppu. I will prob end up going with changing pivot.