How would you go about panning and zooming like Google Maps using SetTextureOffset & SetTextureScale ?
Hi, I might be approaching this the wrong way but I've been really stuck on this. It totally caught me off guard because it seems like a simple problem:
Essentially I'm trying to implement controls like Google Maps to my project where the user would be able to move an image underneath their cursor by clicking and dragging. In addition the user would be able to zoom in on the image by scrolling. The image would then scale from the position of the mouse without the thing underneath it moving (that's 100% the hardest part). All of this should work using only texture offsets to a material rather than using a camera or transforms. (using _MainTex_ST via SetTextureScale & SetTextureOffset).
Does anyone have ideas for how to solve this?
So far I've only been able to get approximations of the effect. You can test them here: https://github.com/thnewlands/PanningZoomingMapWithUVs
Approximation 1: I've gotten it to sort of work by using a custom shader (which is ultimately not how I want to solve the problem). But the camera wiggles around when it zooms in.
This code in a vertex shader will scale the UVs around the pivot position. In this case: _Pivot = the mouse position in view space, _Zoom = a float2 I increase w/ scroll, _Offset = a float2 I add a (lastMousePos - mousePos) to in a loop.
o.uv -= _Pivot;
o.uv *= _Zoom;
o.uv += _Pivot;
o.uv += _Offset;
Approximation 2: I tried initially to solve this problem using Rects but found the strategy to be super cumbersome. It ended up introducing a ton of error when I would zoom in and out. It did show me that this should be possible without using any specialized shaders though.
canvasOffset.size += scaleDelta; //This scales from the top left corner -- the corner now needs to be offset
canvasOffset.position -= pivot * scaleDelta;// Scale from mouse position
canvasOffset.position += positionDelta;
panningMaterial.SetTextureOffset("_MainTex", canvasOffset.position);
panningMaterial.SetTextureScale("_MainTex", canvasOffset.size);
I also have this posted on reddit here: https://www.reddit.com/r/Unity3D/comments/usj8lk/how_would_you_go_about_panning_and_zooming_like/
Here are a list of resources I've looked closely at to try to answer this question:
Answer by comomomo · May 18 at 10:08 PM
I think I found the solution!! My rect approach turned out to be the correct one. You can see it in action in the github repository here: https://github.com/thnewlands/PanningZoomingMapWithUVs
canvasOffset.size += scaleDelta * Vector2.one;//This scales from the top left corner -- the corner now needs to be offset
canvasOffset.position -= mousePos * scaleDelta;// Scale from mouse position
canvasOffset.position += positionDelta * canvasOffset.size;
panningMaterial.SetTextureOffset("_MainTex", canvasOffset.position);
panningMaterial.SetTextureScale("_MainTex", canvasOffset.size);