LibGDX Screen to World coordinates

Hey guys, I’m making a game in which I need to convert screen coordinates to world coordinates. The player has the ability to move/zoom the camera, and I want a click/tap to properly correspond with the world.

I know the traditional way of doing this is:


Vector2 clickPos = new Vector2(x, camera.viewportHeight - y);
camera.unproject(new Vector3(clickPos, 0));

However, this doesn’t seem to work for me. I’m not sure how to describe the problem, but it just isn’t giving the right world coordinates.
Everything in my world is drawn at a scale of 2, so I thought that meant I had to scale the vector but that gave this weird exponential effect.
I know I’m doing something wrong, but everywhere I look it only goes into the amount of detail above. Let me know if you need some screenshots of the situation
if there doesn’t seem to be anything obviously wrong.

Thanks guys! :slight_smile:

Unfortunately I don’t know enough about LibGDX to point you directly to the answer (maybe someone else can do so), but I can think of some additional information that might be helpful.

How is your camera projection set up? Is it a centered orthogonal projection with the same aspect ratio as the viewport? If so, what’s the size?

Also, what do you get if you un-project points with easily predictable results? For example, in the ‘centered orthogonal’ case, (0, 0) should probably un-project to ~(-x_extent, -y_extent), (width/2, height/2) should probably un-project to ~(0, 0), and so on. Knowing what results you get for these simple cases might be informative.

camera.unproject returns the updated Vector3 so you need to save that value:


Vector2 clickPos = new Vector2(x, camera.viewportHeight - y);
Vector3 worldCoordinates = camera.unproject(new Vector3(clickPos, 0));

or you could also do this and then the updated coordinates will be stored in the original Vector3:


Vector3 clickPos = new Vector3(x, camera.viewportHeight - y, 0);
camera.unproject(clickPos);

Interesting. I stopped subtracting the height by Y (not exactly sure what the point of that is) and stored it in a new vector like you said, and it worked. I swore I tried that already, but oh well.

Thanks for your help guys.

The reason for that is that Camera.unproject() expects screen coordinates with the origin (0/0) in the upper left corner, so Y points down.

By the way, you usually want to use a smaller scale (1/100, for example). In Box2D 1 unit = 1 meter, so just dividing by 2 means that stuff is still gonna be really big.