How to declare circular movement to KinematicBody2D?

I search for this topic,
and I found https://godotengine.org/qa/16331/circular-movement
but I can't use position directly on KinematicBody2D.

I try it by myself,
but I just couldn't figure out how to make original position as the center of the movement.
because the radius in moveandslide always multiply the delta time.

``````extends KinematicBody2D

export(float) var rotate_speed = 5.0

var angle = 0

func _physics_process(delta):

angle = fmod(angle + (rotate_speed * delta), 2 * PI)

var offset = Vector2(sin(angle), cos(angle)) * radius

move_and_slide(offset)
``````
asked Dec 4, 2019 in Projects

I can't help you with the script, but there is a way to move something in a scene without using scripts. I recommend using an animation player. In fact I have a game with moving enemies.

answered Dec 9, 2019 by (50 points)

There are a lot of ways to approach this problem, depending on what you need and the rest of your implementation.

Boiling it down to its simplest form, you just need to gradually turn the body while always moving forward (like in a car if you have the wheel turned). To do that, you'd need nothing more than the following:

``````extends KinematicBody2D

var turn_speed = 0.5  # in radians/sec
var move_speed = 100  # pixels/sec

func _physics_process(delta):
rotation +=turn_speed * delta
move_and_collide(transform.x * move_speed * delta)
``````

Your turning radius then becomes a function of the rotation and movement speeds.

If instead you'd rather start with the circle's radius, then the turn angle will need to vary based on the movement speed (you have to turn sharper if you're going faster). The angle can then be calculated using the chord formula:

``````c = 2 * r * sin(a/2)
``````

`c` is the length of the chord (ie the amount we move forward in one timestep) and is equal to `move_speed * delta`; `r` is the radius, and `a` is the angle. Solve for `a`, and you have your calculation:

``````extends KinematicBody2D

var move_speed = 100  # pixels/sec
var radius = 150  # pixels

func _physics_process(delta):
var a = 2 * asin(move_speed * delta / (2 * radius))
rotation += a
move_and_collide(transform.x * move_speed * delta)
``````

All of that high school Geometry review was fun, but I must also point out that if you don't need your body to be a kinematic, you can make circular movement really simple by just parenting to a Node2D and rotating the parent.

answered Dec 9, 2019 by (17,714 points)