Use KinematicBody2D implement circle movement

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By 張凱捷

How to declare circular movement to KinematicBody2D?

I search for this topic,
and I found https://forum.godotengine.org/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 move_and_slide always multiply the delta time.

extends KinematicBody2D

export(float) var rotate_speed = 5.0
export(float) var radius = 100

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)
:bust_in_silhouette: Reply From: ItsYoBoi

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.

:bust_in_silhouette: Reply From: kidscancode

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.