Offsetting sprite based on extants instead of center

I’m working on a game whose entire play space is divided into an imaginary 2d grid, and figuring out which grid square the player is clicking on by taking the mouse coordinates and dividing them by the size of each square:

  public struct Grid2D
  {
  public float height;
  public float width;

  public Vector2 WorldToGrid(Vector3 worldCoords)
  {

  float xCoord = (int)worldCoords.x / width;
  float yCoord = (int)worldCoords.y / height;

  Vector2 gridCoords = new Vector2(xCoord, yCoord);
  return gridCoords;
  }

  public Vector3 GridToWorld(Vector2 gridCoords) //Doesn't work yet
  {

  float xCoord = gridCoords.x * width;
  float yCoord = gridCoords.y * height;

  Vector3 worldCoords = new Vector3(xCoord, yCoord, 0);

  return worldCoords;

  }
  }

This kinda-sorta works, in the sense that it does correctly divide the world into an arbitrary number of squares of dimensions height/width, but I’m having a lot of trouble getting sprites to snap inside these squares- whenever I set a sprite’s transform.position equal to GridToWorld(vector2Coords), it centers itself on the edge of the square instead of the center. I made a little illustration, the black square indicates the space that Grid2D identifies as (0,0), and the red square indicates where a 1x1 sprite appears if I spawn it at GridToWorld(new Vector2(0,0)).

Is there (hopefully) something wrong with my logic, or is this a case where I need to be hardcoding a spawn offset for every single sprite based on its dimensions?

If you have a grid size of 1, your objects will snap to 0, 1, 2 and so on. The grid positions are where the lines meet, not in the rectangles middle, like you have discovered. One of the easier ways to fix this is to align your objects pivots to a corner, say lower left. Or you can just offset by half the grid size.

Ooh, the pivot is a really clever idea, I hadn’t thought of that… a few minutes of research seem to imply that if I place a sprite on the core gameobject, the pivot will always be in the center- am I right in thinking that the best way to actually move the pivot is to make the core gameobject (with all the scripts/logic/whatever) empty, then place the sprite renderer as a child that has whatever local offsets I need applied to it?

You can also edit the sprite pivot in the sprite editor on the texture importer.
Sometimes it is beneficial to separate visuals from the core game object, like you describe, gives a lot of flexibility, but it also leads to more gameobjects, which might be bad if you already have too many of them.

I don’t have that many, so it should be fine… on average I have 30-40 gameobjects in the sprite pool, about the same number for the core traversable area, and that’s about all. I’ve seen projects run butter-smooth with hundreds or low thousands of gameobjects, and since the per-object overhead is pretty low (it’s just sprite renderers, for the most part), I don’t see a problem… thank you very much for weighing in :slight_smile:

Yeah, I was thinking about tens of thousands when talking too many :slight_smile: