Ayushman Rajora
Ayushman Rajora

Reputation: 31

KinematicBody.move_and_slide() can only be called from an instance

I am new to Godot game engine. Though, I have developed many 2D games with Python and pygame, this is my first time working with 3D. I have just tried to move a kinematic body from its place using GDscript and I am getting an error while calling this function-

KinematicBody.move_and_slide()

Without this function, the player is not moving. And when I write it, an error says-

KinematicBody.move_and_slide() can only be called from an instance.

I tried attaching the script to KinematicBody, it's MeshInstance, new inherited scene etc.

I also tried to turn the KinematicBody to child node under mesh instance. But nothing is changing.

I want to clarify that I AM NOT TALKING ABOUT KINEMATICBODY2D. I am working with 3D only.

Can you please tell me how to solve this problem and what is my mistake?

Thank You

Upvotes: 0

Views: 2555

Answers (1)

Theraot
Theraot

Reputation: 40295

The error is that move_and_slide is an instance method. Thus, calling it like an static method (from the class name, i.e. KinematicBody.move_and_slide(…)) does not work.


Usually, you want to setup your nodes like this:

KinematicBody
├ MeshInstance
└ CollisionShape

The idea is that the MeshInstance moves according to how the KinematicBody moves, so you make it a child of it. You want to move the KinematicBody (with move_and_slide) and have the MeshInstance follow, and not the other way around. Because it is responsibility of KinematicBody to interact with physics, while the responsibility of MeshInstance is to interact with graphics.

About where to call move_and_slide, the recommendation is to have a script in your KinematicBody that looks something like this:

extends KinematicBody

func _physics_process(delta:float)-> void:
    # …
    move_and_slide(…)
    # …

Of course, it is possible to manipulate the the KinematicBody externally. You first need to get a reference to it (using get_node, for example), because - again - it is not an static method. You could have multiple KinematicBody, and which one are you moving? (rhetoric).

Also, move_and_slide is meant to be called in the physics step (remember it will move a physic object, and also it handles collision - which is the slide part), which is why I put it in _physics_process.


To save you some other gotchas, some advice:

  • The method move_and_slide takes velocity, not distance, and thus you don't need to multiply by delta to call it. Which isn't the case with move_and_collide.
  • The values of is_on_wall, is_on_floor and is_on_ceiling are updated when move_and_slide runs (the up vector you pass as second parameter is used to decide what is a wall, floor, or ceiling). As consequence I recommend to query them (and anything else you query, including Input and collisions) after the call to move_and_slide, so you have updated values. The only thing I place before calling move_and_slide is applying gravity (if the game needs gravity).
  • It is usually a bad idea to reference up the scene tree. In particular, if you make an scene for instancing, that scene has no control over where it gets instanced. So avoid referencing outside of the current scene. If you always reference down, then you never have to worry about it when converting a branch into a scene. Instead, when you want to communicate upwards, use signals. The exception is referencing autoloads, which are available everywhere, and survive scene transitions. On that node, know it can useful to put signals on autoloads, so you can connect to them everywhere.

And have some linky links:

Upvotes: 4

Related Questions