Using the linear velocity of a RigidBody2D to affect the volume of the sound it makes on collision

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

I’m trying to get a sound to play louder the faster an object’s velocity is. Something like:

var volume_in_decibels = min(14, max(1, (velocity_as_float / 10))

I suck at maths and physics, so my closest attempt (a wild guess) was to use the length() of the vector (see Arrow.gd below):

ArrowSpawner.gd:

extends Node2D

export (PackedScene) var arrow_template

var shoot_speed = 10

func create_arrow():
    var arrow = arrow_template.instance()
    arrow.add_to_group("arrows")
    var arrow_spawner_position_node = get_node("Position2D")
    owner.get_parent().add_child(arrow)
    arrow.global_transform = arrow_spawner_position_node.global_transform
    
    var distance = owner.get_global_mouse_position() - arrow_spawner_position_node.global_position
    arrow.apply_impulse(Vector2(), distance * shoot_speed)
    

Arrow.gd:

extends RigidBody2D

func _ready():
    contact_monitor = true
    contacts_reported = 1
    connect("body_entered", self, "_on_body_entered")

func _on_body_entered(body):
    print("Arrow collided with " + body.get_path()
        + " linear_velocity " + str(linear_velocity)
        + " as single float " + str(linear_velocity.length()))
    
    contact_monitor = false
    queue_free()

This works fine if you shoot a wall at a perpendicular angle, but if you come from another angle the value jumps wildly (see the output).

What would be the proper way to do this?

Full example here: