0 votes

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 by (603 points)

1 Answer

0 votes

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,483 points)
edited by
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 Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.