UI and mousePosition not centered the same way ?


I have a problem with some UI elements which are on a canvas (which scale with screen size). The ancors of the elements are at the center of the screen. However, when I check the position of the mouse on the screen (with a Debug.Log() in Update(), and I’m using the function “Input.mousePosition”), I can see that the elements are not centered on the (0, 0) of the mouse position ! For the cursor, the default cursor works fine, but as soon as I use a custom one the same difference arise. I’ve tested multiple screen size, editor or build, and it’s always the same gap between the (0, 0) of the mousePosition and the UI / customCursor.

The (0, 0) for the mouse position is at the bottom-left of the screen, while the (0, 0) of the center-anchored UI elements will be in the center of the canvas/screen. You’ll need to manually adjust for this in your code. For example, if you want your mouse position to act like its (0, 0) is in the center of the screen, you will need to do the following:

//The mouse position based on the mouse's coordinate system:
float naturalMouseX = Input.mousePosition.x;
float naturalMouseY = Input.mousePosition.y;

//The mouse position based on the canvas/screen's coordinate system:
float screenMouseX = Input.mousePosition.x - (Screen.width / 2);
float screenMouseY = Input.mousePosition.y - (Screen.height / 2);

Hope this helps!


1: The click point of any cursor is at the top-left corner of the texture being used. To fix this, you’ll have to modify the ‘hotspot’ - the click point - of the cursor when you use Cursor.SetCursor. To position it in the center of the custom cursor, you can use:

 public Texture2D texture;

 private void Start()
     Cursor.SetCursor(texture, new Vector2(texture.width / 2, texture.height / 2), CursorMode.Auto);

2: Screen.width, Texture.width, etc., are int values. This means that when dividing them by 2, the result will be different then expected (due to int division not allowing decimals). To fix this, add (float) before Screen.width and other related int values.

That said, I don’t know how much of an impact this will have, as in the case of dividing by two, there will only be a difference of 0.5 in each case.

One more thing that might help explain things. The screen is displayed in pixels, which cannot display two things at once. Therefore, if there is something that is an even number of pixels in size, it will either be cropped or shifted to an adjacent pixel, meaning it’s center will be about half a pixel away from what you expect.