Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

Setting Volume / Account for Direction During a Collision?

Discussion in 'Physics' started by HoecusPocus, Feb 22, 2021.

  1. HoecusPocus

    HoecusPocus

    Joined:
    Oct 14, 2020
    Posts:
    7
    I'm trying to play audio when my character collides with a surface in Unity, using the 2D Physics engine. The Collision2D object has a relativeVelocity (Vector2D) property, which has a magnitude (float). This was okay to start with, but is very unrealistic when not bouncing on a horizonal surface.

    I know that there must be some way to work out from the ball's velocity, and the collision's relative velocity (or the angle of the other body) to change the volume of the sound I'm playing.

    Maybe this image can explain it better:
    Collision.jpg

    So basically, the second and third collision examples should have a lower volume than the first one, as less of the collision force is at normal to the colliding surface...

    Code (CSharp):
    1. // in OnCollisionEnter2D
    2.  
    3. var hitCollider = hit.collider;
    4.  
    5. // todo: how much of this collision is at normal to travel direction
    6. var relativeVelocity = hit.relativeVelocity.normalized;
    7. var bodyVelocity = _body.velocity.normalized;
    8. var dot = Mathf.Abs(Vector2.Dot(relativeVelocity, bodyVelocity));
    9. var magnitude = hit.relativeVelocity.magnitude;
    10. var volume = magnitude * dot;
    11.  
    12. // set volume of audio here
     
  2. HoecusPocus

    HoecusPocus

    Joined:
    Oct 14, 2020
    Posts:
    7
    I think I've managed to get something that vaguely matches what I need:


    Code (CSharp):
    1.            
    2.             _tempHitCollider = hit.collider;
    3.             _tempAbsNormalImpulse = Mathf.Abs(_tempContact.normalImpulse);
    4.             _tempCollisionVolume = _tempAbsNormalImpulse / MAX_AUDIO_COLLISION_FORCE * 1;
    5.  
    normalImpulse seems to show work, but it's still making loud noises at high speed for surfaces that are actually quite flat, when compared to the direction of the ball travel.