Mouse position not the same as the X and Y in the editor

Hi there,

I am making a prototype where I can place square tiles on a grid. The sprites I use are 32x32 pixels and I set the Pixels Per Unity to 32 so 1 unity is 1 of those tiles.

I have set the grid for snapping in the Unity scene view to 1 and automatic snapping on. But I don’t think this is relevent to the case.

To determine the positions at which the tiles should spawn I use a nested for loop (one for the x position and one for the y position). All tiles spawn perfectly on the perfect location. When I click on the spawned tiles in the editor I get the correct positions in the transform for each tile. (0.0, 0.1, 0.2, 1.1 etc). I also store the tile position in a Vector2Int within the Tile script attached to the spawned BaseTile GameObjects. These Vector2Ints also have the proper coordinates.

In an Update method I do the following:

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector3 mousePos = Input.mousePosition;
            Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(mousePos);
            mouseWorldPos = new Vector3(mouseWorldPos.x, mouseWorldPos.y, 0);
            Vector2Int tilePos = new Vector2Int((int)mouseWorldPos.x, (int)mouseWorldPos.y);

            print($"{mouseWorldPos} => {tilePos}");
            BaseTile foundBaseTile = GetBaseTileTilePos(tilePos);

            foundBaseTile?.EnableHighlight();
        }
    }

In the game window, when I click on a tile to highlight it, it only works correctly for the first row (Y=0). After that there seems to be an offset on the Y axis. I need to click on the tile above the tile I want to select to highlight the tile beneath it.

Any ideas on how I can fix this?

Update: I have set the pivot of the sprite assets to Top Left. I tried other pivots but I get the same issue. If I place the pivot on Center or anything else then the highlight is on the wrong position. The highlight is just a gameobject over the tile gameobject that gets activated/deactivated.

This is the kind of thing where it helps to use OnDrawGizmos or similar to visualise how things are behaving.

The only thing that stands out to me is the cast to int, which is effectively flooring your coordinates, might be shifting the value down with respect to how the tiles are actually positioned in the world?

The issue could also be in GetBaseTileTilePos. In any case, I just see a situation where some debugging is needed.

Worth noting that Unity’s tilemap’s already have methods to convert world positions to a tile coordinate.

2 Likes

Thanks for your reply. I am using the cast to int exactly for that reason. If the mouse is on let’s say 2.25 and 3.45 it needs to turn into 2 and 3. That corresponds with the vector2int stored in the “BaseTile” class and the transform position of the BaseTile GameObject.

I am aware and have worked with TileMaps. I am making a custom grid because with the Tilemap system I can only place/draw a single Tile sprite/asset and I want to spawn custom GameObjects with child objects in them. I could use TileMap purely for the coordinates but that seems overkill and less performant than just storing my tiles in a List with the proper coordinates stored on the script of each Tile.

Remember there is a kink in the number line when you floor stuff that is both positive and negative.

See for yourself:

        for (int i = -3; i <= +3; i++)
		{
            float f = i + 0.5f;
            int x = (int)f;
            Debug.Log("f = " + f + " => x = " + x);
		}

Also, make sure you have no scales set anywhere.

2 Likes

Thank you for your reply. You are right about the flooring of a negative value. However, my spawned tiles are all above 0 in the x and y. I must be missing something obvious here but my brain seems to be broken. :sweat_smile:

Wrap the code in something that blasts known values at it, like 0 to 9 in the x and 0 to 9 in the y and see what comes out of it.

I would post my THIS IS SPARTA! meme that says THIS IS DEBUGGING! but I can’t lay my hands on it.

1 Like

Do you mean simulating the mouse position that get’s floored? :slightly_smiling_face:

I mean anything that constitutes debugging. You have a thing misbehaving. There are many parts to that thing. Many of those parts may not be misbehaving. One or more might be.

Your little personal Friday afternoon minigame right now is to drill down and find the the misbehaving one however you can… and that means… time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

Remember with Unity the code is only a tiny fraction of the problem space. Everything asset- and scene- wise must also be set up correctly to match the associated code and its assumptions.

I debugged a problem like this by using the position of a transform I could move around in the scene view, and using OnDrawGizmos to draw its world position and converted tile coordinates into the scene to visualise how things were going wrong. Though ultimately it meant going through my maths and logic on a piece of paper to find the root of the issue.

Like Kurt says, you really need to debug this on your end.

1 Like

Ideally you want to make a testable class or utility methods so you can write Unit Tests that take input coordinates and use the test to verify that the resulting output matches the expectation.

This puts just the coordinate calculation under a test so you can focus on that without the visualizations, and you can easily debug where the calculations go wrong and learn why.

1 Like

I figured it out. The problem was the pivot of the sprite. I thought I tried all options but it was rendering from “Top Left”. This meant that the spawned tile objects on the first row (Y=0) did go below 0 because the upper part of the sprite was placed on the Y=0 axis. So below that it went below 0 up to -0.5 causing the Y offset. I now have a pivot of “Bottom-Left” and now everything is within positive coordinates and my system works. :slight_smile: