Audio Source landing sound effect causing delay/feedback

I’ve been going through the Comp-3 Interactive YouTube tutorial on programming a First Person Controller (great tutorial series, for anyone else like me who is new to Unity and programming: https://www.youtube.com/playlist?list=PLfhbBaEcybmgidDH3RX_qzFM0mIxWJa21).

I’ve gotten up to the footstep sound FX tutorial, and got it working perfectly, but the one thing he didn’t cover that I wanted to include is jump/land sounds. It kinda sticks out like a sore thumb that the Player makes all the sounds when walking on various terrains, but absolute silence when they jump.

I tried a combination of using what I learned in the Comp-3 tutorial, along with another FP Controller code I found which already had jumping included, and I got really close…except there is a very annoying delay/feedback on the landing sound effect (just the landing effect, the jumping effect works fine). I’m just using a generic jump and land sound, not separating the differing surface textures, to make it easier on myself for now. I’ve tried a bunch of variations to try and get rid of it, but it won’t go away. Below are the code alterations I made to the code from the Comp-3 tutorial. Alterations are //commented for now, until I figure this bug out. Also utilized rows of dots to skip over redundant code bits rather than copy/pasting the entire thing here (the .cs file is attached, though, for a more detailed look).

........................

    [Header("Footstep Parameters")]
    [SerializeField] private float baseStepSpeed = 0.5f;
    [SerializeField] private float crouchStepMultiplier = 1.5f;
    [SerializeField] private float sprintStepMultiplier = 0.6f;
    [SerializeField] private AudioSource footstepAudioSource = default;

........................

    [SerializeField] private AudioClip[] concreteClips = default;
    //[SerializeField] private AudioClip jumpSound = default;
    //[SerializeField] private AudioClip landSound = default;
    //private bool m_PreviouslyGrounded;
    //private float NextStep;
    //private float StepCycle;
    private float footstepTimer = 0;

........................

private void HandleJump()
    {
        if (ShouldJump)
        {
            moveDirection.y = jumpForce;
            //PlayJumpSound();
         }
        //if (!m_PreviouslyGrounded && characterController.isGrounded)
        //{
            //PlayLandingSound();
        //}
        //if (characterController.isGrounded && canJump &&m_PreviouslyGrounded)
        //m_PreviouslyGrounded = characterController.isGrounded;
    }

    //private void PlayJumpSound()
    //{
        //footstepAudioSource.clip = jumpSound;
        //footstepAudioSource.Play();
    //}

    //private void PlayLandingSound()
    //{
        //footstepAudioSource.clip = landSound;
        //footstepAudioSource.Play();
        //NextStep = StepCycle + .5f;
    //}

I’ve directed this query to Mike at Comp-3 via his channel as well, but figured I’d check also to expand my chances at figuring out. Can also provide a Dropbox link to the tutorial project file, if that would be helpful.

8957601–1230237–FirstPersonController.cs (16.2 KB)

Honestly your code looks ok. Maybe there could be an issue if you set the landing AudioClip to your AudioSource while the jumping sound might not be finished playing. You could try using AudioSource.PlayOneShot(landSound), just to see if it makes any difference.

Besides that, could you elaborate on this part? Is the sound coming too late? What do you mean by feedback here?

Cheers!

Thanks for the quick response! I just made this Movavi screen record of the glitch, as it’s rather hard to describe:
https://www.youtube.com/watch?v=mJCdtCbOAOk

When I tried using the “AudioSource.PlayOneShot(landSound)” code instead, I get an object reference error (screenshot attached).

8958087--1230378--Screenshot 2023-04-18 at 1.46.36 PM.png

Sorry, here I meant "using an AudioSource with the PlayOneShot method. In your case that would be footstepAudioSource.PlayOneShot(landSound);

Something you can do that’s useful when debugging sound is to use the AudioProfiler: Window >> Analysis >> Profiler, then click “Audio” and select “Detailed” instead of “Simple” on the lower tab of the profiler window.

Hearing your video gives me the impression that your landing sound if triggering every frame once you jump. I think you should try this and review how you’re handling the grounded state.

if (!m_PreviouslyGrounded && characterController.isGrounded)
{
    PlayLandingSound();
    m_PreviouslyGrounded = characterController.isGrounded;
}

Hope this helps!

Hearing your video gives me the impression that your landing sound if triggering every frame once you jump. I think you should try this and review how you’re handling the grounded state.

if (!m_PreviouslyGrounded && characterController.isGrounded)
{
    PlayLandingSound();
    m_PreviouslyGrounded = characterController.isGrounded;
}

Hope this helps![/QUOTE]

That did the trick! I figured it was some sort of looping issue! Thanks for the quick replies, you’re a life saver!!!

Slightly different topic, but as long as we’re rolling, figured it’d be easier to keep going rather than start over from scratch in a new thread.

I moved onto the next video in that tutorial (

), which covers Health Systems. Was doing fine until I got to the “Setting Up Danger Zones” section (around 13:50 in the video). He had us set up a “fire zone” with a Box Collider trigger and added a simple script to the zone to inflict the damage:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DamageTest : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
            FirstPersonController.OnTakeDamage(15);
    }
}

The code is small enough that I’ve triple checked it a dozen times, and made sure I wrote it exactly as he wrote it in the video, and yet I’m getting a NullReferenceException error, which he did not get. Any ideas?

Never mind this one…I went away, came back, and now it’s working. For once, the computer gremlins worked in my favor, lol.

2 Likes

Back to the jumping SFX - now that I got the basic mechanism figured out, I went ahead and tried to update it to incorporate the various ground textures. I’m 99% there, however, while it works on the launch action, it does not generate any sound on the land action. Attaching the script as it currently stands, here are the main alterations I made (alterations commented// and " " used to simplify redundancies, as there are a lot of floor textures I used):

[Header("Footstep Parameters")]
    [SerializeField] private float baseStepSpeed = 0.5f;
    [SerializeField] private float crouchStepMultiplier = 1.5f;
    [SerializeField] private float sprintStepMultiplier = 0.6f;
    [SerializeField] private AudioSource footstepAudioSource = default;
    [SerializeField] private AudioClip[] dirtyGroundClips = default;
    " "
    //[SerializeField] private AudioClip[] landDirtyGroundClips = default;
    //[SerializeField] private AudioClip[] jumpDirtyGroundClips = default;
    " "
    private bool m_PreviouslyGrounded;
    private float NextStep;
    private float StepCycle;
    private float footstepTimer = 0;
    private float GetCurrentOffset => isCrouching ? baseStepSpeed * crouchStepMultiplier : IsSprinting ? baseStepSpeed * sprintStepMultiplier : baseStepSpeed;

.........

private void HandleJump()
    {
        if (ShouldJump)
        {
            moveDirection.y = jumpForce;
            PlayJumpSound();
         }
        if (!m_PreviouslyGrounded && characterController.isGrounded)
        {
            PlayLandingSound();
            m_PreviouslyGrounded = characterController.isGrounded;
        }
        if (characterController.isGrounded && canJump &&m_PreviouslyGrounded)
        m_PreviouslyGrounded = characterController.isGrounded;
    }
private void PlayJumpSound()
    {
        //if (Physics.Raycast(playerCamera.transform.position, Vector3.down, out RaycastHit hit, 3))
        //{
            //switch (hit.collider.tag)
            //{
                //case "Footsteps/Wood":
                    //footstepAudioSource.PlayOneShot(jumpWoodClips[UnityEngine.Random.Range(0, jumpWoodClips.Length - 1)]);
                    //break;
               " "
            //}
        //}
    }

        private void PlayLandingSound()
        {
            //if (Physics.Raycast(playerCamera.transform.position, Vector3.down, out RaycastHit hit, 3))
            //{
                //switch (hit.collider.tag)
                //{
                //case "Footsteps/Wood":
                    //footstepAudioSource.PlayOneShot(landWoodClips[UnityEngine.Random.Range(0, landWoodClips.Length - 1)]);
                    //break;
                " "
            }
                NextStep = StepCycle + .5f;
            }
        }

This is the last thing I need to figure out on setting up this FPS controller, so once I get this figured out I should be good to go!

8965932–1232184–FirstPersonController.cs (28.1 KB)

Doesn’t give me any errors or feedback loops like the previous attempt, just doesn’t play anything at all when the character lands.

So in trying to figure this out, I went back to the previous version by commenting out the changes, and while it had worked fine prior, now the previous code is doing the same thing that the new code is doing (playing the launch sound, but not the landing sound)…

Well, I figured out what was making the landing sound not work. For anyone interested, changed the HandleJump code from this:

    private void HandleJump()
    {
        if (ShouldJump)
        {
            moveDirection.y = jumpForce;
            PlayJumpSound();
         }

        if (!m_PreviouslyGrounded && characterController.isGrounded)
        {
            PlayLandingSound();
        m_PreviouslyGrounded = characterController.isGrounded;
        }
    }

To this:

    private void HandleJump()
    {
        if (ShouldJump)
        {
            moveDirection.y = jumpForce;
            PlayJumpSound();
         }

        if (!m_PreviouslyGrounded && characterController.isGrounded)
        {
            PlayLandingSound();
        }
        m_PreviouslyGrounded = characterController.isGrounded;
    }

(Alteration was in the last line of the landing section).

That fixed the landing sound not playing - however, as is per usual I am quickly learning, fixing one problem created another.

As you’ll hear in the following video, at the very start of the game, it sounds like it is sounding off all of the variations of footsteps in sequence. It then stops, and plays a few more if you look around a bit (even without pressing any WASD keys, just moving the mouse to look). Once you stop moving, it goes on as it should and plays perfectly, but that first entry into the game is buggy.

Here’s what’s currently happening:

I’m so close to being done with this…I can see the light at the end of the tunnel! If anyone has any ideas what’s causing this latest bug, I will be eternally grateful! (Full current code is attached).

8967627–1232625–FirstPersonController.cs (30.4 KB)

Looking at your code the first thing that stands out to me is that you never initialize m_PreviouslyGrounded. I’m not sure if it’s the cause of your problem though…
Looking at you go I’m sure you’ll figure it out soon :wink:

It’s initialized - it’s the first private bool listed after all the audio clip arrays:

[SerializeField] private AudioClip jumpSound = default;

    private bool m_PreviouslyGrounded;
    private float NextStep;
    private float StepCycle;
    private float footstepTimer = 0;
    private float GetCurrentOffset => isCrouching ? baseStepSpeed * crouchStepMultiplier : IsSprinting ? baseStepSpeed * sprintStepMultiplier : baseStepSpeed;

Interesting development…so in my troubleshooting, I figured seeing if maybe it was something with the Unity tutorial project I was working on. I created a new project, with just a 10x10 cube for a floor, and imported my prefab, scripts, and audios into that project to test it out, and it did the same thing.

BUT…I then decided to take it another step further, and try it in the actual game I’m developing, and…it worked! No idea what made the difference between the three projects, but I certainly ain’t gonna complain, since this is the only one I (currently) need it to work on, lol!

What you’re referring to is “declared”. By “initialized” I meant “explicitely set to a value at the beginning of all things”, to be certain that you’re not starting in an unexpected state. It’s good practice!

Ah, gotcha. Sorry, still learning my way through the terminologies!

1 Like

I’m guessing that an initialization for this would be along the lines of “m_PreviouslyGrounded = false;” in the start/awake function, since the player should be starting off as grounded, correct?

1 Like

Didn’t fix the glitch in the tutorial project, but since it’s working fine in my main project, I’m gonna leave it as is until such a time as it’s generating in a project I care about, lol.