c# - I need help creating mouse-centered zooming - Stack Overflow

admin2025-04-27  5

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.

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.

Share Improve this question edited Jan 10 at 9:25 DarkBee 15.5k8 gold badges72 silver badges118 bronze badges asked Jan 10 at 8:38 SheepSheep 131 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

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

  • you base the positioning on the mouse position rather than the original object position
  • you use the factor new Zoom Level / previous Zoom Level to update the position offset
转载请注明原文地址:http://anycun.com/QandA/1745757105a91165.html