Search code examples
error-handlingruntime-errorgodotgdscriptgodot4

Invalid Set 'x' (on base:'bool') of value of type 'int'


extends CharacterBody2D

var mon = Vector2.ZERO

func _physics_process(delta):
    mon = move_and_slide()

    if Input.is_action_pressed("ui_left"):
        mon.x = -1  # Set the horizontal speed to -1
    elif Input.is_action_pressed("ui_right"):
        mon.x = 1   # Set the horizontal speed to 1
    else:
        mon.x = 0   # Stop horizontal movement

the error is : Invalid Set 'x' (on base:'bool') of value of type 'int'

I tried couple of ideas and please someone explain why and what move and slide does I'm a beginner in GDScript and I'm learning Sfml with C++ Help me on Godot please


Solution

  • There are two points of interest here:

    • The variable mon is declared without a type:

      var mon = Vector2.ZERO
      

      Here the variable is initialized with a Vector2.ZERO, but it is a Variant. Godot won't stop you from setting a variable of a different type.

      If you declare the type explicitly:

      var mon:Vector2 = Vector2.ZERO
      

      Or implicitly:

      var mon := Vector2.ZERO
      

      Then Godot will tell you when you are not setting a Vector2 to it.

    • The method move_and_slide returns a bool.

      As a result, here:

      mon = move_and_slide()
      

      The mon variable is being set to a bool value.

      In Godot 3.x move_and_slide used to return a vector with the final velocity. That is no longer true in Godot 4.x. Instead move_and_slide moves according to the velocity property, and it also updates said velocity property.

      The bool value that move_and_slide returns tells you if there were collisions or not.

    With that said, you should be using velocity:

    extends CharacterBody2D
    
    func _physics_process(delta):
        move_and_slide()
    
        if Input.is_action_pressed("ui_left"):
            velocity.x = -1  # Set the horizontal speed to -1
        elif Input.is_action_pressed("ui_right"):
            velocity.x = 1   # Set the horizontal speed to 1
        else:
            velocity.x = 0   # Stop horizontal movement
    

    I'll also note that the units of velocity for 2D are pixels per second. So setting its components to 1 means that it will take one second to move a pixel, which is too little to notice.

    Instead, consider declaring a speed:

    extends CharacterBody2D
    
    var speed := 100.0
    
    func _physics_process(delta):
        move_and_slide()
    
        if Input.is_action_pressed("ui_left"):
            velocity.x = -speed
        elif Input.is_action_pressed("ui_right"):
            velocity.x = speed
        else:
            velocity.x = 0
    

    Of course, set speed to what you want.


    Bonus chatter: you can use get_axis:

    extends CharacterBody2D
    
    var speed := 100.0
    
    func _physics_process(delta):
        move_and_slide()
    
        velocity.x = Input.get_axis("ui_left", "ui_right") * speed
    

    Note that get_axis method uses the strength of the inputs, so it will be sensible to analog input (such as a joystick) if configured.