0 votes

Hello,
I am trying to find the error in this script which is attached to my player, I am following step by step a video course but I can't identify the issue.
I'm attaching the full script, please help!!
Thanks a lot in advance! :)
ERROR MESSAGE: Invalid type in function 'moveandslide' in base 'KinematicBody (PlayerController.gd)'. Cannot convert argument 1 from float to Vector3.

extends KinematicBody

Declare member variables here. Examples:

var a = 2

var b = "text"

var velocity = Vector3 (0,0,0)
var y_velocity = velocity.y
export (float, 0 , 100) var WALK = 5.0
export (float, 0 , 100) var RUN = 12.5
export (float, 0 , 100) var GRAV = 9.8
export (float, 0 , 100) var JUMP = 7.0
export (float, 0 , 100) var ANGLE = 0.0000001
export (float, 0 , 100) var ZOOM = 1.0

Called when the node enters the scene tree for the first time.

func ready():
#pass # Replace with function body.
#Lock cursor to the game window
Input.set
mousemode(Input.MOUSEMODE_CAPTURED)

func input(event):
if Input.is
actionpressed("scrollup"):
$Spatial/Camera.translate(Vector3(0 , 0.5 * -ZOOM , -ZOOM))

if Input.is_action_pressed("scroll_down"):
    $Spatial/Camera.translate(Vector3(0 , 0.5 * ZOOM , ZOOM))

func unhandledinput(event):
if event is InputEventMouseMotion:
rotate_y(-lerp(0, ANGLE, event.relative.x/10))

func handleinput ():
#Save y
velocity of the player before makinng changes to the local transform
y_velocity = velocity.y

#Reset the player's velocity to detect new changes to player's movement
velocity = Vector3(0, 0, 0)

if Input.is_action_pressed("ui_right") and Input.is_action_pressed("ui_left"):
    velocity = 0
elif Input.is_action_pressed("ui_right"):
    if Input.is_action_pressed("ui_shift"):
        velocity = RUN * transform.basis.x
    else:
        velocity = WALK * transform.basis.x
elif Input.is_action_pressed("ui_left"):
    if Input.is_action_pressed("ui_shift"):
        velocity = -RUN * transform.basis.x
    else:
        velocity = -WALK * transform.basis.x
else:
    velocity = 0


if Input.is_action_pressed("ui_up") and Input.is_action_pressed("ui_down"):
      velocity = 0
elif Input.is_action_pressed("ui_up"):
    if Input.is_action_pressed("ui_shift"):
        velocity = -RUN * transform.basis.z
    else:
        velocity = -WALK * transform.basis.z
elif Input.is_action_pressed("ui_down"):
    if Input.is_action_pressed("ui_shift"):
        velocity = RUN * transform.basis.z
    else:
        velocity = WALK * transform.basis.z
else:
    velocity = 0

#Restore y_velocity of the player after making changes to the local transform
velocity = y_velocity


if Input.is_action_pressed("ui_select") and is_on_floor():
    velocity.y = JUMP

if Input.is_action_pressed("ui_cancel"):
    Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

#The $ Symbol is as get_node() function.
#Write get_noce(Spatial).rotate_y(deg2rad(-ANGLE)) works too

if Input.isactionpressed("Q"):

$Spatial.rotate_y(deg2rad(-ANGLE))

#

if Input.isactionpressed("E"):

$Spatial.rotate_y(deg2rad(ANGLE))

func physicsprocess(delta):
if not isonfloor():
velocity.y -= GRAV * delta
handle_input()

move_and_slide(velocity , Vector3.UP)
Godot version 3.5.1
in Engine by (20 points)

1 Answer

0 votes
Best answer

In the handle_input function, there are many instances where you are using velocity = 0 instead of velocity *= 0 or velocity = Vector3.ZERO.
Velocity should be a vector and thats why move and slide complains where it gets velocity= 0.

by (2,017 points)
selected by

Hi, thanks for the quick reply, I tried to do as you suggested, both ways, but I'm still getting the same issue.
Also in debugger I see:
W 0:00:00.450 The argument 'event' is never used in the function 'input'. If this is intended, prefix it with an underscore: 'event'
<C++ Error> UNUSED_ARGUMENT

PlayerController.gd:23

W 0:00:00.450 The function 'moveandslide()' returns a value, but this value is never used.
<C++ Error> RETURNVALUEDISCARDED

PlayerController.gd:98

func handleinput ():
#Save y
velocity of the player before makinng changes to the local transform
y_velocity = velocity.y

#Reset the player's velocity to detect new changes to player's movement
velocity = Vector3(0, 0, 0)

if Input.is_action_pressed("ui_right") and Input.is_action_pressed("ui_left"):
    velocity = Vector3.ZERO
elif Input.is_action_pressed("ui_right"):
    if Input.is_action_pressed("ui_shift"):
        velocity = RUN * transform.basis.x
    else:
        velocity = WALK * transform.basis.x
elif Input.is_action_pressed("ui_left"):
    if Input.is_action_pressed("ui_shift"):
        velocity = -RUN * transform.basis.x
    else:
        velocity = -WALK * transform.basis.x
else:
    velocity = Vector3.ZERO

In the same handle input function, in this line :

velocity = y_velocity

am sure you mean :

velocity.y = y_velocity

Again, make sure velocity does not get assigned to a scaler because velocity should be a vector.

Thanks a million for your help, but now a new issue is popping up, I can't get why the first IF loop is not working while the second does, I even tried to print to see in debug if it was receiving the input and it does, the code works too as I tried to swap the 2 loops and yeah, whichever is first simply does not work, so when playing in this case the character can't go up or down, just left and right, plus if I move diagonally, it moves but with RUN speed.

func handleinput ():
#Save y
velocity of the player before makinng changes to the local transform
y_velocity = velocity.y

#Reset the player's velocity to detect new changes to player's movement
velocity = Vector3(0, 0, 0)


if Input.is_action_pressed("ui_up") and Input.is_action_pressed("ui_down"):
    velocity.z = 0

velocity = Vector3.ZERO

elif Input.is_action_pressed("ui_up"):
    if Input.is_action_pressed("ui_shift"):
        velocity += -RUN * transform.basis.z
    else:
        velocity += -WALK * transform.basis.z
elif Input.is_action_pressed("ui_down"):
    if Input.is_action_pressed("ui_shift"):
        velocity += RUN * transform.basis.z
    else:
        velocity += WALK * transform.basis.z
else:
    velocity = Vector3.ZERO

if Input.is_action_pressed("ui_right") and Input.is_action_pressed("ui_left"):
    velocity.x = 0

velocity = Vector3.ZERO

elif Input.is_action_pressed("ui_right"):
    if Input.is_action_pressed("ui_shift"):
        velocity += RUN * transform.basis.x
    else:
        velocity += WALK * transform.basis.x

elif Input.is_action_pressed("ui_left"):
    if Input.is_action_pressed("ui_shift"):
        velocity += -RUN * transform.basis.x
    else:
        velocity += -WALK * transform.basis.x

else:
    velocity = Vector3.ZERO

#Restore y_velocity of the player after making changes to the local transform
velocity.y = y_velocity


if Input.is_action_pressed("ui_select") and is_on_floor():
    velocity.y = JUMP

if Input.is_action_pressed("ui_cancel"):
    Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

func physicsprocess(delta):
if not isonfloor():
velocity.y -= GRAV * delta
handleinput()
velocity = move
and_slide(velocity , Vector3.UP)

Am not sure what the problem there is as it's a bit hard to read your code due to the many and nested if statements. With that kind of code structure you are prone to getting many errors. I suggest you use a simple state machine and split your code into more functions. That way you get fewer errors and when they occur it's easier to find them.

Sidenote, if an answer helps you mark it as best to help others get the right solution faster if they have the same problem.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.