0 votes

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
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)
asked Dec 4, 2019 in Projects by 張凱捷 (14 points)

2 Answers

0 votes

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 ItsYoBoi (50 points)
0 votes

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 kidscancode (17,714 points)
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 How to use this Q&A? before posting your first questions.