Snap to grid system - cross selection?

Hello,
I made a Snap to grid system.
To make this system, I used Mathf.RoundToInt() function. It works well.
If snapsize is 10, system return value with 10x grid.

But the problem is… I can’t return cross position directly.
It always go through the x- and z-axes.

I thought a method like, when the position is in the green box below, return cross position.
But I failed to make it code…

Vector3 SnapToGrid(Vector3 pos, int snapsize)
    {
        int x;
        int z;

        if (pos.x < 0)
        {
            if (pos.z < 0)
            {
                x = Mathf.RoundToInt(Mathf.Abs(pos.x / snapsize)) * snapsize * -1;
                z = Mathf.RoundToInt(Mathf.Abs(pos.z / snapsize)) * snapsize * -1;
            }
            else
            {
                x = Mathf.RoundToInt(Mathf.Abs(pos.x / snapsize)) * snapsize * -1;
                z = Mathf.RoundToInt(pos.z / snapsize) * snapsize;
            }
        }
        else
        {
            if (pos.z < 0)
            {
                x = Mathf.RoundToInt(pos.x / snapsize) * snapsize;
                z = Mathf.RoundToInt(Mathf.Abs(pos.z / snapsize)) * snapsize * -1;
            }
            else
            {
                x = Mathf.RoundToInt(pos.x / snapsize) * snapsize;
                z = Mathf.RoundToInt(pos.z / snapsize) * snapsize;
            }
        }

        return new Vector3(x, 0, z);
    }

Not sure which approach you are would like but it seems you are overthinking it. You can just round which will snap in an area around a point, you can use floor which will snap to the lowest value or ceil which will snap to the higher values. If you are dealing with negative positions though, I find the round is the best option.

Try these and see which one feels the better for your game

private Vector3 SnapToGridRound(Vector3 pos, float snapDistance)
{
    pos.x = Mathf.Round(pos.x / snapDistance) * snapDistance;
    pos.y = Mathf.Round(pos.y / snapDistance) * snapDistance;
    pos.z = Mathf.Round(pos.z / snapDistance) * snapDistance;

    return pos;
}

private Vector3 SnapToGridFloor(Vector3 pos, float snapDistance)
{
    pos.x = Mathf.Floor(pos.x / snapDistance) * snapDistance;
    pos.y = Mathf.Floor(pos.y / snapDistance) * snapDistance;
    pos.z = Mathf.Floor(pos.z / snapDistance) * snapDistance;

    return pos;
}

private Vector3 SnapToGridCeil(Vector3 pos, float snapDistance)
{
    pos.x = Mathf.Ceil(pos.x / snapDistance) * snapDistance;
    pos.y = Mathf.Ceil(pos.y / snapDistance) * snapDistance;
    pos.z = Mathf.Ceil(pos.z / snapDistance) * snapDistance;

    return pos;
}
1 Like