First using only zoom property to zoom at point will not be sufficient(read below). Second it looks like either some script modifies cameras anchor_mode
or your camera isn't active-one after all. Try creating simple scene and make zooming at center work, then after you resolve that issue read next part how zoom at specific point.
If we would do manually zoom-at-point transformation we could split it into 3 parts:
- translating to zooming point - to set zoom center
- zooming by desire amount - actual zooming
- applying reversed translation - returning camera to its appropriate position
Because Zooming part is doing for us by Godot as a first transformation we need to combine 1st and 3rd step together and do camera positioning ourselves and it will involves math.
BEWARE MATH BELOW!!!
To tackle this problem first we must get our facts strait.
* Looking for: new camera position
* Variable: zoom
* Invariant: screen size, mouse global position, mouse position on screen
Mouse positions looks like most appropriate points of building an equation to compute new position of camera.
Lets start with defining vars:
M
global mouse position
m
mouse position on screen
C
global camera position
s
screen size
z
zoom level
now lets build equation:
mouse global position depends on position on screen
M ~ m
we set camera anchor to drag center so its reference point is in center of the screen and mouse position on screen is relative to upper left corner which is half screen size to upper left direction
M ~ (m - 0.5 * s)
screen can be zoomed so we need to apply that to screen size and mouse position on screen
M ~ (m - 0.5 * s)*z
everything is relative to camera position
M ~ (m - 0.5 * s)*z + C
that is everything need to compute global mouse position
M = (m - 0.5 * s)*z + C
global mouse positions before and after zooming will be
M0 = (m - 0.5 * s)*z0 + C0
M1 = (m - 0.5 * s)*z1 + C1
We know that global mouse position and mouse position on screen before and after zooming will be same
M0 = M1
replacing M1 and M2 with equations
(m - 0.5 * s)*z0 + C0 = (m - 0.5 * s)*z1 + C1
After transforming(skipping some steps) we will get this:
C1 = C0 + (-0.5*s + m)*(z0 - z1)
That is new camera position that we were searching for.
And here some code to attach to camera script:
var zoom_step = 1.1
func _input(event):
if event is InputEventMouse:
if event.is_pressed() and not event.is_echo():
var mouse_position = event.position
if event.button_index == BUTTON_WHEEL_UP:
zoom_at_point(zoom_step,mouse_position)
else : if event.button_index == BUTTON_WHEEL_DOWN:
zoom_at_point(1/zoom_step,mouse_position)
func zoom_at_point(zoom_change, point):
var c0 = global_position # camera position
var v0 = get_viewport().size # vieport size
var c1 # next camera position
var z0 = zoom # current zoom value
var z1 = z0 * zoom_change # next zoom value
c1 = c0 + (-0.5*v0 + point)*(z0 - z1)
zoom = z1
global_position = c1
best practice is to write new code by yourself - you will remember it better that way - so try avoid copy-pasting