Hi All!

I am trying to write a script for player movement "orbiting" around a central point where left/right corresponds to orbiting around the point and up/down corresponds to moving towards/away from the point respectively. The following script mostly works, except there is some kind of centripetal force that pushes on the KinematicBody2D away from the point when orbiting (moving L/R). ie the force is perpendicular to the L/R movement. any ideas on what is causing this?

``````extends KinematicBody2D

var speed = 200

var velocity = Vector2.ZERO

func get_input():
look_at(Vector2(144,144))
velocity = Vector2()
if Input.is_action_pressed("ui_left"):
velocity = Vector2(0, -speed).rotated(rotation)
if Input.is_action_pressed('ui_right'):
velocity = Vector2(0, speed).rotated(rotation)
if Input.is_action_pressed("ui_down"):
velocity = Vector2(-speed, 0).rotated(rotation)
if Input.is_action_pressed('ui_up'):
velocity = Vector2(speed, 0).rotated(rotation)

func _physics_process(delta):
get_input()
move_and_slide(velocity)
``````
in Engine

you are aplying tangencial movement... Imagine you are on the edge of a circle, then you press left. So you will move `speed*delta` (because `move_and_slide`) in a linear direction tangencial to that circle. If you where just standing on the circle, that would mean that the next position must be off the circle, as you are moving in a linear direction.

If you want to move in orbit, you should change the angle with left/right, and change the length with up/down, and make a vector out of it.

``````extends KinematicBody2D

var angular_speed = 1
var normal_speed = 200

var angle = 0
var length = 500

var movement = Vector2.ZERO

func get_input(delta):
look_at(Vector2(144,144))
if Input.is_action_pressed("ui_left"):
angle += angular_speed*delta
if Input.is_action_pressed('ui_right'):
angle -= angular_speed*delta
if Input.is_action_pressed("ui_down"):
length -= normal_speed*delta
if Input.is_action_pressed('ui_up'):
length += normal_speed*delta

movement = Vector2.RIGHT.rotated(angle)*length

func _physics_process(delta):
get_input(delta)
global_position = movement
``````

Or you could correct the position after moving, if you still want to use `move_and_slide` for collisions:

``````extends KinematicBody2D

var speed = 200

var velocity = Vector2.ZERO
var speed_vector = Vector2()

var previous_length = Vector2.ZERO

func get_input():
look_at(Vector2(0,0))
velocity = Vector2()
speed_vector = Vector2()
var previous_length = global_position.length()
if Input.is_action_pressed("ui_left"):
speed_vector = Vector2(0, -speed)
if Input.is_action_pressed('ui_right'):
speed_vector = Vector2(0, speed)
if Input.is_action_pressed("ui_down"):
speed_vector = Vector2(-speed, 0)
if Input.is_action_pressed('ui_up'):
speed_vector = Vector2(speed, 0)

velocity = speed_vector.rotated(rotation)

func _physics_process(delta):
get_input()
move_and_slide(velocity)
if speed_vector.x != 0:
previous_length = global_position.length()
else:
global_position = global_position.normalized()*previous_length
``````
by (3,505 points)
edited by