Search code examples
2dgame-developmentgodotlerp

camera zoom with lerp(). Godot 2D game


I have a problem. I tried this code:

extends Camera2D

@onready var timer = $Timer

func _process(delta: float) -> void:
zoomi()

func zoomi():
var delta = get_process_delta_time()
var end: float = 3.0
if Input.is_action_just_pressed("accept"):
zoom.x = lerp(zoom.x, end, 0.4 * get_process_delta_time())
zoom.y = lerp(zoom.y, end, 0.4 * get_process_delta_time())

I press a button, the "accept", and I want the camera make a zoom with a slow transition to the new valor of the zoom. but the camera only zoom directly to, doesn't do the smooth transition that i want.

Someone can explain me why isn't working? Thanks


Solution

  • This code actually does "work", but we need to figure out what you're telling it to do. To figure out what your original issue was, press play, open up the remote tab in your scene, and select your camera. You'll see your zoom values change when you press accept.

    However, the calculation only occurs once at the exact moment your accept button is pressed. This is only changing the zoom by 0.011 for one frame, because you're lerping by an incredibly small delta.

    If you want a lerp to occur, it needs to continue to occur past the exact moment the accept button is pressed.

    This could look like this:

    extends Camera2D
    
    @onready var timer = $Timer
    var zooming: bool = false
    
    func _process(delta: float) -> void:
        zoomi(delta)
    
    func zoomi(delta):
        var end: float = 3.0
        
        if Input.is_action_just_pressed("ui_accept"):
            zooming = true
        
        if zooming:
            zoom.x = lerp(zoom.x, end, 0.4 * delta)
            zoom.y = lerp(zoom.y, end, 0.4 * delta)
            
            if zoom.x > end * .8:
                zooming = false
    

    To further clarify the code I added, there is a "zooming" boolean variable that gets triggered on if accept is pressed. That way, when you accept, zooming will continue to be true, and the lerp will calculate a new value every frame.

    In order to escape the lerp, you need an exit condition. Because lerp doesn't really ever reach the end value, you only need to reach a certain part of the value. I arbitrarily had an exit condition if zoom.x > end * 0.8, then stop zooming to escape the if statement. Its about 2 seconds of lerping, but you can adjust the value to make it longer or short.

    I am not an expert, so my solution may not be entirely clean. However, this illustrates that lerp is only a calculation that gets you a value between point A and point B. If you want to continue zooming, lerp needs to give several points between point A and point B over many frames.