Let us start by looking at the documentation of move_and_slide. This is the signature of the function:
Vector2 move_and_slide ( Vector2 linear_velocity, Vector2 up_direction=Vector2( 0, 0 ), bool stop_on_slope=false, int max_slides=4, float floor_max_angle=0.785398, bool infinite_inertia=true )
Notice:
- The first parameter is a velocity vector.
- The second parameter is an up vector.
Thus, this function does not work with a position.
And the error you are getting is because you are passing a float on the up parameter.
Why does move_and_slide take an up vector? It is because move_and_slide updates the values you get from is_on_ceiling, is_on_floor and is_on_wall. And how does it know what is a ceiling, a floor or a wall? That's right, it needs to know what way it up. If you let the up vector at ZERO (or just not pass it, since that's the default value), they are all considered walls (and this is OK for a top down game).
Now, you want to do a platformer game, presumably a side scroller. Most likely you want to pass Vector2.UP as second parameter. And that should fix the error.
However, you are sneaking another question in there. One more suited for gamedev.stackexchange.com. You can ask question there (and it does not have to be that you are getting an error).
So, you want to implement a kinematic body with gravity that chases the player. Let us start with the gravity…
The run of the mill code for a kinematic body with gravity looks like this:
extends KinematicBody2D
export(Vector2) var velocity:Vector2
export(float) var gravity:float = 100
func _physics_process(delta:float) -> void:
velocity.y += gravity * delta
velocity = move_and_slide(velocity, Vector2.UP)
Ok, gravity is probably not 100. But that is the basic structure of the code. Note the distance units - being a 2D game - are in pixels, and delta is in seconds. Thus, gravity is in pixels per second squared.
And you want to chase the player avatar. In order to implement that I'll do the following changes:
- Have a reference to the player avatar.
- Split velocity into vertical and horizontal components.
- Have an horizontal speed.
extends KinematicBody2D
export(NodePath) var player_path:NodePath = @"/root/World/Player"
export(float) var horizontal_speed:float = 100
export(float) var gravity:float = 100
onready var player:Node2D = get_node(player_path)
var _velocity:float = 0
func _physics_process(delta:float) -> void:
_velocity.y += gravity * delta
_velocity = move_and_slide(_velocity, Vector2.UP)
var direction_to_player = transform.origin.direction_to(player.transform.origin)
_velocity.x = direction_to_player.x * horizontal_speed
This code uses a NodePath to find the player avatar. Which it queries on ready, and uses that reference from there on. Assuming the player is always there, that is no problem.
The horizontal_speed specifies how fast it moves horizontally towards the player. In pixels per second.
If you don't want it to change velocity while it is in the air, we can do that too:
extends KinematicBody2D
export(NodePath) var player_path:NodePath = @"/root/World/Player"
export(float) var horizontal_speed:float = 100
export(float) var gravity:float = 100
onready var player:Node2D = get_node(player_path)
var _velocity:Vector2 = Vector2.ZERO
func _physics_process(delta:float) -> void:
_velocity.y += gravity * delta
_velocity = move_and_slide(_velocity, Vector2.UP)
if is_on_floor():
var direction_to_player = global_transform.origin.direction_to(player.global_transform.origin)
_velocity.x = direction_to_player.x * horizontal_speed
Notice I'm using global_transform.origin. You could also use global_position. Don't use transform.origin nor position, because they are relative to the parent node. And if the parent is not the same, you are going to get a wrong direction. *I bias towards using transform because
Notice also I'm using is_on_floor after move_and_slide, so I get the updated value. I strongly encourage this pattern: gravity, move_and_slide, decisions.
This is not going to jump or climb ladders or anything like that. It will also get stuck on walls. It has nothing resembling path finding or obstacle avoidance. So, as you can imagine, it can get quite complex depending on what you want to do. However, it grows from there. I know little of the behavior you want to give these kinematic bodies, beyond that you want them to go to the player, using mode_and_slide and with gravity, I have no idea. Thus, I cannot help you further.