- Home /
Camera zoom towards the mouse in 2D (answered)
I had been looking for a solution to this problem for a while, and I finally came up with one myself. I'll leave it here for anyone interested.
What I wanted to achieve was to have the camera zoom in while keeping the mouse position in the world constant. This results in the camera kind of "zooming towards the mouse". Here's an example of what I mean: https://imgur.com/a/Qm4SwLY
The way I went about this, after implementing a very simple camera zoom, is moving the camera a certain amount to match the last mouse position. In order to do this, I used this simple proportion: lastCameraOrthographicSize : lastDistanceToMouse = currentCameraOrthographicSize : x, where x is the new distance the camera need to get to the mouse. From this we can get this formula to get the newDistanceToMouse: newDistanceToMouse = (lastDistanceToMouse * currentCameraOrthograhicSize) / lastCameraOrthographicSize. Then, we can set thecamera position to be equal to currentMousePosition - newCameraDistance.
In order to do this in the code, we first need to get the mouse position. We can do this by simply writing mousePosition = camera.ScreenToWorldPoint(Input.mousePosition). Then, we calculate the current camera distance with cameraDistance = mousePosition - new Vector2(transform.position.x, transform.position.y) (I'm supposing this script will be a component of the camera, that's why I'm using transform.position). Then, for the new camera distance, we can use newCameraDistance = (cameraDistance * cam.orthographicSize) / lastCameraOrthographicSize. Finally, to get the camera to the correct position, we can use this piece of code:
targetPosition = mousePosition - newCameraDistance; transform.position = new Vector3(targetPosition.x, targetPosition.y, transform.position.z);
Note that this could probably also be done with the proportion lastCameraOrthographicSize : cameraOrthographicSize = lastCameraDistance : x, where x is newCameraDistance.
The full code for this (without the actual zooming part) looks something like this:
cameraOrthographicSize = cam.orthographicSize;
if (Time.frameCount <= 1)
{
lastCameraOrthographicSize = cameraOrthographicSize;
}
mousePosition = cam.ScreenToWorldPoint(Input.mousePosition);
cameraDistance = mousePosition - new Vector2(transform.position.x, transform.position.y);
newCameraDistance = (cameraDistance * cam.orthographicSize) / lastCameraOrthographicSize;
targetPosition = mousePosition - newCameraDistance;
transform.position = new Vector3(targetPosition.x, targetPosition.y, transform.position.z);
lastCameraOrthographicSize = cameraOrthographicSize;
In the first part, I added a check to make sure that we don't get any "division by zero" errors, so if we just started the code lastCameraOrthographicSize will be equal to the cameraOrthographicSize. Then, at the end of the code, we set lastCameraOrthographicSize = cameraOrthographicSize.
This works both when zooming in and when zooming out.