Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Ball GameObject Not Playing Rolling Sound, (Grounded Detection) Please Help

Discussion in 'Scripting' started by SCOPSmusic, Nov 22, 2023.

  1. SCOPSmusic


    Nov 17, 2023
    Hello everyone,

    Thank you very much for your time. I am trying to develop a game with two people. I am not the programmer. I am the sound designer. However, my coder is new to game dev, so I would like to pick up the slack on the coding of sound. I am using FMOD integration. I can get the sound of the ball colliding to work without any problems, but the rolling sound is having lots of trouble. I tried hard to troubleshoot the problem by myself. I have used chatGPT to write the code and have asked it a LOT of questions to understand the what and why of everything, but every iteration of code it is giving me is not solving the problem.

    I have tried a debug on the code, the ball is listed as moving: true, but grounded is always false. The floor object has a box collider on it and the ball has a sphere collider and a rigidbody on it. The sound is linked to FMOD correctly because it played initially, but it was playing while in midair (the ball drops from the sky upon pushing play). I asked chatGPT to write code that would fix that and I asked it questions to understand what and why it did, but I don't know why there is no ground detection and believe that if it were true, the sound loop would play. Here is the code:

    Code (CSharp):
    1. using UnityEngine;
    3. public class BallSoundController : MonoBehaviour
    4. {
    5.     public FMODUnity.EventReference rollingEvent;
    6.     public FMODUnity.EventReference collisionEvent;
    8.     private FMOD.Studio.EventInstance rollingInstance;
    9.     private FMOD.Studio.EventInstance collisionInstance;
    11.     private Rigidbody rb;
    13.     private void Start()
    14.     {
    15.         rb = GetComponent<Rigidbody>();
    17.         // Initialize FMOD instances
    18.         rollingInstance = FMODUnity.RuntimeManager.CreateInstance(rollingEvent);
    19.         collisionInstance = FMODUnity.RuntimeManager.CreateInstance(collisionEvent);
    21.         // Start the rolling sound
    22.         rollingInstance.start();
    23.     }
    25.     private void Update()
    26.     {
    27.         bool isGrounded = IsBallGrounded();
    28.         bool isMoving = IsBallMoving();
    30.         Debug.Log($"Grounded: {isGrounded}, Moving: {isMoving}");
    32.         // Check if the ball is grounded and moving
    33.         if (isGrounded && isMoving)
    34.         {
    35.             // If the rolling sound is not playing, start it
    36.             FMOD.Studio.PLAYBACK_STATE playbackState;
    37.             rollingInstance.getPlaybackState(out playbackState);
    38.             if (playbackState != FMOD.Studio.PLAYBACK_STATE.PLAYING)
    39.             {
    40.                 rollingInstance.start();
    41.             }
    43.             // Update the rolling sound pitch based on the ball's speed
    44.             float speed = rb.velocity.magnitude;
    45.             rollingInstance.setParameterByName("Speed", speed);
    46.         }
    47.         else
    48.         {
    49.             // If the rolling sound is playing, stop it
    50.             FMOD.Studio.PLAYBACK_STATE playbackState;
    51.             rollingInstance.getPlaybackState(out playbackState);
    52.             if (playbackState == FMOD.Studio.PLAYBACK_STATE.PLAYING)
    53.             {
    54.                 rollingInstance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
    55.             }
    56.         }
    57.     }
    59.     private void OnCollisionEnter(Collision collision)
    60.     {
    61.         // Play collision sound when the ball collides with an object
    62.         collisionInstance.start();
    63.     }
    65.     private bool IsBallGrounded()
    66.     {
    67.         // Check if the ball is grounded by looking for ground within 0.1 units
    68.         return Physics.Raycast(transform.position, Vector3.down, 0.1f);
    69.     }
    71.     private bool IsBallMoving()
    72.     {
    73.         // Check if the ball's velocity is close to zero
    74.         return rb.velocity.sqrMagnitude > 0.01f;
    75.     }
    76. }

    And attached is a screenshot of the game.

    Thank you so much for your help.

    Attached Files:

  2. JambonBurst6


    Nov 16, 2021
    Hi there,

    Your raycast seems strange to me. It has a 0.1 range, which is fine, but it starts from transform.position which I assume is the ball center? If that's the case, that means your raycast will not reach the ball if its radius is greater than 0.1.

    What you can try is start raycasting from the ball bottom position. For that, you can simply add an offset to the raycast starting position, like this:

    Code (CSharp):
    1. private bool IsBallGrounded()
    2. {
    3.     // Check if the ball is grounded by looking for ground within 0.1 units
    4.     return Physics.Raycast(transform.position + Vector3.down * ballRadius, Vector3.down, 0.1f);
    5. }
    Where ballRadius is the radius of the ball, that you can define manually, or even better, get from the sphere collider itself. You can at least do it manually at first to make sure this fixes your issue.

    Let me know if this helps!
    Last edited: Nov 30, 2023