How can I make my bullets accelerate/decelerate?

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

I have rigid body script containing code below, how do I make it accelerate or decelerate?

extends RigidBody2D

var speed = -700

func start_at(direction, position):
	set_rotation(direction)
	set_position(position)
	apply_impulse(Vector2(), Vector2(speed, 0).rotated(direction + PI/2))

I know for constant acceleration, you can change apply_impulse to apply_thrust

You want it to accelerate/decelerate after an amount of time?

System_Error | 2020-02-06 15:07

Both variants would be ideal (with and without delay).

sempiro | 2020-02-06 22:03

:bust_in_silhouette: Reply From: System_Error

Moving RigidBody2Ds is a wee bit more complicated than pushing something else around.
Also, what you want your bullet to DO can determine which Body you use. High-speed projectiles (i.e. Bullets) tend to be KinematicBody2D, and Instant-Travel weapons (a.k.a. Lasers) straight up use RayCast2D.

I have a mine that moves towards its target when said target is within a specific area. If the target leaves the pursuit range, it no longer is a target, and the mine slowly comes to a stop.

func _on_ImpulseTimer_timeout():
    var mine_pos = self.global_position
    var target_pos = targets.front().global_position
    var pos_diff = target_pos - mine_pos
    var n_pos_diff = pos_diff.normalized()
    apply_impulse(target_pos, n_pos_diff * 1.5)

The above is how I get it to move, as it is a RigidBody2D.

For firing a rocket, a constantly accelerating projectile, I would set a value (engine_power) to true after spawning/instancing the rocket.

var engine_power = false

func _ready():
    engine_power = true

func _integrate_forces(state):
    if engine_power == true:
	    set_applied_force(thrust.rotated(global_rotation))
    else:
        thrust = Vector2()

I used that for a spaceship that gets spawned in repeatedly, but they’re pretty similar to rockets, in a way.

To make a projectile slow down, and eventually stop, you’ll have an initial, high-power impulse, and either apply smaller ones to gradually slow it down, OR have the Linear Dampening of that specific projectile be higher than normal. (set_linear_damp())

It’d be a good idea to use the yield(get_tree().create_timer(DURATION), "timeout") command. This’ll create a temporary Timer with the specified duration, and the code block will continue running after the duration.

So you’d have your Impulse fire, sending the projectile out, and the Timer will be created, running for a short time as the bullet/delayed rocket slowly comes to a stop, and as soon as the Timer is done, you’ll apply a force to get that thing moving again.