How to set a max speed of a RigidBody2d?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Shadow Assassin

I’m making a tennis game using a RigidBody2d for the ball and kinematicBody2d for the player. The player can move forwards when the player hits the ball it causes the ball to speed up. What is the code to add to the ball script to set a max speed?

Here is the script for the ball

export var ball_speed = 150                                                                                                      
                                                                                                                                                       
func _ready():
apply_impulse(Vector2(), Vector2(1, 1).normalized() * ball_speed)
:bust_in_silhouette: Reply From: wombatstampede

In your code you apply a one-time force (impulse) to the ball. The speed is just a result from applying the impulse. So you named your variable wrong. How fast the ball will go will also depends on the set mass of the rigid body.

To slow down the ball while it is in the air I would add a “draft” force/impulse in opposite direction of the balls velocity. Probably you will also have a floor so the friction will bring the ball to a stop.

A rough estimation of air draft will be that it is proportional to the square of its speed. So in this code below i put the square of the velocity (length of velocity vector2) in sqrVelocity. Also the applied impulse is multiplied by delta so the draft_factor basically stays for the draft force applied in one second. (depending on velocity)

export var draft_factor = 10.0

func _physics_process(delta):
   sqrVelocity = linear_velocity().length()*linear_velocity().length()
   apply_impulse(Vector2(),linear_velocity().normalized() * sqrVelocity * -1 * delta * draft_factor)

You will have to try out the draft factor.

Thanks for your response. I tried to add the code but had the following error Identifier ‘sqrVelocity’ is not declared in current scope. Sorry I’m completely new to GDscript.

I’m making a game like SpiritSphere DX. Using a RigidBody2D for the ball do I need to use _integrate_forces() instead to access the Physics2DDirectBodyState? I would like to apply limit to the ball speed something like linear_velocity but don’t know the code.

Shadow Assassin | 2019-04-22 23:50

You get the error because I forgot to put a var in front of sqrVelocity. Anyway I posted the code only to give you one idea how to approach the problem.

_integrate_forces() might be a good place to limit the velocity as the docs says that would also be the place to set the position if needed.

So it is probably something like this:

export var max_speed = 100.0

_integrate_forces(state):
    if state.linear_velocity.length()>max_speed:
        state.linear_velocity=state.linear_velocity.normalized()*max_speed

wombatstampede | 2019-04-23 06:10