Nice one, thanks.
Indeed, I didn't give a solution for that. I actually scraped it because I found the controls nicer with the ability to always zoom in and out.
The way I would handle this is by adding a boolean on the camera that toggles zoom on or off. It's the same boilerplate as with the zoom property:
# CameraRig.gd
var use_zoom: = true setget set_use_zoom
...
func set_use_zoom(value : bool) -> void:
use_zoom = value
if not spring_arm:
yield(spring_arm, "ready")
spring_arm._use_zoom = zoom
The spring arm needs to keep track of the last zoom level, so when the player goes out of aiming mode, the camera returns to the previous zoom level. Note that I'm making _use_zoom pseudo-private, the idea is that my teammates should only change this through the camera node:
# SpringArm.gd
var _use_zoom: = true setget _set_use_zoom
var _zoom_previous := 0.0
...
func _set_use_zoom(value : bool) -> void:
_use_zoom = value
if _use_zoom:
self.zoom = _zoom_previous
else:
_zoom_previous = zoom
self.zoom = 0.0
Above, when we toggle the ability to zoom off, we store the zoom level and set the current zoom to 0.0.
When we toggle _use_zoom back on, we restore the last zoom level, stored in _zoom_previous.
Finally, we need to adjust the set_zoom setter function:
func set_zoom(value: float) -> void:
zoom = value
if not _use_zoom:
return
assert(value >= 0.0 and value <= 1.0)
spring_length = lerp(length_range.y, length_range.x, zoom)
(thanks again for simplifying the last line)
From there, all we need to do is to toggle the use_zoom property of the camera on and off in the Player's states:
player.camera.use_zoom = false