I've been trying to make a system in my 2D unity game where you can zoom in and out by scrolling, and it should center that zoom around the cursor, like zooming in on a web browser. With the way the game is set up, I can't alter the camera in any way so I'm attempting to do this mouse-centered zoom by positioning and scaling the transform that this script is attatched to (the camera is directly facing this GameObject). I have the scaling part down, but I've been trying to get the positioning to work for days and it just won't work properly. Here is my code.
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 mousePercentPoint = new Vector2((mousePos.x - transform.position.x)/(fieldMask.transform.localScale.x * currentZoom - transform.position.x), (mousePos.y - transform.position.y)/(fieldMask.transform.localScale.y * currentZoom - transform.position.y));
float zoomDelta = Input.GetAxis("Mouse ScrollWheel");
currentZoom += zoomDelta;
currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);
transform.localScale = new Vector3(currentZoom, currentZoom, 1.0f);
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 mousePostPercentPoint = new Vector2((mousePos.x - transform.position.x)/(fieldMask.transform.localScale.x * currentZoom - transform.position.x), (mousePos.y - transform.position.y)/(fieldMask.transform.localScale.y * currentZoom - transform.position.y));
transform.position = new Vector3((mousePercentPoint.x - mousePostPercentPoint.x), mousePercentPoint.y - mousePostPercentPoint.y, transform.position.z);
FieldMask.transform.localScale is supposed to be a reference size for the default scale of the transform
I've tried various methods, I think this attempt involved calculating the position of the mouse relative to the transform's bounds as a percent (using fieldMask.transform.localScale as a base size), and then scaling that up/down and repositioning the attatched transform according, but it has not worked correctly.
As I understand what you could try is
// [as before] get the mouse position in world space
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// [as before] get zoom input
float zoomDelta = Input.GetAxis("Mouse ScrollWheel");
// cache currentZoom
float originalZoom = currentZoom;
// get original position offset in world space
Vector3 mousePositionOffset = transform.position - mousePosition;
// [as before] update zoom and scale
currentZoom = Mathf.Clamp(currentZoom + zoomDelta, minZoom, maxZoom);
transform.localScale = new Vector3(currentZoom, currentZoom, 1.0f);
// calculate factor originalZoom -> new zoom
float zoomFactor = currentZoom / originalZoom;
// update position based on and zoom change
transform.position = mousePosition + mousePositionOffset * zoomFactor;
so the trick is basically
new Zoom Level / previous Zoom Level
to update the position offset