0
\$\begingroup\$

I'm currently making spaceship controller script. Control is simple, W/S to move forward/backward, A/D/ to rotate ship by Y Axis(yaw).

Spaceship is RigidBody node and has CollisionShape as children.

Here's the code for move forward/backward:

export var speed = 1
export var max_speed = 10
var current_speed = 0

export var key_acceleration = KEY_W
export var key_deceleration = KEY_S

func process_movement(delta):
    if Input.is_key_pressed(key_acceleration):
        current_speed -= speed * delta
    elif Input.is_key_pressed(key_deceleration):
        current_speed += speed * delta

    current_speed = clamp(current_speed, -max_speed, max_speed)

    linear_velocity = Vector3(0, 0, current_speed)

I need to limit it's maximum speed, so I updated velocity directly, not using something like add_force.

Next is rotating code:

export var yawing_speed = 0.01
export var max_yawing_speed = 0.02
export var yaw_stop_threshold = 0.001
var current_yaw = 0

func process_yaw(delta):
    if Input.is_key_pressed(key_yaw_left):
        current_yaw += yawing_speed * delta
    elif Input.is_key_pressed(key_yaw_right):
        current_yaw += -yawing_speed * delta
    else:
        if current_yaw > 0:
            current_yaw -= yawing_speed * delta

            if current_yaw < yaw_stop_threshold:
                current_yaw = 0
        elif current_yaw < 0:
            current_yaw += yawing_speed * delta

            if current_yaw > yaw_stop_threshold:
                current_yaw = 0

    current_yaw = clamp(current_yaw, -max_yawing_speed, max_yawing_speed)   
    rotation.y += current_yaw

In this code, I updated rotation.y directly. Each of this function works if run separately, however run these together, it only changed rotation, not velocity.

func _physics_process(delta):
    process_movement(delta)
    process_yaw(delta)

Change order of process_movement and process_yaw doesn't change anything. If I just run one of process_movement and process_yaw, it works perfectly.

Why my rigidbody ignored velocity and only rotated? Any advice will very appreciate it.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Directly manipulating the velocity of a RigidBody in _physics_process is not supported. From the docs:

The body’s linear velocity. Can be used sporadically, but don’t set this every frame, because physics may run in another thread and runs at a different granularity. Use _integrate_forces as your process loop for precise control of the body state.

You have 3 options to limit the max speed of your body:

1. Use a counter-force

Use add_force for acceleration, and apply a counter-force to slow it down. This counter-force should be proportional to the speed, such that when speed == max_speed, force == counter_force so the forces cancel out and the ship stops accelerating. This is similar to how air resistance works in real life (not that a spaceship would have "air resistance" per se).

I have an example of this from a game jam project I worked on recently (it is MIT-licensed, so feel free to borrow code).

2. Use a KinematicBody

With a KinematicBody, you have are able to precisely control velocity, but you don't get to participate in a full physics simulation. I also have an example of this from the same game, as I decided to switch my ship from a RigidBody to a KinematicBody to get more control over the movement.

3. Use _integrate_forces

You can keep using RigidBody but gain more precise control over its behavior by implementing custom logic in _integrate_forces. The docs discuss this briefly.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .