How do you make a RigidBody2D move in a specific direction?

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

Here is my scene. The red square you can see rotates around the circle and when left-mouse is clicked will add a “ball” (a RigidBody2D) to the scene at the location of the red square. The way I’m currently moving the RigidBody2D is by giving it a linear velocity value of 100 (x and y). The problem with this is that it makes it move in the same direction regardless of where it spawned. I want the ball to move “forward” from where its spawned (represented by the blue arrows in the image).

Thank you in advance.

Screenshot of my scene:

:bust_in_silhouette: Reply From: spaceyjase

Pick a direction that’s forward; typically that’s transform.x, multiply it by some desired speed. Ensure forward is always pointing in the direction your want. See for clarification:

(alternatively, if forward isn’t really relevant for your game, just set velocity to the desired direction)

Thanks for your reply!

The problem with this is that I’m using a StaticBody2D and moving it by applying a linear velocity force. I’m doing this because I’m using the bounce feature that it has to bounce off walls and other objects. Changing the rotation of the StaticBody2D doesn’t change the direction that it moves in. Instead I need to set the linear velocity so that it moves “forward” from the current rotation of my red square. (see screenshot in original post for visualisation). Do you know how I would get the linear velocity in a situation like this?

Kron | 2023-04-13 13:13

:bust_in_silhouette: Reply From: Juxxec

You should use the transform.x property of the object.

However, you should switch from a StaticBody2D to a KinematicBody2D. You can achieve the effect you desire with the following code:

extends KinematicBody2D

var velocity := Vector2.ZERO
var max_speed := 12.0
var acceleration := 4.0
var friction := 2.0

func _physics_process(delta):
	var left = Input.get_action_strength("ui_left")
	var right = Input.get_action_strength("ui_right")
	var up = Input.get_action_strength("ui_up")
	var down = Input.get_action_strength("ui_down")
	var horizontal = right - left
	var vertical = down - up
	if vertical:
		self.velocity = lerp(
			(transform.y * (down - up)).normalized() * self.max_speed,
			delta * self.acceleration)
		self.velocity = lerp(
			(transform.y * (down - up)).normalized() * self.max_speed,
			delta * self.acceleration)
	if horizontal:
		self.rotation_degrees += horizontal * 90.0 * delta
	var collision = move_and_collide(self.velocity)

	if collision:
		var collider = collision.collider
		var normal = collision.normal
		self.velocity = self.velocity.bounce(normal)

Using my code you would get the following behaviour:

Example of bounce using KinematicBody2D