Search Unity

Audio Need help with 'push' sound peculiar behaviour

Discussion in 'Audio & Video' started by N1ghtrunner, Nov 25, 2022.

  1. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    hi everyone,

    I am trying to implement a straight-forward 'pushing' sound of a box on snow when said box is pushed by the player. ive got the basic code in place, but it isnt perfect and I have 2 issues.

    1. In the first instance it actually seems to play for a loop or two longer than it should, and
    2. in the second instance it was playing the sound every time I stood on top of it (i.e. I wasnt pushing it anywhere).

    I am basing the logic as per the below code on x velocity of the box. I see that even when visually the box has stopped moving, it still appears to have x and y velocity in unity for about a second, and so the sound plays again. Then because my character is animated/moves slightly in idle state, I suspect that this is giving the box a bit of x velocity (at least this is what I see in the editor). I tried to combat this second issue by giving the player 'feet' (another box 2D collider) and saying that whenever the box is touching these feet, no sound should play, and this almost worked, yet low and behold when I jump off the box I get a second of sound as there is some x velocity injected.

    There is probably a much better more efficient way of handling this problem and I'd really appreciate some guidance. What is currently a very slick little game for a game jam suddenly feels like amateur hour with these erratic sounds. Here is the code:

    Code (CSharp):
    1. public class GreenPresScript : MonoBehaviour
    2. {
    3.  
    4.     [SerializeField] AudioSource pushSnow;
    5.     [SerializeField] GameObject Player;
    6.  
    7.     Rigidbody2D presentRigidBody;
    8.     BoxCollider2D presentCollider;
    9.     BoxCollider2D playerFeet;
    10.     bool presentIsMoving = false;
    11.  
    12.     void Start()
    13.     {
    14.         presentRigidBody = GetComponent<Rigidbody2D>();
    15.         presentCollider = GetComponent<BoxCollider2D>();
    16.         playerFeet = Player.GetComponent<BoxCollider2D>();
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         PlayPushSound();
    22.     }
    23.  
    24.  
    25.  
    26.     public void PlayPushSound()
    27.     {
    28.         if (presentRigidBody.velocity.x != 0 && presentCollider.IsTouchingLayers(LayerMask.GetMask("Ground")) && !pushSnow.isPlaying && !presentCollider.IsTouching(playerFeet))
    29.         {
    30.             presentIsMoving =true;
    31.             pushSnow.Play();
    32.             Debug.Log("Pushing on Snow");
    33.          
    34.          }
    35.  
    36.         }
    37.  
    38.  
    39. }
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,435
    does it help if you add some threshold to that speed value check?
    mathf.abs(presentRigidBody.velocity.x) > 0.1f
     
  3. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Hey there, I updated the code a fair bit and I'm getting a generally better result when the velocity is kept to a value between -5 & 5 on the x axis. However the problem I'm having now is that as soon as the object touches another object (basically a box/present touching another box/present) the sound stops. No idea why and using isTouchingLayers has no effect on it. Stumped.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5.  
    6. public class pushScript : MonoBehaviour
    7. {
    8.  
    9.     Rigidbody2D presentRB;
    10.     BoxCollider2D presentBC;
    11.     GameObject player;
    12.     [SerializeField] AudioSource snowPush;
    13.     public bool presentIsMoving;
    14.     void Start()
    15.     {
    16.         presentRB = GetComponent<Rigidbody2D>();
    17.         presentBC = GetComponent<BoxCollider2D>();
    18.     }
    19.  
    20.     void Update()
    21.     {
    22.         if (presentRB.velocity.x >= 5 || presentRB.velocity.x <= -5)
    23.         {
    24.             presentIsMoving = true;
    25.         }
    26.         else presentIsMoving = false;
    27.     }
    28.  
    29.     public void OnCollisionStay2D(Collision2D other)
    30.  
    31.     {
    32.         if (presentIsMoving == true && other.gameObject.tag == "Player" && !snowPush.isPlaying)
    33.         {
    34.             snowPush.Play();
    35.             Debug.Log("Present being pushed");
    36.         }  
    37.     }
    38.  
    39.     public void OnCollisionExit2D(Collision2D other)
    40.     {
    41.         presentIsMoving = false;
    42.         snowPush.Stop();
    43.         Debug.Log("Present stopped");
    44.     }  
    45. }
     
  4. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Turns out this was a velocity issue. When the 2 objects touch the velocity drops to a point where the isMoving bool is false. I had to drop the velocity quite a bit, but thankfully it works well now. I'm sure there is a cleaner way of implementing this feature, but I'll take this solution for now.