if-statementgodot4

Godot 4. Why my if condition end without doing all her process


I have a problem where my if condition work but end her function in just a moment.

var speed = 75
var dir: Vector2 = Vector2.ZERO
var enter: bool = false

@onready var camera = $"../camera"

func _ready():
    randomize()
    _choose_random_direction()

func _physics_process(delta: float) -> void:
    
    velocity = dir * speed
    
    if Input.is_action_just_pressed("accept"):
        camera.unzoomi(delta)
    
    move_and_slide()

func _choose_random_direction():
    var directions = [
        Vector2(-1, 0), Vector2(1, 0),  # Left, Right
        Vector2(0, -1), Vector2(0, 1),  # Up, Down
        Vector2(-1, -1), Vector2(1, -1),  # Top-left, Top-right
        Vector2(-1, 1), Vector2(1, 1),   # Bottom-left, Bottom-right
        Vector2(0, 0)
        ]
    dir = directions[randi() % directions.size()]
    await get_tree().create_timer(randf_range(1, 3)).timeout
    _choose_random_direction()

The if inside the func _physics_process supose to be a zoom of the camera with a smooth transition, but when i call the function of the zoom, the zooming end in a instance instead that 2 sec that i programated.

this is the code of the camera:

var zooming: bool = false

@onready var player = $"../player"

func _process(delta: float) -> void:
    position = player.position

func zoomi(delta):
    var end: float = 3
    
    zooming = true
    
    if zooming == true:
        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

func unzoomi(delta):
    var end: float = 3
    
    zooming = true
    
    if zooming == true:
        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

thanks.


Solution

  • Your issue is that the zooming transition in your zoomi() and unzoomi() functions happens only once when the function is called. Since lerp() requires multiple frames to create a smooth transition, you need to update the zoom continuously inside _process().

    this is the code of the camera:

    var zooming: bool = false
    var zoom_target: float = 1.0  
    var zoom_speed: float = 0.4  
    
    @onready var player: CharacterBody2D = $"../player"
    
    func _process(delta: float) -> void:
        position = player.position
        if zooming:
            zoom.x = lerp(zoom.x, zoom_target, zoom_speed * delta)
            zoom.y = lerp(zoom.y, zoom_target, zoom_speed * delta)
            if abs(zoom.x - zoom_target) < 0.05:
                zooming = false
    
    func zoomi():
        zoom_target = 3.0 
        zooming = true
    
    func unzoomi():
        zoom_target = 1.0
        zooming = true
    

    this is the code of the player:

    var speed = 75
    var dir: Vector2 = Vector2.ZERO
    var enter: bool = false
    
    @onready var camera: Camera2D = $"../camera"
    
    func _ready():
        randomize()
        _choose_random_direction()
    
    func _physics_process(delta: float) -> void:
        
        velocity = dir * speed
        if Input.is_action_just_pressed("zoom_in"):
            camera.zoomi()
        elif Input.is_action_just_pressed("zoom_out"):
            camera.unzoomi()
        
        move_and_slide()
    
    func _choose_random_direction():
        var directions = [
            Vector2(-1, 0), Vector2(1, 0),  # Left, Right
            Vector2(0, -1), Vector2(0, 1),  # Up, Down
            Vector2(-1, -1), Vector2(1, -1),  # Top-left, Top-right
            Vector2(-1, 1), Vector2(1, 1),   # Bottom-left, Bottom-right
            Vector2(0, 0)
            ]
        dir = directions[randi() % directions.size()]
        await get_tree().create_timer(randf_range(1, 3)).timeout
        _choose_random_direction()